LoginSignup
1
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-12

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


    #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関数を作ってみた(空白も含む)

    #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


    #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関数を作ってみた

    #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

    #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;
    }
    #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


    #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;
    }

    #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を文字列スタートにしている!


    #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;
    }

シャッフル

    #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;
    }

カードゲーム

    #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;
    }

文字列変換

#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]で処理できるからだ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0