C++で一方の文字列の部分文字列がもう一方の文字列にいくつ含まれるかを調べる方法
この記事では、2つの文字列が与えられたとき、1つ目の文字列の部分文字列のうち、2つ目の文字列内に存在するものがいくつあるかを求める方法を解説します。なお、同じ部分文字列が複数回出現する場合は、その回数もカウント対象となります。
具体例
入力 : string1 = "fogl"
string2 = "google"
出力 : 6
説明 : string2 内に存在する string1 の部分文字列は
[ "o", "g", "l", "og", "gl", "ogl" ] の6個です。
入力 : string1 = "ajva"
string2 = "java"
出力 : 5
説明 : string2 内に存在する string1 の部分文字列は
[ "a", "j", "v", "a", "va" ] の5個です。解決へのアプローチ
例を見ると分かるように、まず1つ目の文字列から取り得るすべての部分文字列を生成し、その各部分文字列が2つ目の文字列内に存在するかどうかを順番にチェックしていきます。存在していればカウンターを1つ増やし、すべての部分文字列の確認が終わった時点で、カウンターに格納された値が答えとなります。
この方法の計算量は O(n² × m) です(n は string1 の長さ、m は string2 の長さ)。部分文字列の生成に O(n²)、それぞれの検索に find 関数による O(m) を要するためです。より高速化が必要な場合は、接尾辞配列やハッシュセットを活用する手法もありますが、まずはシンプルな実装を理解しましょう。
C++での実装コード
以下が、上記のアプローチを実装したC++のコードです。
サンプルコード
#include<iostream>
#include<string>
using namespace std;
int main() {
string str1 = "ajva";
string str2 = "java";
int count = 0; // 結果を格納するカウンター
int n = str1.length();
for (int i = 0; i < n; i++) {
// str1 のすべての部分文字列を格納するための変数
string str3;
for (int j = i; j < n; j++) {
str3 += str1[j];
// 部分文字列がもう一方の文字列に存在するかどうかを判定
if (str2.find(str3) != string::npos)
count++;
}
}
cout << "Number of substrings of one string present in other : " << count;
return 0;
}実行結果
Number of substrings of one string present in other : 5
コードの解説
まず、コード冒頭で2つの文字列に値を設定し、カウンターを0で初期化しています。次に、外側のループと内側のループを組み合わせて文字列全体を走査し、str1 から取り得るすべての部分文字列を str3 に格納していきます。そして、生成した各部分文字列が str2 内に存在するかどうかを find 関数で判定し、存在すればカウンターを1ずつ増加させます。最後に、カウンター変数に保存された値を出力として表示します。
ポイントは、str2.find(str3) が該当する部分文字列を見つけられなかった場合に string::npos を返すという仕様です。この戻り値と比較することで、部分文字列の有無を正確に判定できます。
まとめ
この記事では、ある文字列の部分文字列が別の文字列内にいくつ存在するかを求めるシンプルな解法を紹介しました。紹介したロジックは、C言語、Java、Pythonなど、他のプログラミング言語でも同様に実装することが可能です。本記事が皆さんの学習の一助となれば幸いです。
-
C++で文字列の部分文字列の総数を求める方法を解説
この記事では、与えられた文字列から作成できる空でない部分文字列の個数を求める方法について解説します。入力 : string = "moon" 出力 : 10 説明 : 部分文字列は m、o、o、n、mo、oo、on、moo、oon、moon の 10 個です。 入力 : string = "yellow" 出力 : 21解法のアプローチ文字列の長さを n とします。上の例からも分かるように、考えられるすべての部分文字列の個数を求めるには、長さ n、(n-1)、(n-2)、(n-3)、……2、1 の部分文字列の個数を順に加算していく必要があります。部分文
-
C++で列車の停車駅の組み合わせ数を求める方法
地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない