2018華為校招筆試題
阿新 • • 發佈:2019-02-15
校招題1 字串重排
給定一個原始字串,統計字串中各字元出現的次數,並按照ASCII碼遞增的順序依次輸出。
例:原始字串為eeefgghh
統計字串中各字元的出現次數:
e : 3
f : 1
g : 2
h : 2
重排字串輸出為:efgheghe
說明:給定的原字串只包含數字和字母,大寫字母和小寫字母存在區別。
樣例輸入輸出:
eeefgghh
efgheghe
這道題其實在平時的C語言中就有過小模組的訓練,一般分為字串中字元的計數和字串的重排。計數可以通過設定陣列,陣列的下標為字元的ASCII碼,陣列儲存的數為對應字元的數量,特別要注意下標的查重。但是C++STL提供的關聯容器map使得計數和排序變得格外簡單。map的key值用於存放字元,value用於存放對應字元的數量。由於map本身的特性,字元已經預設按照ASCII碼遞增的方式存放了,接下來需要考慮如何重排字串。我的想法是通過控制迭代器對value的指向是否大於0,來判斷對應字元是否應該輸出。由於map是鍵值匹配關係,設定迭代器it,其中it->first是key值,it->second是value值。當it->second>0時,輸出it->first,it後移;否則直接it後移。而當輸出一輪字元時,it需要回到起始位置,這時的判斷條件應該是it==map.end() && n>0,這裡的n指的是剩餘字串的長度。
大功告成,直接上程式碼:
#include<iostream> #include<cstring> #include<map> using namespace std; int main(){ string str; map<char,int> s; getline(cin,str); for(int i=0;i<str.length();i++){ s[str[i]]++; } int n=str.length(); for(map<char,int>::iterator it=s.begin();;){ if(it->second>0){ cout<<it->first; it->second --; it++; n--; } else{ it++; } if(it==s.end() && n>0) it=s.begin(); if(n==0) break; } return 0; }
輸入輸出顯示:
如有更好方法,請各位大佬指正。