字串類習題、面試題詳解(第一篇)

QingLiXueShi發表於2014-12-01

第二篇連結:字串類習題、面試題詳解(第二篇)

 

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 }    

相關文章