Page List

Search on the blog

2011年9月22日木曜日

文字列に関するcoding tips

ちょっとしたtipsを紹介します。
  1. accumulate()で文字結合
  2. mapは使わない
  3. 文字をint型に代入する
まず、1.番目。vectorで与えられた入力をconcatenate して新しい文字列を作成せよ。よくありますね。これをどう書くか。

  1. vector<string> x;  
  2.   
  3. void init() {  
  4.     x.push_back("acchan");  
  5.     x.push_back("yuko");  
  6.     x.push_back("yukirin");  
  7.     x.push_back("mayuyu");  
  8. }  
  9.   
  10. int main() {  
  11.     init();  
  12.   
  13.     string y = "";  
  14.     REP(i, x.size())  
  15.         y += x[i];  
  16.   
  17.     cout << y << endl;  
  18.     return 0;  
  19. }  

でもいいけど、accumulate()を使うとちょっとだけかっこよく書けます。accumulate()はdefaultでは演算子+を用いる。stringに対する+は文字の結合なのでそのまま使えます。

  1. int main() {  
  2.     init();  
  3.   
  4.     string y = accumulate(ALL(x), string());  
  5.   
  6.     cout << y << endl;  
  7.     return 0;  
  8. }  


次に、2.番目。文字の出現回数を数えています。char -> intへの写像なので、mapを使うのが自然に見えます。

  1. int main() {  
  2.     string x = "riverponiiteerutoshushuheavyrotationeverydaykachusha";  
  3.   
  4.     map<charint> cnt;  
  5.     REP(i, x.size())  
  6.         cnt[x[i]]++;  
  7. }  

でも、charなんて高々[0, 256)までなので、配列に入れるのもありです。C++の配列はランダムアクセスなので、こっちの方が計算量は安いです。[0, 256)と書きましたが、ASCIIコード表を見ると、実際に使われるコードは[0, 128)で十分のようです。AKBのメンバーの名前を覚える暇があったら、ASCIIコードを覚えましょう。(→自分)

  1. int main() {  
  2.     string x = "riverponiiteerutoshushuheavyrotationeverydaykachusha";  
  3.   
  4.     int cnt[128];  
  5.     memset(cnt, 0, sizeof(cnt));  
  6.     REP(i, x.size())  
  7.         cnt[x[i]]++;  
  8. }  

最後に、3.番目。これは、文字をインクリメントして走査したい場合です。それぞれの数字がdigit中に何回出てくるかを標準出力に表示します。

  1. int main() {  
  2.     string digit = "1234254723075027659279743057423953";  
  3.   
  4.     for (char i = '0'; i <= '9'; i++)  
  5.         cout << count(ALL(digit), i) << endl;  
  6. }  

とか、

  1. int main() {  
  2.     string digit = "1234254723075027659279743057423953";  
  3.   
  4.     REP(i, 10)  
  5.         cout << count(ALL(digit), i+'0') << endl;  
  6. }  

とかやっていましたが、以下のようにできますね。プロコン界伝統の悪しきマクロで書いてますが、iはintで持っています。charではなく、intで持っていた方が何かと便利です。

  1. int main() {  
  2.     string digit = "1234254723075027659279743057423953";  
  3.   
  4.     FOR (i, '0''9'+1)  
  5.         cout << count(ALL(digit), i) << endl;  
  6. }  

0 件のコメント:

コメントを投稿