C风格字符串----字符串的常见问题

本文包含字符串包含问题(isSubstr)、字符串转化为整数(atoi)、统计词频问题(Wordcount)、字符串反转(Reverse)。字符串去除空格等

 一:字符串包含问题(isSubstr)

思路:本程序采用最简单的方法;

1、遍历源字符串,当子字符串的首字符与遍历到的字符相同时,就遍历字符串。

2、遍历子字符串时,如果遇到不相等,跳出子循环,源字符串的位置++;

3、若子循环遍历的长度恰好等于子字符串,那么原串包含子串,返回true。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include "assert.h"
 5 
 6 //时间复杂度为O(lensub*(lens-lensub+1))
 7 int isSub(const char *str, const char*strsub)
 8 {
 9     assert(str != NULL && strsub != NULL);
10 
11     int lens =strlen(str);
12     int lensub = strlen( strsub);
13     //若原串的长度不及子串的长度,则直接返回
14     if( lens < lensub) 
15         return  0;
16 
17     int i,j ;//自增量
18     for( i= 0; i <=lens- lensub; ++i)//循环次数
19     {
20         for( j =0; j < lensub; ++j)
21             if( str[i+j] != strsub[j])
22                 break;
23         if( j == lensub)
24             return 1;
25     }
26     return 0;
27 }
28 
29 //测试用例最好多考虑几种情况
30 int main(int argc, char const *argv[])
31 {
32     char s[] = "helloworld";
33     char sub[] = "wo";
34 
35     printf("%d
", isSub(s, sub)); 
36     return 0;
37 }
View Code

 二:字符串转化为整数(atoi)

思路:依次遍历字符串,主要的执行语句:sum = sum*10 +'ch'-'0'

注意:

0、判断传入的参数是否为空;

1、返回值的长度问题,本程序返回值用 long long类型;

2、字符串的第一个字符有可能是‘+’,‘-’,因此要判断正负值问题;

3、转换时,如果遇到非法字符,则直接返回0;

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 #include <limits>
 5 using namespace std;
 6 
 7 long long aToi(const char *str)
 8 {
 9     if(str == NULL)
10         return 0;
11     long long num = 0;
12 
13     const char *digit = str;
14     int flag =0; //标记正负
15     if( *digit == '-') //首位元素值得情况
16         flag = 1;
17     else if( *digit == '+')
18         flag =0;
19     else if( *digit >='0' && *digit <='9')
20         num = *digit - '0';
21     else 
22         return 0;
23     digit ++;
24 
25     while( *digit != '')
26     {
27         if( *digit >='0' && *digit <='9')
28         {
29             num = num*10 + *digit - '0';
30             if( num > std::numeric_limits<int>::max())
31             {
32                 num = 0 ;
33                 return num;
34             }
35             digit ++;
36         }else
37         {
38             num = 0 ;
39             return num;
40         }
41     }
42 
43     if( flag == 1)
44         return 0-num;
45     return num;
46 }
47 
48 int main(int argc, char const *argv[])
49 {
50     char s[]="254436"; //正常
51     printf("%lld
",aToi(s));
52     
53     char t[]="+254436"; //正常
54     printf("%lld
",aToi(t));
55 
56     char t1[]="-254436"; //正常
57     printf("%lld
",aToi(t1));
58 
59     char t2[]="2544323436"; //溢出问题 -0
60     printf("%lld
",aToi(t2));
61 
62     char s1[]="25i436"; //非法字符
63     printf("%lld
",aToi(s1));
64 
65     char s2[]="";//
66     printf("%lld
",aToi(s2));
67 
68     char s3[]="  ";//非法字符
69     printf("%lld
",aToi(s3));
70     return 0;
71 }
View Code

 三:统计词频问题(Wordcount)

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <assert.h>
 4 
 5 int WordCount( const char *str)
 6 {
 7     assert( str != NULL);
 8 
 9     const char *strb = str;
10     const char *stre = str;
11 
12     int count =0;
13     while( *strb != '')
14     {
15         while( *strb ==' ') //排除前面的空格
16             strb ++;
17         if( *strb == '')//如果全部空格,直接退出
18             break;
19 
20         stre = strb; //此时*strb一定不是空格,故count++
21         count ++;
22         while( *stre !=' ' && *stre != '')// stre开始往后移,
23             stre++;
24         strb = stre;
25     }
26     return count ;
27 }
28 
29 int main(int argc, char const *argv[])
30 {
31     char s[] = "  hello, this is a C program!!  ";
32     printf("%d
", WordCount(s));
33 
34     char s1[] = "     "; //全是空格
35     printf("%d
", WordCount(s1));
36     return 0;
37 }
View Code

 四:字符串反转(Reverse)、、

思路:

1、先将源字符串反转一遍;

2、再将单个单词反转,即可。

3、反转单词时,跳过空格。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include "assert.h"
 5 
 6 void ReverseSub(char *left, char *right)
 7 {
 8     assert( left != NULL && right != NULL);
 9     while( left < right)
10     {
11         char tmp = *left;
12         *left = *right;
13         *right = tmp;
14         ++left;
15         --right;
16     }
17 }
18 
19 char *Reverse(char *str)
20 {
21     if( str == NULL)
22         return ;
23     if( strlen(str) == 1)
24         return;
25     char *ptrb = str;
26     char *ptre = str;
27     //走到末尾
28     while( *ptre != '')
29         ++ptre;
30 
31     ReverseSub(ptrb, --ptre); //去掉''
32 
33     ptrb = ptre = str;
34     while( *ptrb != '') //一个字符一个字符的走
35     {
36         if( *ptrb == ' ') //走完前面的空格
37         {
38             ++ptrb;
39             ++ptre;
40             continue;
41         }
42         //反转单词
43         else if( *ptre == ' ' || *ptre == '') //此时*ptrb是一个字符
44         {
45             ReverseSub(ptrb, --ptre);
46             ptrb = ++ptre;
47         }
48         else 
49             ptre ++;
50     }
51     return str;
52 }
53 
54 int main(int argc, char const *argv[])
55 {
56     char str[] = " hello, world, thank you! ";
57     printf("original:%s
", str);
58     printf("reversed:%s
",Reverse(str));
59 
60     char str1[] = "     ";
61     printf("original:%s
", str1);
62     printf("reversed:%s
",Reverse(str1));
63     return 0;
64 }
View Code

五:字符串去除空格

1、先去除头部空格;

2、再去除尾部空格;

3、最后去除中间空格

一)去除中间空格做法:当遇到空格时,直接跳过;

二)这样,我们跳过的空格数的取值可能为0、1、2·····

三)判断当前非空格字符的前两个字符是否为空格;

若都为空格,我们写入一个空格;

若只是一个空格,直接写入串中;

对于不是空格的字符,直接写入串中即可。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include "assert.h"
 5 
 6 char *trimSpace( char * str)
 7 {
 8     if( str == NULL)
 9         return;
10 
11     int i = 0; //用于写字符
12     char j = 0;//用于遍历字符
13 
14     while( str[j] == ' ') //移除前面的空格
15         j++;
16 
17     int lens = strlen( str );
18     while( str[--lens] == ' ') ; //移除后面的空格
19     str[++lens] = ''; //封装    
20 
21     while( str[j] != '')
22     {
23     //移除中间的空格    
24         while( str[j] == ' ')
25             j++;
26     //连续两个空格,表明需要移除
27         if( str[j-1]==' ' && str[j-2] ==' ' && i!= 0 ) //考虑情况:头部连续超过两个空格,若没有i!=0;接下来的语句就会写一个空格
28             str[i++] = ' ';
29         str[i++] = str[j++];
30     } 
31     str[i] = '';
32     return str;
33 }
34 
35 int main(int argc, char const *argv[])
36 {
37     char str[] = "  hel  l0  ";
38     printf("original:%s
", str);
39     printf("trimSpaced:%s
",trimSpace(str));
40 
41     return 0;
42 }
View Code

六:移位包含问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

//移位包含问题。解决方法:
//一:对于原串s1,可连接s1与自身得到s1s1,遍历s1s1查看是否包含另外一个穿
//二:在指针指向s1末尾元素时,下一步重新回到s1头元素
int shift_contain_str(const char *const Src, const char *const Des)
{
    assert(Src != NULL && Des != NULL);
    int lenS = strlen( Src);
    int lenD = strlen( Des);
    if( lenS < lenD)
        return 0;

    int i = 0;//遍历字符串        
    for ( i = 0; i < lenS; ++i)
    {
        int k = i; 
        int j;
        for (j= 0; j < lenD; ++j)
         {
             if(Src[k++%lenS] != Des[j])
                 break;
         } 
         if( k - i == lenD)//k -i 代表 内层for循环执行的次数
             return 1;
    }
    return 0;
}

int main(int argc, char const *argv[])
{
    int ret;
    char Src[]= "hello";
    char Des[] ="ol";

    char Des1[] = "elloh";
    ret = shift_contain_str(Src, Des);
    printf("ret: %d
", ret);
    printf("ret:%d
",shift_contain_str(Src, Des1));
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xfxu/p/4083720.html