STL #include stringのまとめ。

以外と曖昧なコンストラクタの実験から.

string ( );
string ( const string& str );
string ( const string& str, size_t pos, size_t n = npos );
string ( const char * s, size_t n ); 
//Content is initialized to a copy of the string formed by the first n characters in the array of characters pointed by s.
string ( const char * s );  //普通のcharでも通るよ.
string ( size_t n, char c );
template string (InputIterator begin, InputIterator end);

//std::string::nposは-1 とは限らないし、s.length()とも限らない.処理系に依存する.

出力系にも絡んでくる.
http://d.hatena.ne.jp/kenta11626918/20110412/1302619244

substr

#include 
string substr( size_type index = 0, size_type length = npos ) const;

string a = "abcdefghij";
substr(0, 4);  //a = "abcd";
substr(4)  //a = "efghij";

int sz = A.length();
    for(int i = 0; i <= sz; i++) {
      string newstr = A.substr(0, i) + B + A.substr(i);  //一見、out_of_rangeされそうだが、実はOK!!
//i = szでもOKなのです。ただし、A.substr(sz) == "";
}

string tmp= "0123456";
tmp.substr(0, 100)は実は通る.
例えば、
if(tmp.substr(0, otherLen ) == a[i]) {
..
}
としても、otherが0だろうが、100だろうが、out_of_rangeしない.ちなみに、(tmp.substr(0, 100) == tmp)が真.
唯一きをつけるべきことは、
tmp.substr(9, 0)とかはout_of_rangeする。
tmp.substr(11, 2)とか。


find
string型には、もう定義されてる

  #include 
    size_type find( const string& str, size_type index = 0 ) const;
    size_type find( const charT* str, size_type index = 0 ) const;
    size_type find( const charT* str, size_type index, size_type length ) const;
    size_type find( charT ch, size_type index = 0 ) const;

ここでポイントなのが、インデックス番号を返すということ.
インデックス番号を知るには、ふつうに、

cout << find(str.begin(), str.end(), item) << endl;

とすれば、OK!!
文字列を逆からたどりたいときとかはrfindを使えば良い.

  string s = "10001100";
  int pos = s.rfind('1');  //pos = 5
  for(int i = pos; i < s.length(); i++) {
    cout << s[i] << endl;  //1 0 0
  }

rfind()関数は、検索文字列を”index”から逆順に文字列を検索し、最後に見つかった位置を返します。
もし文字列が見つからないと、string::not_foundを返します。(string::npos)じゃないよ。
検索位置は、文字列の最初から0から数えます。
逆順に検索を開始し、最後に現れる位置を返します。


文字の重複を取り除きたい.

0011001101  -->010101
word.erase(  unique(  word.begin(), word.end()  ), word.end()  );
eraseの定義  イテレータを返す.
    #include 
    iterator erase( iterator loc );
    iterator erase( iterator start, iterator end );
    basic_string& erase( size_type index = 0, size_type num = npos );

replace

#include 
string& replace( size_type index, size_type num, const string& str );
string& replace( iterator start, iterator end, const string& str );

//str.replace(3, 5, other) //とかやると、3..7文字目までの文字列をreplaceするといういみになる。
まちがった意味(二つ目の意味)でとらえないこと。
とかんがえると、iteratorのほうはつかいづらいかも。
基本的にstringの文字列をforでまわすときは、
for(int i = 0; i < len; i++) とするはずで、
for(string::iterator it = str.begin(); it != str.end(); it++) とはしないかな。
と思った.


erase

    #include 
    iterator erase( iterator loc );
    iterator erase( iterator start, iterator end );
    basic_string& erase( size_type index = 0, size_type num = npos );
//削除された文字の次の文字を指すイテレータを返します。
  string str= "We are the world ,soo I learn about the word, too";
  string::iterator it;
  for(it = str.begin(); it != str.end(); it++) {
    if(*it == 'o') {
      str.erase(it);
    }
  }
  cout << str << endl;  //sooとかが正しく消されない.
  string str= "We are the world ,soo I learn about the word, too";
  string::iterator it;
  for(it = str.begin(); it != str.end();) {
    if(*it == 'o') {
      it = str.erase(it);
    } else {
      it++;
    }
  }
  cout << str << endl;

こうすればきちんと消せる.


word::   1  2  3  5  6
form[i]::1  2  5  3  6  //最低なんかいスワップしなければならないか.

    int res = INF;
    int bufsz = form.size();
    for(int i = 0; i < bufsz; i++) {
      int cnt = 0;
      string tmp = form[i];
      for(int j = 0; j < sz; j++) {
	if(tmp[j] != word[j]) {   //j番目で比較して違うならば、
	  int pos = tmp.find(word[j]);  
	  swap(tmp[j], tmp[pos]);  //入れ替える.
	  cnt++;
	}
      }
      res = min(res, cnt);
    }
    return (res == INF) ? -1 : res;


string型の文字列の比較は辞書順である.例えば、

//"10000" < "989"
//"878" < "9"
//とかが真である状態.文字列の状態のまま.

//どうしても数字による比較をしたければ、次のような関数を作ると良い.
//ただし、この関数では、stringの長さが10くらいまでしか対応指定いない。空白は0としている.
bool compareByNumber(string a, string b) {
  if(a == "" || b == "") {
    return (a == "") ? false : true;
  }
  int numa; int numb;
  sscanf(a.c_str(), "%d", &numa);
  sscanf(b.c_str(), "%d", &numb);
  return (numa > numb) ? true : false;
}

//これなら、stringがどんな長さでも数字順に並ぶ.
string maxToInt(string a, string b) {
  string ans = "";
  int lena = a.length(); int lenb = b.length();
  if(lena > lenb) ans = a;
  else if(lena < lenb) ans = b;
  else ans = (a > b) ? a : b;
  return ans;
}