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

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

 

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 }    
posted @ 2014-12-01 18:37  QingLiXueShi  阅读(1930)  评论(4编辑  收藏  举报