串最基本的5个操作的C实现

串的最小操作子集
服务器君一共花费了282.591 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

前面谈到串的最小操作子集

  • 串赋值StrAssign
  • 串比较StrCompare
  • 求串长StrLength
  • 串联接Concat
  • 求子串SubString
  • 这5种操作不可能利用其他串操作来实现,但其他串操作均可在这个最小操作子集上实现。这里我们写程序实现上面的操作吧。

1. 串赋值StrAssign

/* 生成一个其值等于chars的串T */
Status StrAssign(String T,char *chars)
{
	int i;
	if(strlen(chars)>MAXSIZE)
		return ERROR;
	else
	{
		T[0]=strlen(chars);
		for(i=1;i<=T[0];i++)
			T[i]=*(chars+i-1);
		return OK;
	}
}
  • 串赋值的算法比较简单,把目标字符串一个个复制到数组T即可。T[i]=*(chars+i-1) 这行代码是关键,字符串可以用指针访问。

2. 串比较StrCompare

/*  初始条件: 串S和T存在 */
/*  操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S < T,则返回值 < 0 */
int StrCompare(String S,String T)
{
	int i;
	for(i=1; i<=S[0]&&i<=T[0]; ++i)
		if(S[i]!=T[i])
			return S[i]-T[i];
	return S[0]-T[0];
}
  • 这里字符串数组的第一个元素存储的是字符串的长度,所以循环条件是 i<=S[0]&&i<=T[0]。假如 S[i]与T[i]不相等,就返回它们的差值,根据这个差值我们就可以知道,哪个字符串比较大。

3. 求串长 StrLength

/* 返回串的元素个数 */
int StrLength(String S)
{
	return S[0];
}
  • 字符串数组的第一个元素存储的就是它的长度,所以直接返回第一个元素就可以了。

4. 串联接Concat

/* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
Status Concat(String T,String S1,String S2)
{
	int i;
	if(S1[0]+S2[0]<=MAXSIZE)
	{ /*  未截断 */
		for(i=1;i<=S1[0];i++)
			T[i]=S1[i];
		for(i=1;i<=S2[0];i++)
			T[S1[0]+i]=S2[i];
		T[0]=S1[0]+S2[0];
		return TRUE;
	}
	else
	{ /*  截断S2 */
		for(i=1;i<=S1[0];i++)
			T[i]=S1[i];
		for(i=1;i<=MAXSIZE-S1[0];i++)
			T[S1[0]+i]=S2[i];
		T[0]=MAXSIZE;
		return FALSE;
	}
}

连接两个,需要考虑截断问题,判断条件就是 S1[0]+S2[0] 是否大于 MAXSIZE。

如果未发生截断,则将数组S2的元素补到S1的后边 T[S1[0]+i]=S2[i];

如果发生截断,那就将MAXSIZE-S1[0]个S2的元素补到S1的后边。

5. 求子串SubString

/* 用Sub返回串S的第pos个字符起长度为len的子串。 */
Status SubString(String Sub,String S,int pos,int len)
{
	int i;
	if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
		return ERROR;
	for(i=1;i<=len;i++)
		Sub[i]=S[pos+i-1];
	Sub[0]=len;
	return OK;
}
  • 这里需要注意条件,起始位置不能小于1,也不能大于串长度,长度len不能小于0,也不能大于总长度减去起始位置等。接下来就简单了,从起始位置开始,将串数组元素逐个赋值给sub数组。

完整的可执行程序为:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 40 /* 存储空间初始分配量 */

typedef int Status;		/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef char String[MAXSIZE+1]; /*  0号单元存放串的长度 */

/*  输出字符串T */
void StrPrint(String T)
{
	int i;
	for(i=1;i<=T[0];i++)
		printf("%c",T[i]);
	printf("\n");
}

/* 生成一个其值等于chars的串T */
Status StrAssign(String T,char *chars)
{
	int i;
	if(strlen(chars)>MAXSIZE)
		return ERROR;
	else
	{
		T[0]=strlen(chars);
		for(i=1;i<=T[0];i++)
			T[i]=*(chars+i-1);
		return OK;
	}
}

/* 返回串的元素个数 */
int StrLength(String S)
{
	return S[0];
}

/*  初始条件: 串S和T存在 */
/*  操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S < T,则返回值< 0 */
int StrCompare(String S,String T)
{
	int i;
	for(i=1;i < =S[0]&&i<=T[0];++i)
		if(S[i]!=T[i])
			return S[i]-T[i];
	return S[0]-T[0];
}

/* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
Status Concat(String T,String S1,String S2)
{
	int i;
	if(S1[0]+S2[0]<=MAXSIZE)
	{ /*  未截断 */
		for(i=1;i<=S1[0];i++)
			T[i]=S1[i];
		for(i=1;i<=S2[0];i++)
			T[S1[0]+i]=S2[i];
		T[0]=S1[0]+S2[0];
		return TRUE;
	}
	else
	{ /*  截断S2 */
		for(i=1;i<=S1[0];i++)
			T[i]=S1[i];
		for(i=1;i<=MAXSIZE-S1[0];i++)
			T[S1[0]+i]=S2[i];
		T[0]=MAXSIZE;
		return FALSE;
	}
}

/* 用Sub返回串S的第pos个字符起长度为len的子串。 */
Status SubString(String Sub,String S,int pos,int len)
{
	int i;
	if(pos < 1||pos>S[0]||len < 0||len>S[0]-pos+1)
		return ERROR;
	for(i=1;i<=len;i++)
		Sub[i]=S[pos+i-1];
	Sub[0]=len;
	return OK;
}

int main()
{
    int i, j, opp;
    char s;
	String t,s1,s2,sub;
	Status k;

    printf("\n1.StrAssign 生成串 \n2.StrLength 求串长 \n3.StrCompare 串比较 ");
    printf("\n4.Concat 串连接 \n5.SubString 求子串");
    printf("\n0.退出 \n请选择你的操作:\n");
    while(opp != '0')
    {
        scanf("%d",&opp);
        switch(opp)
        {
        case 1:
            k=StrAssign(s1,"nowamagic.net");
            if(!k)
            {
                printf("串长超过MAXSIZE(=%d)\n",MAXSIZE);
                exit(0);
            }
            printf("串s1为:");
            StrPrint(s1);
            printf("\n");
            break;

        case 2:
            printf("串s1长为%d \n",StrLength(s1));
            break;

        case 3:
            k=StrAssign(s2,"google.com");
            if(!k)
            {
                printf("串长超过MAXSIZE(%d)\n",MAXSIZE);
                exit(0);
            }
            printf("串s2为:");
            StrPrint(s2);
            printf("\n");

            i=StrCompare(s1,s2);
            if(i < 0)
                s=' < ';
            else if(i==0)
                s='=';
            else
                s='>';
            printf("串s1%c串s2\n",s);
            break;

        case 4:
            Concat(t,s1,s2);
            StrPrint(t);
            break;

        case 5:
            printf("求串s1的子串,请输入子串的起始位置: ");
            scanf("%d", &i);
            printf("请输入子串的长度: ");
            scanf("%d", &j);
            printf("起始位置:%d,子串长度:%d\n", i, j);
            k=SubString(sub,s1,i,j);
            if(k)
            {
                printf("子串sub为: ");
                StrPrint(sub);
            }
            break;

        case 0:
            exit(0);
        }
    }
}

延伸阅读

此文章所在专题列表如下:

  1. 数据结构里的串是什么东西?
  2. 如何比较串的大小
  3. 串的抽象数据类型ADT
  4. 串的顺序存储结构
  5. 串最基本的5个操作的C实现
  6. 寻找子串在主串中的位置
  7. 如何在串中插入串
  8. 如何在串中删除特定长度的子串
  9. 字符串中的子串替换
  10. 题外话:谈谈malloc()和free()

本文地址:http://www.nowamagic.net/librarys/veda/detail/2421,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/2421

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《代码整洁之道》 马丁(Robert C. Martin) (作者), 韩磊 (译者)

软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关。这一点,无论是敏捷开发流派还是传统开发流派,都不得不承认。《代码整洁之道》提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。作为编程领域的佼佼者,《代码整洁之道》作者给出了一系列行之有效的整洁代码操作实践。这些实践在《代码整洁之道》中体现为一条条规则(或称“启示”),并辅以来自现实项目的正、反两面的范例。只要遵循这些规则,就能编写出干净的代码,从而有效提升代码质量。

更多计算机宝库...