char型、string型の文字列の違い(AIZU 8,9)

#char型の配列で構成された文字列

宣言・初期化
①　char s[6];
②　char s[6] = "Hello";
③　char s[ ] = "Hello"; (null文字も含めたびっしりの箱が完成)
④　char s[8] = {'H' , 'e' , 'l' , 'l' , 'o' }(指定されてない要素は0に設定される)

関数一覧
① int strlen(char[ ] s)　→　文字列sの長さを返す
② char strcpy(char[ ] s1 , char[ ] s2)　→　文字列s1に文字列s2をコピーする　
③ char strcat(char[ ] s1 , char[ ] s2)　→　文字列s1に文字列s2を連結する
④ char strstr(char[ ] s1 , char[ ] s2)　→　文字列s1からs2を探す
ex)if (strstr(s1,s2)==NULL)
⑤ int strcmp(char[ ] s1, char[ ] s2)　→　文字列s1と文字列s2を比較する
※
s1 < s2...負の値を返す
s1=s2...0を返す
s1 > s2...正の値を返す

#大文字と小文字の入れ替え
ex) This is a pen → tHIS IS A PEN

```c

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        char ch;
        while(1){
            scanf("%c",&ch);// 2文字目以降を自動で入力していることになってる！
            if (isalpha(ch)){
                if (islower(ch)) printf("%c",toupper(ch));
                else printf("%c",tolower(ch));
            } else printf("%c",ch);
            if (ch=='\n') break;
            
        }
        return 0;
    }
```
###大文字小文字を入れ替えるtransfer関数を作ってみた(空白も含む)

```c
    #include<bits/stdc++.h>
    using namespace std;
    
        string transfer(string s){
            string t=s;
            for (int i=0; i<s.size(); i++){
                if (isalpha(s[i])){
                    if (islower(s[i])) t[i]=toupper(s[i]);
                    else t[i]=tolower(s[i]);
                }
                else t[i]=s[i];
            }
            return t;
        }
    
        int main(){
            string A,ans;
            while(getline(cin,A)){
            //getline関数は空白を読み込む！　→　一行ごとに区切るから！　
                ans=transfer(A);
                cout << ans << endl;
            }
        }
```



#整数における各桁の和
ex) 101→2  24→6

```c

    #include<bits/stdc++.h>
    using namespace std;
        
    int main(){
        char ch[1001];//1000個の箱を作ればよい！
        while(1){
            int ans=0;
            scanf("%s",ch);//chを文字列として入力！
                           //文字列を自動でch[0]~ch[1001]まで入れてくれている！
            
            for (int i=0; i<strlen(ch); i++){
                ans+=ch[i]-'0';
            }
            if (ch[0]=='0') break;
            cout << ans << endl;
        }
        return 0;
    }
```
###各桁のsum関数を作ってみた

```c
    #include<bits/stdc++.h>
    using namespace std;
    
    int sum(string s){
        int t=0;
        for (int i=0; i<s.size(); i++){
            t+=s[i]-'0';
        }
        return t;
    }
    
    int main(){
        string s1;
        while(cin >> s1){
            int ans;
            if (s1[0]=='0') break;
            ans = sum(s1);
            cout << ans << endl;
        }
        return 0;
    }
```
#文字のカウント
ex) This is a pen →
a : 1
b : 0
・
・          
z : 0

```c
    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        char ch;
        int cnt[26]={};//気づくことが難しい置き方！
        
        while(cin >> ch){
            ch=tolower(ch);
            if (isalpha(ch)){
                cnt[ch-'a']++;
            }
        }
        
        for (int i=0; i<26; i++){
            printf("%c : %d\n",i+'a',cnt[i]);//i+'a'は最終的にint型になる！
        }
        return 0;
    }
```
```c
    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        int cnt[26]={};
        string s;
        
        while(cin >> s){
            for (int i=0; i<s.size(); i++){
                if (isalpha(s[i])){
                    s[i]=tolower(s[i]);
                    cnt[s[i]-'a']++;
                }
            }
        }
        
        for (int i=0; i<26; i++){
            printf("%c : %d\n",i+'a',cnt[i]);
        }
        return 0;
    }
```
#リング

ex)
 abcd   ab → Yes
 abcd   de → No

```c

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        char s1[101],s2[101],s3[201];
        scanf("%s %s",s1,s2); //("%s,%s)にしないように注意！
        strcpy(s3,s1);
        strcat(s3,s1);
        if (strstr(s3,s2) == NULL) cout << "No" <<endl;
        else cout << "Yes" <<endl;
        return 0;
    }
```
```c

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        string s1,s2;
        cin >> s1 >> s2;
        
        s1+=s1;
        if (s1.find(s2)!=-1) cout << "Yes"<< endl;//find関数とは探している文字列がない場合、-1を返す関数！
        else cout << "No" << endl;
        return 0;
    }
```
#string型の配列で構成された文字列

宣言・初期化
①　string color = "black";
※宣言の際に格納できる文字列の長さを指定する必要がない！

関数一覧
※sは文字列
①s.size()→文字列sの文字数を返す
②s.substr(1,4)→指定した文字列を返す(要素1から4文字)
③s.replace(1,4,"abcd")→指定した文字列を置き換える(要素1から4文字を"abcd"へ)
④s.find(a)→指定した文字列がsの中に含まれているか判断する(sの中にaがなければ、-1を返す)

#単語の検索
文字列→文字→文字列は最終的に文字列として出力できる！
文字→文字列は、最終的に文字列として出力できない（s[0],s[1]とかの文字なら出力できる）！

故に、toUpper関数で最初にstring t ;ではなく、string t=s ;としてtを文字列スタートにしている！

```c

    #include<bits/stdc++.h>
    using namespace std;
    
    string toUpper(string s){
        string t=s; //string t;だとエラーになる！
        for (int i=0; i<s.size(); i++){
            t[i]=toupper(s[i]);
        }
        return t;
    }
    
    int main(){
        string target,source;
        
        cin >> target;
        target = toUpper(target);
        
        int cnt=0;
        
        while(1){
            cin >> source;
            if (source == "END_OF_TEXT") break;
            source = toUpper(source);
            if (target == source) cnt++;
        }
        
        cout << cnt << endl;
        return 0;
    }
```
#シャッフル
```c
    #include<bits/stdc++.h>
    using namespace std;
    
    string shuffle(string str, int h){
        string head = str.substr(0,h);
        string tail = str.substr(h,str.size()-h);
        return tail + head;
    }
    
    int main(){
        string cards;
        int m,h;
        
        while(1){
            cin >> cards;
            if (cards == "-") break;
            
            cin >> m;
            for (int i=0; i<m; i++){
                cin >> h;
                cards = shuffle(cards,h);
            }
            cout << cards << endl;
        }
        return 0;
    }
```
#カードゲーム
```c
    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        int n;
        string s1,s2;
        int a=0, b=0;
        cin >> n;
        
        for (int i=0; i<n; i++){
            cin >> s1 >> s2;
            if (s1>s2) a+=3;
            else if (s1<s2) b+=3;
            else{
                a++;b++;
            }
        //同時にaとbの処理を行うときはそれぞれに　;　をつける！
        }
        cout << a << " " << b << endl;
        return 0;
    }
```
#文字列変換
```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    string target,order,A,p;
    int n,a,b;
    cin >> target >> n;
    
    for (int i=0; i<n; i++){
        cin >> order >> a >> b;
        if (order=="print"){
            cout << target.substr(a,b-a+1) << endl;
        }    //a 文字目から b 文字目までを出力する。
        else if (order=="reverse"){
            //a 文字目から b 文字目までを逆順にする。
            A=target.substr(a,b-a+1);
            for (int i=0; i<b-a+1; i++){
                target[a+i]=A[b-a-i];
            }
        }
        else if (order=="replace"){
            //a 文字目から b 文字目までを p に置き換える。
            cin >> p;
            target = target.replace(a,b-a+1,p);
        }
   }
    return 0;
}
```
#結論
以上、AizuOnlineJudegeの8問を解いてみたが、string型で8問解けたのでchar型の重要度は低いように見えた。（絶対いらないとは言ってない）
もしchar型の処理を要するときは、string型からfor (int i=0;~~)とやってS[i]で処理できるからだ。