⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c.txt

📁 有关C语言中字符串的操作的一些经典程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
65   int main()

66   {

67       char hello[] = "hasd11H";

68   

69       EncodeString(hello, strlen(hello));

70       cout << hello << endl;

71   

72       return 0;

73   }

程序说明如下:

q  代码第61~62行,EncodeString()函数调用了ReplaceChars ()函数和ReverseString()函数,前者替代字符,后者翻转整个字符串。

q  ReplaceChars()函数调用GetFourthChar()函数来查找并替换后面第4个字符。GetFourthChar()函数查找两个全局数组,这两个数组分别包含了所有的字母。

q  ReverseString()函数使用了begin和end两个分别指向字符串头尾的指针,然后头尾的内容不断交换,begin指针往尾移动,end指针往头移动,如此循环直到两个指针碰头。

程序执行结果如下:

L11hwel

 

面试例题20:反转字符串,但其指定的子串不反转。

考点:字符串相关的综合编程能力。

出现频率:★★★

给定一个字符串以及该字符串的子串,将字符串反转,但子串部分不反转,示例如下。

输入字符串为"Welcome you, my friend"

子串为"you"

输出为"dneirf ym ,you emocleW"

解析

对于本类型题目,采取的步骤如下所示。

q  扫描一遍字符串,然后用stack把它反转,同时记录下子串出现的位置。

q  扫描一遍记录下来的子串,再用stack反转。

q  将堆栈里的字符弹出,这样子串又恢复了原来的顺序。

这里使用扫描数组的方法。如果扫描中发现子串,就将子串倒过来压入堆栈。最后再将堆栈里的字符弹出,这样子串又恢复了原来的顺序。C++标准库中的stack是后进先出的栈结构,使用stack可以轻松地完成这个转换。程序代码如下:

1    #include <iostream>

2    #include <cassert>

3    #include <stack>

4    using namespace std;

5    

6    const char* reverse(const char* s1, const char* token)

7    {

8        stack<char> stack1;

9        const char* ptoken = token, *head = s1, *rear = s1;

10       assert(s1 && token);

11       while (*head != '\0')

12       {

13           while(*head != '\0' && *ptoken == *head)

14           {

15               ptoken++;

16               head++;

17           }

18           if(*ptoken == '\0')

19           {

20               const char* p;

21               for(p=head-1; p>=rear; p--)

22               {

23                   stack1.push(*p);

24               }

25               ptoken = token;

26               rear = head;

27           }

28           else

29           {

30               stack1.push(*rear++);

31               head = rear;

32               ptoken = token;

33           }

34       }

35       char *pReturn = new char[strlen(s1)+1];

36       int i=0;

37       while(!stack1.empty())

38       {

39           pReturn[i++] = stack1.top();

40           stack1.pop();

41       }

42       pReturn[i]='\0';

43   

44       return pReturn;

45   }

46   

47   int main(int argc, char* argv[])

48   {

49       char welcome[] = "Welcome you, my friend";

50       char token[] = "you";

51       const char *pRev = reverse(welcome, token);

52   

53       cout << "before reverse:" << endl;

54       cout << welcome << endl;

55       cout << "after reverse:" << endl;

56       cout << pRev << endl;

57   

58       return 0;

59   }

代码第13~17行,reverse()函数搜索字符串的字串位置。其中指针ptoken记录当前扫描的子串位置,如果其内容为结束符'\0'(代码第18~27行),如果搜索到了这个子串,将它倒过来压入堆栈,否则直接压入堆栈(代码第28~33行)。最后申请一块堆内存,使用退栈把栈中内容存入堆内存中并返回堆内存。程序执行结果如下:

before reverse:

welcome you, my friend

after reverse:

dneirf ym ,you emocleW

 

面试例题21:编写字符串反转函数strrev。

考点:字符串相关的综合编程能力。

出现频率:★★★★

编写字符串反转函数:strrev,要求时间和空间效率都尽量高。

测试用例:输入“abcd”,输出应为“dcba”。

解析

这种类型的题目最简单的解法是:遍历字符串,将第1个字符和最后1个字符交换,第2个和倒数第2个字符交换,依次循环。解法1代码如下:

1    char* strrev1(const char* str)

2    {

3        int len = strlen(str);

4        char* tmp = new char[len + 1];

5

6        strcpy(tmp,str);

7        for (int i = 0; i < len/2; ++i)

8        {

9            char c = tmp[i];

10           tmp[i] = tmp[len - i - 1];

11           tmp[len - i - 1] = c;

12       }

13   

14       return tmp;

15   }

解法1是通过数组下标的方式访问字符串,也可以用指针直接操作。解法2代码如下:

1    char* strrev2(const char* str)

2    {

3        char* tmp = new char[strlen(str) + 1];

4        strcpy(tmp,str);

5        char* ret = tmp;

6        char* p = tmp + strlen(str) - 1;

7    

8        while (p > tmp)

9        {

10           char t = *tmp;

11           *tmp = *p;

12           *p = t;

13

14           --p;

15           ++tmp;

16       }

17   

18       return ret;

19   }

解法1和解法2都没有考虑时间和空间的优化,典型的优化策略就是两个字符交换的算法优化,我们可以借助异或运算符(^)完成两个字符的交换,对应的是解法3和解法4。

解法3:

1    char* strrev3(const char* str)

2    {

3        char* tmp = new char[strlen(str) + 1];

4        strcpy(tmp,str);

5        char* ret = tmp;

6        char* p = tmp + strlen(str) - 1;

7    

8        while (p > tmp)

9        {

10           *p ^= *tmp;

11           *tmp ^= *p;              

12           *p ^= *tmp;

13   

14           --p;

15           ++tmp;

16       }

17   

18       return ret;

19   }

解法4:

1    char* strrev4(const char* str)

2    {

3        char* tmp = new char[strlen(str) + 1];

4        strcpy(tmp,str);

5        char* ret = tmp;

6    

7        char* p = tmp + strlen(str) - 1;

8    

9        while (p > tmp)

10       {

11           *p = *p + *tmp;

12           *tmp = *p - *tmp;

13           *p = *p - *tmp;

14   

15           --p;

16           ++tmp;

17       }

18   

19       return ret;

20   }

也可以使用递归算法来解决这个问题。每次交换首尾两个字符,中间部分又变成和原来字符串相同的问题。

解法5:

1    char* reverse5(char* str,int len)

2    {

3        if (len <= 1)

4            return str;

5    

6        char t = *str;

7        *str = *(str + len -1);

8        *(str + len -1) = t;

9    

10       return (reverse5(str + 1,len - 2) - 1);

11   }

注意:这5个解法中只有解法5修改了输入字符串,其他4种都是在函数体内申请堆内存。下面给出测试用的main()函数:

1    int main(int argc,char* argv[])

2    {

3        char* str = "123456";

4        cout << str << endl;

5    

6        char* str2 = reverse1(str);

7        cout << str2 << endl;

8    

9        char* str3 = reverse2(str2);

10       cout << str3 << endl;

11   

12       char* str4 = reverse3(str3);

13       cout << str4 << endl;

14   

15       char* str5 = reverse4(str4);

16       cout << str5 << endl;

17   

18       char* str6 = reverse5(str5,strlen(str5));

19       cout << str6 << endl;

20   

21       return 0;

22   }

程序输出结果如下:

    123456

    654321

    123456

    654321

    123456

    654321
 
 
面试例题22:编程实现任意长度的两个正整数相加。

考点:字符串相关的综合编程能力。

出现频率:★★★★

解析

在C/C++中可以用int、float、double等类型表示数字,但是它们的长度都是有限的,而本题要求数字是任意长度,因而需要用字符串表示数字,同样用字符串表示结果。因此所要做的就是做一个类似整数加法的字符串转换,程序代码如下所示:

1    #include <stdio.h>

2    #include <string.h>

3    #include <stdlib.h>

4    #include <math.h>

5

6    char* addBigInt(char* num1, char* num2)

7    {

8        int c = 0;                //进位,开始最低进位为0

9        int i = strlen(num1)-1;    //指向第一个加数的最低位

10       int j = strlen(num2)-1;    //指向第二个加数的最低位

11       int maxLength = strlen(num1) >= strlen(num2) ? 

12           (strlen(num1)+1):(strlen(num2)+1);    //得到2个数中较大数的位数

13       char* rst = (char*)malloc(maxLength+1);  //保存结果

14       int k;

15       if (rst == NULL)

16       {

17          printf("malloc error!\n");

18          exit(1);

19       }

20   

21       rst[maxLength] = '\0';    //字符串最后一位为'\0'

22       k = strlen(rst) - 1 ;       //指向结果数组的最低位

23       while ( (i >= 0) && (j >= 0) )

24       {

25          rst[k] = ( (num1[i] - '0') + (num2[j] - '0') + c )%10 +'0';   //计算本位的值

26          c = ( (num1[i] - '0') + (num2[j] - '0') + c )/10;           //向高位进位值

27          --i;

28          --j;

29          --k;

30       }

31       while ( i >= 0 )

32       {

33          rst[k] = ( (num1[i] - '0') + c )%10 + '0';

34          c = ( (num1[i] - '0') + c)/10;

35          --i;

36          --k;

37       }

38       while ( j >= 0 )

39       {

40          rst[k] = ( (num2[j] - '0') + c )%10 + '0';

41          c = ( (num2[j] - '0') + c )/10;

42          --j;

43          --k;

44       }

45       rst[0] = c + '0';

46   

47       if ( rst[0] != '0' )                     //如果结果最高位不等于0,则输出结果

48       {

49          return rst;

50       }

51       else

52       {

53          return rst+1;

54       }

55   }

56   

57   int main()

58   {

59       char num1[] = "123456789323";

60       char num2[] = "45671254563123";

61       char *result = NULL;

62   

63       result = addBigInt(num1, num2);

64       printf("%s + %s = %s\n", num1, num2, result);

65   

66       return 0;

67   }

程序执行结果如下所示:

123 456 789 323 + 45 671 254 563 123 = 45 794 711 352 446

 

面试例题23:编程实现字符串循环右移。

考点:字符串综合编程能力。

出现频率:★★★★

解析

根据题意,编写的函数能把字符串循环右移n位。例如字符串“abcdefghi”,如果n=2,移位后是“hiabcdefgh”。

程序代码如下所示:

1    #include <stdio.h>

2    #include <stdlib.h>

3

4    void loopMove(char *str, int n)

5    {

6        int i = 0;

7        char *temp = NULL;

8        int strLen = 0; 

9        char *head = str;           //指向字符串头

10       

11       while(*str++);

12       strLen = str - head - 1;      //计算字符串长度

13       n = n % strLen;            // 计算字符串尾部移到头部的字符个数

14       temp = (char *)malloc(n); //分配内存

15       for (i = 0; i < n; i++)

16       {

17           temp[i] = head[strLen - n + i]; //临时存放从尾部移到头部的字符

18       }

19       for (i = strLen - 1; i >= n; i--)

20       {

21           head[i] = head[i - n];     //从头部字符移到尾部

22       }

23       for (i = 0; i < n; i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -