題目:點擊開啟連結
求重複的號碼東西。第一反應就是MAP(他們有用hash做的),寫起來也很順(我指標弱渣)實際應用的時候卻發現了一些陷阱,導致了若干次的wa.
原理很簡單:打表,轉化成數字,忽略橫杠,添加到MAP裡,根據MAP自動管理的特性(自動保持升序,自動開記憶體++等)輸出重複的次數。
但陷阱也挺麻煩,可能和我略奇葩的思維有關
1、刪除橫杠。
下面的代碼,看上去很對有木有??刪除橫杠啊~
錯解1:
string::iterator it;for(it=tar.begin();it!=tar.end();it++) {if((*it)=='-'){tar.erase(it); }}
但是如果用這句來刪除橫杠,會報非法記憶體,為什麼呢?不信你寫個123-4-5-6--7--試試。即防不住兩個橫杠,也防不住最後的橫杠,刪著刪著就出緩衝區了。。
正解,用別的字串res存不就行了。。
for(int p=0;p<tar.size();p++){if(isdigit(tar[p]))res+=tar[p];}
2、兩種存入方式。
錯解:無腦用map["1234567"]++存。存這個會報TLE,原理是按重載的運算子[]進行更新的話,會把所有的已知參數都搜尋一遍,非常麻煩。
正解:分情況討論
map<string,int>::iterator apper=phonepack.find(conv);if(apper==phonepack.end()){ phonepack.insert(map<string,int>::value_type(conv,1));}else{phonepack[conv]++;}
3、注意沒輸出的情況,這個純讀題問題。
綜合以上情況,終於能AC了,雖然也有點卡時間 1700/2000 MS...
#include <string>#include <map>#include <algorithm>#include <ctype.h>#include <stdlib.h>#include <iostream>using namespace std;map<string,int> phonepack;string phonecall(string tar){string res;for(int i=0;i<tar.size();i++){if(tar[i]=='A' || tar[i]=='B' || tar[i]=='C')tar.replace(i,1,"2");else if(tar[i]=='D' || tar[i]=='E' || tar[i]=='F')tar.replace(i,1,"3");else if(tar[i]=='G' || tar[i]=='H' || tar[i]=='I')tar.replace(i,1,"4");else if(tar[i]=='J' || tar[i]=='K' || tar[i]=='L')tar.replace(i,1,"5");else if(tar[i]=='M' || tar[i]=='N' || tar[i]=='O')tar.replace(i,1,"6");else if(tar[i]=='P' || tar[i]=='R' || tar[i]=='S')tar.replace(i,1,"7");else if(tar[i]=='T' || tar[i]=='U' || tar[i]=='V')tar.replace(i,1,"8");else if(tar[i]=='W' || tar[i]=='X' || tar[i]=='Y')tar.replace(i,1,"9");}/*string::iterator it;for(it=tar.begin();it!=tar.end();it++) //不加這一句可能會導致系統讀取非法記憶體,因為刪除了標識符就沒了,-有很多會出錯 {if((*it)=='-'){tar.erase(it); cout<<tar<<endl;}}*/for(int p=0;p<tar.size();p++){if(isdigit(tar[p]))res+=tar[p];}return res;}int main(){int testcase;map<string,int>::iterator it2;cin>>testcase;for(int i=0;i<testcase;i++){string region;string conv;cin>>region;conv=phonecall(region);map<string,int>::iterator apper=phonepack.find(conv);if(apper==phonepack.end()){ phonepack.insert(map<string,int>::value_type(conv,1));}else{phonepack[conv]++;}}int pos=0;//初始化,又WA一次 for(it2=phonepack.begin();it2!=phonepack.end();it2++){if((*it2).second>1) //輸出格式比較麻煩 {for(int i=0;i<=2;i++)cout<<(*it2).first[i];cout<<"-";for(int j=3;j<=6;j++)cout<<(*it2).first[j];cout<<" "<<(*it2).second<<endl;pos++;}}if(pos==0){cout<<"No duplicates."<<endl;}return 0;}