字串類習題、面試題詳解(第二篇),習題第二篇
第一篇連結:字串類習題、面試題詳解(第一篇)
6題:迴文串(競賽基礎題)
輸入一個字串,求出其最長迴文子串。子串的含義是:在原串中連續出現的字串片段。迴文的含義是:正著看和倒著看相同,如abba和yyxyy。在判斷時,應該忽略所有標點符號和空格,且忽略大小寫,但輸出應保持原樣(在迴文串的首部和尾部不要輸出多餘字元)。輸入字串長度不超過5000,且佔據單獨一行。應該輸出最長的迴文串,如果有多個,輸出起始位置最靠左的。
範例輸入:Confuciuss say: Madam, I’m Adam.
範例輸出:Madam,I’m Adam
方法1:枚舉迴文串的起點和終點。
#include <stdio.h>#include <ctype.h>#include <string.h>#define MAXN 5000 + 10char buf[MAXN], s[MAXN];int p[MAXN];int main(void){ int n, m = 0, max = 0, x, y; int i, j, k, ok; fgets(buf, sizeof(buf), stdin); n = strlen(buf); for (i = 0; i < n; i++) { if (isalpha(buf[i])) { p[m] = i; //儲存字元的實際位置 s[m++] = toupper(buf[i]); //儲存為大寫字母 } } for (i = 0; i < m; i++) //枚舉迴文串起始位置 { for (j = i; j < m; j++) //枚舉迴文串終止位置 { ok = 1; for (k = i; k <= j; k++) { if (s[k] != s[i + j - k]) ok = 0; } if (ok && j - i + 1 > max) { max = j - i + 1; x = p[i]; y = p[j]; } } } for (i = x; i <= y; i++) { printf("%c", buf[i]); } printf("\n"); return 0;}
方法2:枚舉迴文串的中間位置。
#include <stdio.h>#include <string.h>#include <ctype.h>#define MAXN 5000 + 10char buf[MAXN], s[MAXN];int p[MAXN];int main(void){ int n, m = 0, max = 0, x, y; int i, j; fgets(buf, sizeof(buf), stdin); n = strlen(buf); for (i = 0; i < n; i++) { if (isalpha(buf[i])) { p[m] = i; //儲存字元實際位置 s[m++] = toupper(buf[i]); } } for (i = 0; i < m; i++) //枚舉迴文串的中間位置 { for (j = 0; i - j >= 0 && i + j < m; j++) //迴文子串長度為奇數 { if (s[i - j] != s[i + j]) break; if (j * 2 + 1 > max) { max = j * 2 + 1; x = p[i - j]; y = p[i + j]; } } for (j = 0; i - j >= 0 && i + j + 1 < m; j++) //迴文串長度為偶數 { if (s[i - j] != s[i + j + 1]) break; if (j * 2 + 2 > max) { max = j * 2 + 2; x = p[i - j]; y = p[i + j + 1]; } } } for (i = x; i <= y; i++) printf("%c", buf[i]); printf("\n"); return 0;}解析:枚舉迴文串的中間位置時要注意長度為奇數和偶數的處理方式是不一樣的。
7題:編碼實現求給定字串(全為小寫英文字母)的最小後繼,如"abc"的最小後繼為"abd","dhz"的最小後繼為"di"。(Google筆試題)
#include <stdio.h>#include <string.h>#define MAXN 1024int main(void){ char buf[MAXN]; int n, m, i; scanf("%s", buf); n = strlen(buf); for (i = n - 1; i >= 0; i--) { if (buf[i] + 1 <= 'z') { buf[i] += 1; buf[i + 1] = '\0'; break; } } printf("%s\n", buf); return 0;}
解析:對最後一個字元+1,如果大於'z'則對前一個字元+1,如果又大於 'z' 則重複之前的步驟。
8題:X86結構下,下面代碼的printf輸出結果是什嗎?(西艾面試題)
#include <stdio.h>int main(void){ char str[20]="Good night"; int *p = (int *)str; p[0] = 0x61626364; p[1] = 0x31323334; p[2] = 0x41424344; printf("%s\n", str); return 0;}
解析:輸出結果為:dcba4321DCBA。X86結構下,資料的低位儲存在記憶體的低地址中,資料的高位儲存在記憶體的高地址中。還需要注意常見字元的ASCII碼(十進位),’a’為97,’A’為65,’1’為49。
9題:編一個函數,輸入一個字串,要求做一個新字串,把其中所有的一個或多個連續的空白字元都壓縮為一個空格。這裡所說的空白包括空格、'\t'、'\n'、'\r'。例如原來的字串是:
This Content hoho is ok
ok?
file system
uttered words ok ok ?
end.
壓縮了空白之後就是:
This Content hoho is ok ok? file systemuttered words ok ok ? end.(面試題)
參考程式如下:
#include <stdio.h>#include <string.h>#include <stdlib.h>const char *p = "This Content hoho is ok\ ok?\\ file system\n\uttered words ok ok ?\end.";int IsSpace(char c){ if (c == ' ') return 1; else if (c == '\n' || c == '\r') return 2; else if (c == '\t') return 3; else return 0;}char *shrink_space(char *dest, const char *src, size_t n){ char *t_dest = dest; char temp; int pre = -1, cur = -1, key = -1; while (IsSpace(*src)) //忽略字串起始空格 src++; *t_dest = *src; while ((temp = *src++) != '\0') { key = IsSpace(temp); if (0 == key) //0表示字元 { cur = 0; *t_dest++ = temp; } else if (1 == key) //1表示空格 { if (pre == 1) //如果前面也是空格 continue; else { cur = 1; *t_dest++ = temp; } } else if (2 == key && pre == 0) { *t_dest++ = ' '; } else if (3 == key) { if (pre == 1) continue; else { *t_dest++ = ' '; //將\t轉換為1個空格 cur = 1; } } pre = cur; } *t_dest = '\0'; return dest;}int main(void){ int len = strlen(p); char *dest = (char *)malloc(sizeof(char) * (len + 1)); shrink_space(dest, p, 1); printf("%s\n", dest); free(dest); dest = NULL; return 0;}
10題:寫出在母串中尋找子串出現次數的代碼。(面試題)
#include <stdio.h>#include <string.h>#define BUFSIZE 1024int StrCount(char *strLong, char *strShort){ int result = 0; char *t_strS = strShort; char *t_strD = strLong; while (*t_strD != '\0') { t_strS = strShort; //子串 while (*t_strD == *t_strS && *t_strS != '\0' && *t_strD != '\0') { t_strD++; t_strS++; } if (*t_strS == '\0') result += 1; else if (*t_strD == '\0') break; else t_strD++; } return result;}int main(void){ int len; char strD[BUFSIZE], strS[BUFSIZE]; fgets(strD, sizeof(strD), stdin); len = strlen(strD); strD[len - 1] = '\0'; fgets(strS, sizeof(strS), stdin); len = strlen(strS); strS[len - 1] = '\0'; printf("%d\n", StrCount(strD, strS)); return 0;}
資料結構有關字串的面試題 解答
建一張hash表,記錄a-z 26個字母的出現次數
char table[ 26 ] ;
第一題,假設第一個字串為s1,第2個字串為s2
for( i = 0 ; i < 26 ) ; i ++)
table[ i ] = 0 ;
for( i = 0 ; i < strlen( s1 ) ; i ++)
table[ s1[i] - 'a' ] ++ ;
for( i = 0 ; i < strlen( s2 ) ; i ++ )
if( table[ s2[i] - 'a' ] == 0 )
{
print( "字母 %c 沒有出現" , s2[i] );
break;
}
if( i >= strlen( s2 ) )
print( "字母全部出現" );
複雜度應是 O(M+N) , M和N分別是s1和s2的長度
第二題更簡單了:
for( i = 0 ; i < 26 ) ; i ++)
table[ i ] = 0 ;
for( i = 0 ; i < strlen( s1 ) ; i ++)
table[ s1[i] - 'a' ] ++ ;
for( i = 0 ; i < 26 ) ; i ++)
if( table[i] == 1 )
print( "只出現一次的字母: %c" , table[i] );
8088組合語言上機實驗考試題 1、從鍵盤輸入一個字串(串長度小於100個字元),統計其串的長度後輸出該串
;同學我幫你完成了你的程式,編譯通過,可 1、從鍵盤輸入一個字串(串長度小於100個字元),統計其串的長度後輸出該串,需要說明的是最後輸出的字串長度是十六進位的,不過這個關係不大。呵呵
;加點分哈~~~~~~~~~~~~~~~~~~~~~~~~~~~
;-----------------------------------------------------------------
;-------------------------------
;宏定義
display MACRO string
mov ah,09h
lea dx,string
int 21h
ENDM
;-------------------------------
;********************************資料區段
data segment
array db 100 dup(0) ;數組開闢空間
string1 db "Please input a string ended with ENTER: $" ;字串以$結束
string2 db "The length of the string = $"
string3 db "The string you inputed is: $"
crlf db 13,10,13,10,"$" ;13斷行符號,10換行
data ends
;**********************************
;**********************************程式碼片段
code segment
assume ds:data,cs:code ;段對應關係的說明
main proc far ;far子程式調用時的參數
;-----------------------------------------
start:
push ds
sub ax,ax ;清零
push ax ;壓棧
mov ax,data ;將資料傳送入資料區段
mov ds,ax
;---------------------------------------
;主程式開始
;---------------------------------------------------------
;顯示"Please input a string ended with ENTER: $"的內容
display stri......餘下全文>>