アルゴリズム学習ノート (C++) - 文字列処理

アルゴリズム学習メモ(C++) - 文字列処理

文字列の基本

  • 文字列標準テンプレートを使用するには、ヘッダー ファイル #include を追加する必要があります
  • 初期化に関しては、文字列を直接使用して変数に値を割り当てることができます
string str = "hello world";
// or
string str = str + " !!!";
  • 長さに関しては、size() と length() の 2 つのメソッドが使用できます。
  • アクセス方法としては、添字アクセスとイテレータアクセスの2通りがあります。
    (1) 添字アクセス:
string str = "hello world";
for (int i=0; i<str.size(); ++i){
    
    
	printf("%c", str[i]);
}

(2) イテレータアクセス

string str = "hello world";
for (string::iterator it = str.begin(); it !=str.end(); ++it){
    
    
	printf("%c", *it);
}
  • 文字列内の要素の操作については、

(1) 指定位置にinsert()を挿入

str.insert(index, str);
最初のパラメータは挿入された位置のインデックス
、2 番目のパラメータは挿入された文字列です

(2) 指定位置の消去 Erase()
str.erase(first_char, length_of_erase);
第一引数は削除インデックスの開始位置
、第二引数は削除文字列の長さで、デフォルトでは削除します。文字列の終わり

(3) 文字列clear()を
パラメータなしで空にする

  • 文字列を含む演算
    文字列の加算とは文字列を連結すること
    文字列の「==」「<=」「">」などの演算は辞書順に基づいて大小を比較する

  • その他よく使われる関数について
    (1) find()
    文字列内の特定の文字または文字列を検索し、見つかった場合は対応する添字を返し、見つからない場合は string::npos を返します (int 型受信の場合は -1) )

string渗透入= "hello world";
int found = str.find("world");
if(found != string::npos){
    
    
	cout << found << endl;
}
found = str.find('.');


(2) substr()
str.substr(begin_index, length)
第一引数は開始位置
、第二引数は文字列の全長です。

string str1 = "we think in generalities";
string str2 = str1.substr(3, 5);

文字列の応用例

注: 文字列適用のプロセスでは、境界の問題が頻繁に発生します
。文字列の読み取りプロセスでは、文字列にスペースが含まれている場合、cout と scanf を使用して読み取ることはできなくなり、文字列のロードは次の時点で終了します。 getline を使用すると、読み取りの中断を回避できます。

テーマ:
パスワード暗号化問題:
平文のA~Zの各文字をアルファベットの下5桁に相当する文字に置き換えると、V~ZはA→Fのように暗号文が得られます。平文の「 」(最後の 5 文字)は、暗号文の A ~ Z に対応します。
次に、暗号文を平文に変換する必要があります

入力形式:
暗号文の各行の最初の行は START、次の行は END で、最終的に ENDOFINPUT が読み取られるとプログラムは終了します。

出力形式は複数行で、各行にはプレーンテキストが含まれます。

# include <string>
# include <cstdio>
# include <iostream>

using namespace std;

int main(){
    
    
	string str;
	// the first line, deciding a new case of the end of code
	while(getline(cin, str)){
    
    
		if (str == "ENDOFINPUT"){
    
    
			break;
		}
		// text which is encoded
		getline(cin, str);
		for (int i=0; i<str.size(); ++i){
    
    
			if ( 'A' <= str[i] && str[i] <= 'Z'){
    
    
				str[i] = (str[i] - 5 + 26 - 'A') % 26 + 'A';
			}
		}
		string str1;
		// eat the string "END"
		getline(cin, str1);
		cout << str << endl;
	}
	return 0;
}

ここに画像の説明を挿入


指定された文字列内の指定された文字の出現数をカウントします。

入力形式:
各テスト サンプルは 2 行で構成され、最初の行は 5 文字以下の文字列、2 行目は 80 文字以下の文字列です (スペースを含む、つまり、スペースも必要な文字です)読み取り時 '#'に到達すると入力終了

出力形式:
テストサンプルごとに、1行目の文字列と2行目の文字列の各文字の出現回数をカウントし、以下の形式で出力します。
c0 n0
c1 n1
c2 n2

# include <cstdio>
# include <iostream>
# include <string>
# include <cstring>
using namespace std;
int number[128];

int main(){
    
    
	// record appearing times for every char
	string str1;
	string str2;
	while (getline(cin, str1)){
    
    
		if (str1=="#"){
    
    
			break;
		}
		// initial the array
		memset(number, 0, sizeof(number));// sizeof() returns how many bytes the array has
		getline(cin, str2);
		// count appearing times
		for (int i=0; i<str2.size(); ++i){
    
    
			number[str2[i]] += 1;
		}
		for (int i=0; i<str1.size(); ++i){
    
    
			printf("%c %d \n", str1[i], number[str1[i]]);
//			cout << str1[i] << " " << str2[str1[i]] << endl;
		}	
	}
	return 0;
}

ここに画像の説明を挿入

文字列マッチング問題 - KMP アルゴリズム

テキスト文字列とパターン文字列のマッチング問題には、効率的な KMP アルゴリズムがあります。
その核心は、パターン文字列が一致しない場合、次の文字列から開始して最初から再一致させるのではなく、既存の文字列を使用することです。情報を取得すると、パターン文字列とビーズ文字列のマッチング時間を最小限に抑え、マッチング作業を迅速に完了するために、正常にマッチングできない一部の位置をスキップします。

KMP アルゴリズムの時間計算量について:
次のテーブルを取得するためにパターン文字列を 1 回走査するだけでよく、テキスト文字列が文字列の一致を取得できるように次のテーブルを走査する必要があるため、KMP アルゴリズムの時間計算量はアルゴリズムは O(m+n)


例:
テキスト文字列内でパターンが正常に一致した回数をカウントします。

# include <cstdio>
# include <string>
# include <iostream>

using namespace std;
const int MAXN = 100;

int nextTable[MAXN];


void GetNextTable(string pattern){
    
    
	int m = pattern.size();
	// initial
	memset(nextTable, 0, sizeof(nextTable));
	int j = 0;
	nextTable[j] = -1;
	int i = nextTable[j];
	while (j<m){
    
    
		if(i==-1 || pattern[i]==pattern[j]){
    
    
			++i;
			++j;
			nextTable[j] = i;
		}
		else{
    
    
			i = nextTable[i];
		}
	}
	return ;
}

int KMP(string pattern, string text){
    
    
	// the number of pattern appears
	int number = 0;
	int m = pattern.size();
	int n = text.size();
	int j = 0; // match with pattern
	int i = 0; // match with text
	while (i < n){
    
    
		if (j==-1 || text[i]==pattern[j]){
    
     	// no error just now
			++i;
			++j;			
		}
		else{
    
    								// error in match
			j = nextTable[j]; 
		}
		if (j == m){
    
    						// successfully matched
			++number;
			j = nextTable[j];
		}
	}
	return number;
}


int main(){
    
    
	int casenumber;
	cin >> casenumber;
	while (casenumber--){
    
    
		string pattern;
		string text;
		cin >> pattern >> text;
		// get the next table
		GetNextTable(pattern);
		// KMP algorithm
		cout << KMP(pattern, text);
	}
	return 0;
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_53327618/article/details/124517439