Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

与えられた文字列から生成できる全ての文字列(任意の長さ)を列挙する方法

この記事では、与えられた文字列から構成できる任意の長さのすべての文字列を生成する方法を解説します。これは、各文字の組み合わせ(部分列)とその順列をすべて求める問題です。

例えば、入力文字列が「ABC」の場合、次のような文字列が生成されます。

{A, B, C, AB, BA, BC, CB, CA, AC, ABC, ACB, BAC, BCA, CAB, CBA}

それでは、具体的な手順を見ていきましょう。

アルゴリズムの考え方

基本的なアイデアは次の通りです。

  • 長さ n の文字列に対して、ビットフラグを用いて 2n - 1 通りの部分列を作成します(カウンタの j ビット目が立っていれば、j 番目の文字を選択)。
  • それぞれの部分列に対して next_permutation を使って順列をすべて出力します。

擬似コード

Begin
    n := 文字列 str の長さ
    count := 2^n - 1
    for カウンタ = 0 to count, do
        sub_str := 空文字列
        for j = 0 to n-1, do
            if カウンタの j ビット目が立っている場合
                sub_str に str の j 番目の文字を連結
            end if
        done
        repeat:
            sub_str を出力
        until sub_str の次の順列が存在しなくなるまで
    done
End

C++による実装例

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
void printAllString(string str) {
    int n = str.size();
    unsigned int count = pow(2, n);
    for (int counter = 1; counter <count; counter++) { // 2^n - 1 個の文字列を生成
        string subs = "";
        for (int j = 0; j < n; j++) {
            if (counter & (1<<j)) // j ビット目が立っているとき、j 番目の文字を追加
                subs.push_back(str[j]);
        }
        do{
            cout << subs << endl;
        }
        while (next_permutation(subs.begin(), subs.end()));
    }
}

コードのポイント

  • counter & (1 << j):ビット演算により、カウンタの j ビット目がセットされているかを判定し、対応する文字を部分列に追加します。
  • next_permutation():標準ライブラリの関数で、同じ文字集合の並び替え(順列)を辞書順に次々と生成します。

実行結果(入力:ABCD)

A
B
AB
BA
C
AC
CA
BC
CB
ABC
ACB
BAC
BCA
CAB
CBA
D
AD
DA
BD
DB
ABD
ADB
BAD
BDA
DAB
DBA
CD
DC
ACD
ADC
CAD
CDA
DAC
DCA
BCD
BDC
CBD
CDB
DBC
DCB
ABCD
ABDC
ACBD
ACDB
ADBC
ADCB
BACD
BADC
BCAD
BCDA
BDAC
BDCA
CABD
CADB
CBAD
CBDA
CDAB
CDBA
DABC
DACB
DBAC
DBCA
DCAB
DCBA

このように、入力文字列「ABCD」から長さ 1 の文字列から長さ 4 の文字列まで、すべての組み合わせと順列が出力されていることが確認できます。なお、文字数が増えると組み合わせの総数は指数関数的に増加するため、この手法は短い文字列に適しています。

  1. C/C++で電話番号のダイヤルに使える文字列の全組み合わせを出力する方法

    問題の概要 ある番号が与えられたとき、以下の仕様に基づいて、その番号を電話でダイヤルするために使用できる文字列のすべての組み合わせを表示するプログラムを考えます。 2 →「A」「B」「C」のいずれか 3 →「D」「E」「F」のいずれか ……(以下同様) 7 →「P」「Q」「R」「S」のいずれか 8 →「T」「U」「V」のいずれか 9 →「W」「X」「Y」「Z」のいずれか 1 →「1」のみ 0 →「0」のみ 例として、電話番号として「89」が与えられた場合、プログラムは次の12通りの文字列を出力します。 TW TX TY TZ UW UX UY UZ VW VX VY VZ アルゴリズムの

  2. 角度と半径から弧の長さを求める方法|C++での計算例をわかりやすく解説

    この記事では、円の半径と中心角が与えられたときに、弧の長さを求める方法を解説します。プログラミング(C++)を使った具体的な実装例もあわせて紹介するので、数学的な考え方とコードの両方を一度に理解できます。弧の長さとは?円周上の一部分を「弧」と呼びます。円全体の円周の長さは 2πr で表されますが、中心角が360度未満の場合、その角度に対応する部分だけの長さ、つまり弧の長さを求める必要があります。たとえば、下図のように半径 r の円があり、中心角 x(度数法)が与えられているとします。ここで求めたいのは、この角に対応する弧の長さ L です。弧の長さを求める公式中心角が360度のとき、弧の長さは円