字符串类习题、面试题详解(第一篇)

第二篇链接:字符串类习题、面试题详解(第二篇)

 

1题:WERTYU(竞赛基础题)

把手放在键盘上时,稍不注意就会往右错一位,这样的话Q会变为W,J会变为K等。输入一个错位后敲出的字符串,输出打字员本来想打出的句子。

样例输入:O S, GOMR YPFSU/

样例输出:I AM FINE TODAY.

 1 #include <stdio.h>  

 2 const char *str = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";  

 3   

 4 int main(void)  

 5 {  

 6     char c;  

 7     int i;  

 8     while ((c = getchar()) != EOF)  

 9     {  

10         for (i = 0; str[i] && str[i] != c; i++);  

11         if (str[i])  

12             putchar(str[i - 1]);  

13         else  

14             putchar(c);  

15     }  

16       

17     return 0;  

18 }  

解析:本题注意两点:(1)for循环终止条件的判断,常量字符串末尾自动补“\0”,因而可利用str[i]的取值判断是否查找到最后一个字符。(2)反斜线“\”是特殊字符,需要使用转义序列或直接引用其ASCII码。

 

2题:TeX括号(竞赛基础题)

 在TeX中,左双引号是``,右双引号是’’。输入一篇包含双引号的文章,你的任务是把它转换成TeX格式。

样例输入:

“To be or not to be,” quoth the Bard, “thatis the question”.

样例输出:

``To be or not to be,” quoth the Bard,``that is the question”.

 1 #include <stdio.h>  

 2   

 3 int main(void)  

 4 {  

 5     char c;  

 6     int q = 1;  

 7     while ((c = getchar()) != EOF)  

 8     {  

 9         if (c == '"')  

10         {  

11             printf("%s", q ? "``" : "''");  

12             q = !q;  

13         }  

14         else  

15             printf("%c", c);  

16     }  

17       

18     return 0;  

19 }  

解析:本题的关键是如何判断一个双引号是左双引号还是右双引号。

 

3题:周期串(竞赛基础题)

如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。输入一个长度不超过80的串,输出它的最小周期。

样例输入:HoHoHo

样例输出:2

写法1:

 1 #include <stdio.h>  

 2 #include <string.h>  

 3 #define MAXLEN 80  

 4 int main(void)  

 5 {  

 6     char str[MAXLEN + 1] = {0};  

 7     scanf("%s", str);  

 8     int len = strlen(str);  

 9     int result = len;  

10     int i, j;  

11   

12     for (i = 1; i < len / 2 + 1; i++)              //i为周期  

13     {  

14         for (j = 0; j < len - i; j++)  

15         {  

16             if (str[j] != str[j + i])  

17                 break;  

18         }  

19   

20         if (j == len - i)  

21         {  

22             result = i;  

23             break;  

24         }  

25     }  

26     printf("%d\n",result);  

27   

28     return 0;  

29 }  

写法2:

 1 #include <stdio.h>  

 2 #include <string.h>  

 3 int main(void)  

 4 {  

 5     char word[100];  

 6     scanf("%s", word);  

 7     int len = strlen(word);  

 8     int i, j;  

 9   

10     for (i = 1; i <= len; i++)  

11     {  

12         if (len % i == 0)  

13         {  

14             int ok = 1;  

15             for (j = i; j < len; j++)  

16                 if (word[j] != word[j % i])  

17                 {  

18                     ok = 0;  

19                     break;  

20                 }  

21             if (ok)  

22             {  

23                 printf("%d\n", i);  

24                 break;  

25             }  

26         }  

27     }  

28   

29     return 0;  

30 }  

解析:本题两种解法的思路是一致的。

 

4题:编写一个函数,把一个char组成的字符串循环右移n位。例如:原来是”abcdefghi”,如果n = 2,移位后应该是”hiabcdefg”。(面试题)

 1 #include <stdio.h>  

 2 #include <string.h>  

 3 #define MAX_LEN 1024  

 4   

 5 void LoopMove_1(char *pStr, int steps)  

 6 {  

 7     int len = strlen(pStr) - steps;  

 8     char temp[MAX_LEN];  

 9   

10     strcpy(temp, pStr + len);  

11     strcpy(temp + steps, pStr);  

12     *(temp + steps + len) = '\0';  

13     strcpy(pStr, temp);  

14 }  

15   

16 void LoopMove_2(char *pStr, int steps)  

17 {  

18     int len = strlen(pStr) - steps;  

19     char temp[MAX_LEN];  

20   

21     memcpy(temp, pStr + len, steps);  

22     memcpy(temp + steps, pStr, len);  

23     memcpy(pStr, temp, len + steps);  

24 }  

25   

26 int main(void)  

27 {  

28     char str1[] = "abcdefghi";  

29     LoopMove_1(str1, 3);  

30     printf("%s\n", str1);  

31   

32     char str2[] = "gklmnopqrst";  

33     LoopMove_1(str2, 3);  

34     printf("%s\n", str2);  

35     return 0;  

36 }  

解析:本题提供了两种方法。

 

5题:编写程序,从键盘输入一组任意长度的字符串,当输入“#”符时结束输入(字符串不包括“#”),然后程序反向输出该字符串。(面试题)

方法1:将输入的字符串保存在一个数据结构中,然后将其内容反向输出。例如:首先申请一个栈,每输入一个字符时都将该字符做入栈操作,直到入栈队列中发现“#”为止(“#”不入栈)。然后再将栈中的元素顺序出栈。

 1 #include <stdio.h>    

 2 #define MAX_LEN 1024    

 3     

 4 int main(void)    

 5 {    

 6     char arr[MAX_LEN], c;    

 7     int i = 0, j;    

 8     while ((c = getchar()) != '#')    

 9     {    

10         arr[i++] = c;    

11     }    

12     arr[i] = '\0';    

13     

14     for (j = i - 1; j >= 0; j--)    

15     {    

16         printf("%c", arr[j]);    

17     }    

18     printf("\n");    

19         

20     return 0;    

21 }    

方法2:题目没要求保存输入的字符串,因此可用递归解此题。递归算法本身有栈的特性,每次递归地调用递归函数时,系统都会将现场保存在栈中,待调用结束返回时再恢复现场的内容。

 1 #include <stdio.h>    

 2     

 3 void StrRev()    

 4 {    

 5     char c;    

 6     scanf("%c", &c);    

 7     if ('#' == c)    

 8     {    

 9         printf("反转后的字符串:");    

10         return;    

11     }    

12     

13     StrRev();    

14     printf("%c", c);    

15 }    

16     

17 int main(void)    

18 {    

19     printf("请输入英文字符串(以#结束):");    

20     StrRev();    

21     printf("\n");    

22     return 0;    

23 }    

你可能感兴趣的:(字符串)