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

特定の文字列からN文字のシーケンスを生成するC++プログラム

この記事では、指定された元の文字列(ベース文字列)をもとに、同じ文字を重複させずに長さNのシーケンス(文字列)を複数個生成するC++プログラムを紹介します。標準ライブラリの rand() 関数でランダムなインデックスを選択することで、実行のたびに異なる組み合わせのシーケンスを作り出せます。

アルゴリズム

開始
    関数 GenerateSequence():特定のケースに対してN文字のシーケンスを生成する
        rand() を使ってランダムなインデックスを生成する
        最初の文字はそのままシーケンスに格納する
        2文字目以降は、すでに使用済みの文字なら破棄して
        ランダムなインデックスを再生成する
終了

処理の流れ

GenerateSequence() 関数は、元の文字列・生成する文字数 n・元の文字列の長さ l・結果を格納する配列の4つを引数に取ります。まず1文字目をランダムに選んでシーケンスへ格納し、2文字目以降は「すでに選んだ文字と重複していないか」を1文字ずつ照合しながら選択します。重複が見つかれば goto 文でラベル h に戻り、乱数を発生し直します。こうしてユニークな文字だけを順に追加し、最後にヌル文字 '\0' を付加して1つのシーケンスを完成させます。main() 側では、この関数を生成したい個数分だけ繰り返し呼び出しています。

サンプルコード

#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
void GenerateSequence(char string[], int n, int l, char *sequence)
{
    int i, j=0, k, in;
    for(i = 0; i < n; i++) {
        // 最初の文字はそのままシーケンスに格納する
        if(j == 0)
            sequence[j++] = string[rand()%l];
        else {
            h:
            in = rand()%l;
            for(k = 0; k < j; k++) {
                // すでに使われている文字ならやり直し
                if(string[in] == sequence[k])
                    goto h;
            }
            sequence[j++] = string[in];
        }
    }
    sequence[j] = '\0'; // ヌル文字でシーケンスを終了する
}
int main() {
    int n, m, l, i;
    char string[100];
    cout<<"元の文字列を入力してください: ";
    cin>>string;
    cout<<"\nベース文字列から生成する文字列の個数を入力してください: ";
    cin>>n;
    cout<<"\n生成する各文字列の長さを入力してください: ";
    cin>>m;
    l = strlen(string);
    for(i = 0; i < n; i++) {
        char sequence[m];
        GenerateSequence(string, m, l, sequence);
        cout<<"\nシーケンス"<<i+1<<": "<<sequence;
    }
    return 0;
}

実行結果

元の文字列を入力してください: tutorialspoint
ベース文字列から生成する文字列の個数を入力してください: 7
生成する各文字列の長さを入力してください: 6
シーケンス1: tuanol
シーケンス2: itlurp
シーケンス3: tonaiu
シーケンス4: untlri
シーケンス5: liorpt
シーケンス6: liusto
シーケンス7: luisot

補足ポイント

  • 乱数の初期化:rand() だけでは、プログラムを実行するたびに同じ乱数列が再現されます。実行ごとに異なる結果を得たい場合は、main() の先頭で srand(time(NULL)) を呼び出し、<ctime> をインクルードしてください。
  • 可変長配列について:サンプルコードの char sequence[m] は可変長配列(VLA)で、GCC など一部のコンパイラではコンパイルできますが、C++の標準規格には含まれていません。移植性を重視する場合は std::vector<char> や動的確保(new / delete)の利用を検討しましょう。
  • 文字数の制約:このアルゴリズムは元の文字列内の文字を重複させないため、生成する各シーケンスの長さ m は元の文字列の長さ l 以下である必要があります。
  1. 指定した辺の数からランダムな有向非巡回グラフ(DAG)を生成するC++プログラム

    この記事では、指定した辺の数 e に基づいて、ランダムな有向非巡回グラフ(DAG:Directed Acyclic Graph) を生成するC++プログラムを紹介します。有向非巡回グラフとは、方向性のある辺(矢印)で頂点同士を結びながらも、どこを起点にしても元の頂点へ戻ってくる閉路(サイクル)が一切存在しないグラフのことです。本プログラムの時間計算量は O(e×v×e) です。 アルゴリズム 開始   関数 GenerateRandomGraphs() は、引数として辺の数 e を受け取る。   2つの乱数の間に接続(辺)を生成する。動作確認用の小さなケースでは、頂点数を20に制限する。   

  2. C++で実装する二分探索アルゴリズム:配列内の特定の検索シーケンスを見つける方法

    本プログラムでは、二分探索(バイナリサーチ)を用いて、配列の中に指定した検索シーケンス(連続する値の並び)が存在するかどうかを調べる方法を実装します。二分探索の計算量は O(log n) であり、大規模なデータセットに対しても非常に高速に動作する点が大きな特徴です。 処理の手順と擬似コード 全体の流れは以下のとおりです。 開始  BinarySearch() 関数は、引数としてデータ配列 arr、  要素数 n、探索範囲の start(開始)と end(終了)の  インデックス、反復回数カウンタ、および探索対象となる  最初の要素 b[0] を受け取る。  反復カウンタを増やし、探索対象の値を