T21:單詞替換
描述
輸入一個字符串,以回車結束(字符串長度<=100)。該字符串由若干個單詞組成,單詞之間用一個空格隔開,所有單詞區分大小寫。現需要將其中的某個單詞替換成另一個單詞,並輸出替換之后的字符串。
輸入
輸入包括3行,
第1行是包含多個單詞的字符串 s;
第2行是待替換的單詞a(長度 <= 100);
第3行是a將被替換的單詞b(長度 <= 100).
s, a, b 最前面和最后面都沒有空格.
輸出
輸出只有 1 行,將s中所有單詞a替換成b之后的字符串。

樣例輸入
You want someone to help you
You
I
樣例輸出
I want someone to help you

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 char s[501],a[501],b[501]; 6 string f[101]; 7 bool v[101]; 8 int main() 9 { 10 gets(s);gets(a);gets(b); 11 int k=1,l=strlen(s); 12 for(int i=0;i<l;i++) 13 { 14 if(s[i]!=' ') 15 f[k]+=s[i]; 16 else k++; 17 } 18 for(int i=1;i<=k;i++) 19 { 20 if(f[i]==a) cout<<b<<' '; 21 else cout<<f[i]<<' '; 22 } 23 }
T22 緊急措施
描述
近日,一些熱門網站遭受黑客入侵,這些網站的賬號、密碼及email的數據慘遭泄露。你在這些網站上注冊若干賬號(使用的用戶名不一定相同),但是注冊時使用了相同的email。你此時拿到了那份泄露的數據,希望盡快將自己的密碼更改。策略如下:根據email找到你的用戶名和密碼,然后更改密碼。更改的規則為:小寫和大寫交換,非字母字符保持不變。
輸入
第一行為你的email地址,長度不超過50個字符且只包含字母、數字和‘@’符號。
第二行為賬號數N,N(0 < N < 10000)。
接下來N行,每行表示一個賬號,格式為:
用戶名 密碼 email
它們之間用單個空格分開。用戶名、密碼、email均不含空格,且長度不超過50個字符。
輸出
有若干行,每行為你的一個賬號,包括:你的賬號,修改后的密碼(之間用單個空格分隔)。
如果沒有你的賬號,則輸出empty。

樣例輸入 樣例輸入1: abc@pku.edu.cn 5 helloKitty iLoveCats abc@pku.edu.cn 2012 maya2012 cplusplus@exam.com KittyCat 5iKitty abc@pku.edu.cn program password teacher@exam.com whoAmi Feb.29$ abc@pku.edu.cn 樣例輸入2: abc@pku.edu.cn 1 2012 maya2012 cplusplus@exam.com 樣例輸出 樣例輸出1: helloKitty IlOVEcATS KittyCat 5IkITTY whoAmi fEB.29$ 樣例輸出2: empty

1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 string me,usename,password,email; 5 int n; 6 bool ok; 7 int main() 8 { 9 cin>>me;cin>>n; 10 for(int i=1;i<=n;i++) 11 { 12 cin>>usename>>password>>email; 13 if(me==email) 14 { 15 ok=true; 16 cout<<usename<<' '; 17 for(int j=0;j<password.size();j++) 18 if(password[j]>='a'&&password[j]<='z') cout<<char(password[j]-32); 19 else if(password[j]>='A'&&password[j]<='Z') cout<<char(password[j]+32); 20 else cout<<password[j]; 21 cout<<endl; 22 } 23 } 24 if(!ok) cout<<"empty"; 25 }
T23 過濾多余的空格
描述
一個句子中也許有多個連續空格,過濾掉多余的空格,只留下一個空格。
輸入
一行,一個字符串(長度不超過200),句子的頭和尾都沒有空格。輸出過濾之后的句子。

樣例輸入 Hello world.This is c language. 樣例輸出 Hello world.This is c language.
每相鄰連個判斷一次,若相鄰兩個都是空格,則刪除后面的,刪除可以通過bool實現

1 #include<cstring> 2 #include<iostream> 3 #include<cstdio> 4 using namespace std; 5 char a[501]; 6 bool b[501]; 7 int main() 8 { 9 gets(a); 10 for(int i=0;i<strlen(a);i++) 11 if(a[i]==' '&&a[i+1]==' ') b[i+1]=true;//true代表為多余的空格 12 for(int i=0;i<strlen(a);i++) 13 { 14 if(b[i]) continue; 15 cout<<a[i]; 16 } 17 }
T24 單詞的長度
描述
輸入一行單詞序列,相鄰單詞之間由1個或多個空格間隔,請對應地計算各個單詞的長度。
注意,如果有標點符號(如連字符,逗號),標點符號算作與之相連的詞的一部分。沒有被空格間開的符號串,都算作單詞。
輸入
一行單詞序列,最少1個單詞,最多300個單詞,單詞之間用至少1個空格間隔。單詞序列總長度不超過1000。
輸出
依次輸出對應單詞的長度,之間以逗號間隔。
注意中間可能有相連的好幾個空格,排除方法參見下方T25題解

樣例輸入 She was born in 1990-01-02 and from Beijing city. 樣例輸出 3,3,4,2,10,3,4,7,5

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 char a[2001]; 6 int s; 7 int main() 8 { 9 gets(a); 10 int l=strlen(a); 11 for(int i=0;i<l;i++) 12 { 13 if(a[i]!=' ') s++; 14 else if(a[i]==' '&&a[i-1]!=' ') //排除掉多個空格相連的情況 15 { 16 cout<<s<<','; 17 s=0; 18 } 19 } 20 cout<<s; 21 }
T25 最長最短單詞
描述
輸入1行句子(不多於200個單詞,每個單詞長度不超過100),只包含字母、空格和逗號。單詞由至少一個連續的字母構成,空格和逗號都是單詞間的間隔。
試輸出第1個最長的單詞和第1個最短單詞。
輸入
一行句子。
輸出
兩行輸出:
第1行,第一個最長的單詞。
第2行,第一個最短的單詞。

樣例輸入 I am studying Programming language C in Peking University 樣例輸出 Programming I
如果所有單詞長度相同,那么第一個單詞既是最長單詞也是最短單詞。
注意中間可能有相連的好幾個空格或逗號
確定一個單詞,排除相連的幾個空格或逗號的干擾的方法:若是2個單詞之間的空格,則滿足(a[i]==' '||a[i]==',')&&(a[i-1]!=' '&&a[i-1]!=','),即這一位是空格或逗號,上一位既不是空格,又不是逗號,本方法同樣適用T24

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 char a[3001]; 6 int s; 7 int max_len,max_num,min_len=200,min_num;//分別代表含義:最長單詞的長度,最長單詞是第幾個單詞,最短單詞的長度,最短單詞是第幾個單詞 8 string f[201];//存儲斷開的單詞 9 int main() 10 { 11 gets(a); 12 int k=1;//要存儲第幾個單詞 13 int l=strlen(a); 14 for(int i=0;i<l;i++) 15 { 16 if(a[i]!=' '&&a[i]!=',') f[k]+=a[i],s++;//s代表當前單詞長度 17 else if((a[i]==' '||a[i]==',')&&(a[i-1]!=' '&&a[i-1]!=',')) 18 { 19 if(s>max_len) {max_len=s;max_num=k;} 20 if(s<min_len) {min_len=s;min_num=k;} 21 s=0; 22 k++; 23 } 24 } 25 if(s>max_len) {max_len=s;max_num=k;}//由於只循環到strlen(a)-1,所以最后一個單詞在上述循環中是無法被記錄的 26 if(s<min_len) {min_len=s;min_num=k;} 27 cout<<f[max_num]<<endl<<f[min_num]; 28 }
T26:字符串最大跨距
- 描述
- 有三個字符串S,S1,S2,其中,S長度不超過300,S1和S2的長度不超過10。想檢測S1和S2是否同時在S中出現,且S1位於S2的左邊,並在S中互不交叉(即,S1的右邊界點在S2的左邊界點的左側)。計算滿足上述條件的最大跨距(即,最大間隔距離:最右邊的S2的起始點與最左邊的S1的終止點之間的字符數目)。如果沒有滿足條件的S1,S2存在,則輸出-1。
- 例如,S = "abcd123ab888efghij45ef67kl", S1="ab", S2="ef",其中,S1在S中出現了2次,S2也在S中出現了2次,最大跨距為:18。
- 輸入
- 三個串:S1, S2, S3,其間以逗號間隔(注意,S1, S2, S3中均不含逗號和空格);
- 輸出
- S1和S2在S最大跨距;若在S中沒有滿足條件的S1和S2,則輸出-1。

樣例輸入 abcd123ab888efghij45ef67kl,ab,ef 樣例輸出 18
特別注意字符串不交叉

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 char a[301],b[11],c[11],t[11]; 6 char s[401]; 7 int p,la,lb,lc,first,endd; 8 int find(int k,int w) 9 { 10 int j=1,i=k,lt; 11 if(w==2) 12 { 13 lt=lb; 14 for(int r=1;r<=lb;r++) t[r]=b[r]; 15 } 16 else 17 { 18 lt=lc; 19 for(int r=1;r<=lc;r++) t[r]=c[r]; 20 } 21 for(;i<=la,j<=lt;i++,j++) 22 if(a[i]!=t[j]) return 0; 23 if(j-1!=lt) return 0; 24 return k; 25 } 26 int main() 27 { 28 cin>>s; 29 int ls=strlen(s); 30 for(int i=0;i<ls;i++)/輸入一整行,再斷開 31 { 32 if(s[i]==',') p++; 33 else if(!p) a[++la]=s[i]; 34 else if(p==1) b[++lb]=s[i]; 35 else c[++lc]=s[i]; 36 } 37 for(int i=1;i<=la;i++) 38 { 39 if(a[i]==b[1]&&!first) first=find(i,2);//只需要出現的第一個位置,所以!first時才執行 40 if(a[i]==c[1]) endd=max(endd,find(i,3));//需要最后一個位置,所以要取大 41 42 } 43 if(first==0||endd==0||first+lb>endd) cout<<-1;//first+lb>endd,交叉的情況以及first>endd的情況都是-1 44 else 45 { 46 first+=lb;//first變成最大跨距中的第一個位置 47 cout<<endd-first;//endd為最大跨距中的最后一個位置的后一個。例:字符串abcde中找ab、de,first開始=1,+lb=3,endd=4,ans=end-first=1 48 } 49 }
兩大錯誤:1、沒認真讀好題,題目里說的是檢測條件是s1在s2左邊,且不交叉,不是輸入字符串的本就具備的條件
2、處理endd時,沒加max,忽略了find函數可能返回0,直接賦值有可能用0蓋過原來的值
- T27 單詞翻轉
- 描述
輸入一個句子(一行),將句子中的每一個單詞翻轉后輸出。
- 輸入
- 只有一行,為一個字符串,不超過500個字符。單詞之間以空格隔開。
- 輸出
- 翻轉每一個單詞后的字符串,單詞之間的空格需與原文一致。

樣例輸入
hello world
樣例輸出
olleh dlrow

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 char a[1001],b[1001]; 6 int main() 7 { 8 gets(a); 9 int la=strlen(a); 10 for(int i=0;i<la;i++) 11 { 12 if(a[i]==' ') 13 { 14 for(int j=b[0];j>0;j--) cout<<b[j];//若多個空格相連,b[0]=0,不會有輸出 15 b[0]=0; 16 cout<<' '; 17 } 18 else b[++b[0]]=a[i]; 19 } 20 for(int j=b[0];j>0;j--) cout<<b[j];//若最后一個但此后面沒有空格,執行此句輸出 21 }
T28 單詞倒排
描述
編寫程序,讀入一行英文(只包含字母和空格,單詞間以單個空格分隔),將所有單詞的順序倒排並輸出,依然以單個空格分隔。
輸入
輸入為一個字符串(字符串長度至多為100)。
輸出
輸出為按要求排序后的字符串。

樣例輸入
I am a student
樣例輸出
student a am I
法1:將T27的代碼第一重循環改為逆序即可

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 char a[1001],b[1001]; 6 int main() 7 { 8 gets(a); 9 int la=strlen(a); 10 for(int i=la-1;i>=0;i--) 11 { 12 if(a[i]==' ') 13 { 14 for(int j=b[0];j>0;j--) cout<<b[j]; 15 b[0]=0; 16 cout<<' '; 17 } 18 else b[++b[0]]=a[i]; 19 } 20 for(int j=b[0];j>0;j--) cout<<b[j]; 21 }
法2:開一個字符二維數組,單個字符單個字符的讀入,忽略空格以單詞的形式存儲,再倒着循環第一維輸出每個單詞和一個空格

1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int i; 6 char a[1002][102]; 7 i=1; 8 while(cin>>a[i])i++; 9 for(i--;i>=1;i--) 10 cout<<a[i]<<' '; 11 return 0; 12 }
T29 ISBN號碼
描述
每一本正式出版的圖書都有一個ISBN號碼與之對應,ISBN碼包括9位數字、1位識別碼和3位分隔符,其規定格式如“x-xxx-xxxxx-x”,其中符號“-”是分隔符(鍵盤上的減號),最后一位是識別碼,例如0-670-82162-4就是一個標准的ISBN碼。ISBN碼的首位數字表示書籍的出版語言,例如0代表英語;第一個分隔符“-”之后的三位數字代表出版社,例如670代表維京出版社;第二個分隔之后的五位數字代表該書在出版社的編號;最后一位為識別碼。
識別碼的計算方法如下:
首位數字乘以1加上次位數字乘以2……以此類推,用所得的結果mod 11,所得的余數即為識別碼,如果余數為10,則識別碼為大寫字母X。例如ISBN號碼0-670-82162-4中的識別碼4是這樣得到的:對067082162這9個數字,從左至右,分別乘以1,2,…,9,再求和,即0×1+6×2+„„+2×9=158,然后取158 mod 11的結果4作為識別碼。
你的任務是編寫程序判斷輸入的ISBN號碼中識別碼是否正確,如果正確,則僅輸出“Right”;如果錯誤,則輸出你認為是正確的ISBN號碼。
輸入
只有一行,是一個字符序列,表示一本書的ISBN號碼(保證輸入符合ISBN號碼的格式要求)。輸出共一行,假如輸入的ISBN號碼的識別碼正確,那么輸出“Right”,否則,按照規定的格式,輸出
正確的ISBN號碼(包括分隔符“-”)。

樣例輸入 樣例 #1: 0-670-82162-4 樣例 #2: 0-670-82162-0 樣例輸出 樣例 #1: Right 樣例 #2: 0-670-82162-4

1 #include<iostream> 2 using namespace std; 3 char a[15]; 4 int s; 5 int main() 6 { 7 cin>>a; 8 int j=1; 9 for(int i=0;i<=10;i++) 10 { 11 if(a[i]=='-') continue; 12 s+=(a[i]-'0')*j++; 13 } 14 s%=11; 15 if(s<10) 16 { 17 if(a[12]==char(s+48)) cout<<"Right";//數字的值與對應的ascll碼相差48 18 else 19 { 20 for(int i=0;i<=11;i++) cout<<a[i]; 21 cout<<char(s+48); 22 } 23 } 24 else 25 { 26 if(a[12]=='X') cout<<"Right"; 27 else 28 { 29 for(int i=0;i<=11;i++) cout<<a[i]; 30 cout<<'X'; 31 } 32 } 33 }
T30 字符環
描述
有兩個由字符構成的環。請寫一個程序,計算這兩個字符環上最長連續公共字符串的長度。例如,字符串“ABCEFAGADEGKABUVKLM”的首尾連在一起,構成一個環;字符串“MADJKLUVKL”的首尾連在一起,構成一個另一個環;“UVKLMA”是這兩個環的一個連續公共字符串。
輸入
一行,包含兩個字符串,分別對應一個字符環。這兩個字符串之間用單個空格分開。字符串長度不超過255,且不包含空格等空白符。
輸出
輸出一個整數,表示這兩個字符環上最長公共字符串的長度。

樣例輸入 ABCEFAGADEGKABUVKLM MADJKLUVKL 樣例輸出 6
這是一個環,環的特點是從任何一個位置轉一圈都能回到起點,也就是從任何一個位置開始遍歷都能把整個字符串遍歷一遍。假設有一個字符串a(從0開始),長度為l,我們可以將a復制一遍接到a的后面,這樣以0—l-1的任何一個點,長度為l的區域都是整個字符串,這就實現了環向鏈的轉化。
然后就是枚舉區間長度,區間起點、終點比較,因為是求最大,所以可以從兩個字符串的長度值較小的開始枚舉,依次遞減,符合要求就輸出,結束程序

1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 char a[1111],b[1111]; 5 int main() 6 { 7 cin>>a>>b; 8 int la=strlen(a),lb=strlen(b); 9 for(int i=0;i<la;i++) a[la+i]=a[i];//斷環成鏈 10 for(int i=0;i<lb;i++) b[lb+i]=b[i]; 11 for(int k=min(la,lb);k>=1;k--)//枚舉答案可能情況 12 for(int i=0;i<la;i++)//第一個字符串的左端點 13 { 14 int za=i+k-1;//第一個字符串區間長度為k時的右端點 15 for(int j=0;j<lb;j++)//第二個字符串的左端點 16 { 17 int zb=j+k-1;//第二個字符串區間長度為k時的右端點 18 int sa=i,sb=j; 19 bool flag=true; 20 while(sa<=za&&sb<=zb)//比較是否公共 21 { 22 if(a[sa]!=b[sb]) 23 { 24 flag=false; 25 break; 26 } 27 else sa++,sb++; 28 } 29 if(flag) 30 { 31 cout<<k; 32 return 0; 33 } 34 } 35 } 36 }