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

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

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

1. 串赋值StrAssign

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

2. 串比较StrCompare

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

3. 求串长 StrLength

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

4. 串联接Concat

01 /* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
02 Status Concat(String T,String S1,String S2)
03 {
04     int i;
05     if(S1[0]+S2[0]<=MAXSIZE)
06     /*  未截断 */
07         for(i=1;i<=S1[0];i++)
08             T[i]=S1[i];
09         for(i=1;i<=S2[0];i++)
10             T[S1[0]+i]=S2[i];
11         T[0]=S1[0]+S2[0];
12         return TRUE;
13     }
14     else
15     /*  截断S2 */
16         for(i=1;i<=S1[0];i++)
17             T[i]=S1[i];
18         for(i=1;i<=MAXSIZE-S1[0];i++)
19             T[S1[0]+i]=S2[i];
20         T[0]=MAXSIZE;
21         return FALSE;
22     }
23 }

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

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

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

5. 求子串SubString

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

完整的可执行程序为:

001 #include "stdio.h"
002 #include "string.h"
003 #include "stdlib.h"
004  
005 #define OK 1
006 #define ERROR 0
007 #define TRUE 1
008 #define FALSE 0
009  
010 #define MAXSIZE 40 /* 存储空间初始分配量 */
011  
012 typedef int Status;     /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
013 typedef char String[MAXSIZE+1]; /*  0号单元存放串的长度 */
014  
015 /*  输出字符串T */
016 void StrPrint(String T)
017 {
018     int i;
019     for(i=1;i<=T[0];i++)
020         printf("%c",T[i]);
021     printf("\n");
022 }
023  
024 /* 生成一个其值等于chars的串T */
025 Status StrAssign(String T,char *chars)
026 {
027     int i;
028     if(strlen(chars)>MAXSIZE)
029         return ERROR;
030     else
031     {
032         T[0]=strlen(chars);
033         for(i=1;i<=T[0];i++)
034             T[i]=*(chars+i-1);
035         return OK;
036     }
037 }
038  
039 /* 返回串的元素个数 */
040 int StrLength(String S)
041 {
042     return S[0];
043 }
044  
045 /*  初始条件: 串S和T存在 */
046 /*  操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S < T,则返回值< 0 */
047 int StrCompare(String S,String T)
048 {
049     int i;
050     for(i=1;i < =S[0]&&i<=T[0];++i)
051         if(S[i]!=T[i])
052             return S[i]-T[i];
053     return S[0]-T[0];
054 }
055  
056 /* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
057 Status Concat(String T,String S1,String S2)
058 {
059     int i;
060     if(S1[0]+S2[0]<=MAXSIZE)
061     /*  未截断 */
062         for(i=1;i<=S1[0];i++)
063             T[i]=S1[i];
064         for(i=1;i<=S2[0];i++)
065             T[S1[0]+i]=S2[i];
066         T[0]=S1[0]+S2[0];
067         return TRUE;
068     }
069     else
070     /*  截断S2 */
071         for(i=1;i<=S1[0];i++)
072             T[i]=S1[i];
073         for(i=1;i<=MAXSIZE-S1[0];i++)
074             T[S1[0]+i]=S2[i];
075         T[0]=MAXSIZE;
076         return FALSE;
077     }
078 }
079  
080 /* 用Sub返回串S的第pos个字符起长度为len的子串。 */
081 Status SubString(String Sub,String S,int pos,int len)
082 {
083     int i;
084     if(pos < 1||pos>S[0]||len < 0||len>S[0]-pos+1)
085         return ERROR;
086     for(i=1;i<=len;i++)
087         Sub[i]=S[pos+i-1];
088     Sub[0]=len;
089     return OK;
090 }
091  
092 int main()
093 {
094     int i, j, opp;
095     char s;
096     String t,s1,s2,sub;
097     Status k;
098  
099     printf("\n1.StrAssign 生成串 \n2.StrLength 求串长 \n3.StrCompare 串比较 ");
100     printf("\n4.Concat 串连接 \n5.SubString 求子串");
101     printf("\n0.退出 \n请选择你的操作:\n");
102     while(opp != '0')
103     {
104         scanf("%d",&opp);
105         switch(opp)
106         {
107         case 1:
108             k=StrAssign(s1,"nowamagic.net");
109             if(!k)
110             {
111                 printf("串长超过MAXSIZE(=%d)\n",MAXSIZE);
112                 exit(0);
113             }
114             printf("串s1为:");
115             StrPrint(s1);
116             printf("\n");
117             break;
118  
119         case 2:
120             printf("串s1长为%d \n",StrLength(s1));
121             break;
122  
123         case 3:
124             k=StrAssign(s2,"google.com");
125             if(!k)
126             {
127                 printf("串长超过MAXSIZE(%d)\n",MAXSIZE);
128                 exit(0);
129             }
130             printf("串s2为:");
131             StrPrint(s2);
132

你可能感兴趣的:(数据结构)