総当たりアルゴリズムとはどのような方法がありますか?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
寅一

総当たりアルゴリズムとはどのような方法がありますか?

#1

投稿記事 by 寅一 » 10年前

英単語だけを記述してある単語帳ファイル(1単語1行で4055行くらい)があるのですが、
その中の単語1語~5語までを総当たりで表示したいのですが、どのようなアルゴリズムがありますか?


[1語]
egg
bag
rose
chair
bat
fish

[2語]
egg egg
egg bag
egg rose
egg chair
egg bat
egg fish
bag egg
bag rose



fish fish

[3語]
egg egg egg



fish fish fish

このように表示したいです。
よろしくお願いします。

たいちう
記事: 418
登録日時: 14年前

Re: 総当たりアルゴリズムとはどのような方法がありますか?

#2

投稿記事 by たいちう » 10年前

アルゴリズムと構えるほどのものは必要なく、例えば、ファイルを読み込んで配列に保持し、1重のforループから5重のforループを使って順に表示すれば作れます。これが完成してから改良の方法を考えればよいでしょう。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 総当たりアルゴリズムとはどのような方法がありますか?

#3

投稿記事 by みけCAT » 10年前

再帰を用いると簡単です。

コード:

#include <stdio.h>

void display_words(const char *words[], int words_num, int log[], int log_num, int display_num) {
	int i;
	if (display_num <= 0) {
		/* 例でなぜかbag bagが無いので、それに合わせる(厳密な法則は不明なので、とりあえずこのケースのみに対応) */
		if (log_num == 2 && log[0] == 1 && log[1] == 1) return;
		for (i = 0; i < log_num; i++) {
			printf("%s%c", words[log[i]], i + 1 < log_num ? ' ' : '\n');
		}
	} else {
		for (i = 0; i < words_num; i++) {
			log[log_num] = i;
			display_words(words, words_num, log, log_num + 1, display_num -1);
		}
	}
}

int main(void) {
	const char *words[6] = {"egg", "bag", "rose", "chair", "bat", "fish"};
	int log[10];
	int i;
	for(i = 1; i <= 5; i++) {
		printf("[%d語]\n", i);
		display_words(words, 6, log, 0, i);
		if (i < 5) putchar('\n');
	}
	return 0;
}
ただし、
寅一 さんが書きました:英単語だけを記述してある単語帳ファイル(1単語1行で4055行くらい)があるのですが、
その中の単語1語~5語までを総当たりで表示したいのですが、どのようなアルゴリズムがありますか?
そんなことをすると、出力はおよそ1,096,633,243,279,848,455行になります。(こちらの解釈の間違いかもしれませんが)
すなわち、約1.097エクサ行(約1,096,633テラ行)です。
※bag bagの他にどんな行を抜かすかの法則によっても変わってくるかもしれません

総当りのアルゴリズムは単純ですが、表示のアルゴリズムを考えないといけないですね。
ちなみに、この値は以下のHaskellのコードで求めました。

コード:

main :: IO ()
main = putStrLn $ show $ sum $ map (4055^) [1..5]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 総当たりアルゴリズムとはどのような方法がありますか?

#4

投稿記事 by みけCAT » 10年前

さすがに約1エクサ行も表示したいとは考えにくいので、より厳密に例に合わせたプログラムを作ってみました。
これなら単語を4055個にしても現実的な出力量になるでしょう。

コード:

#include <stdio.h>

void display_words(const char *words[], int words_num, int display_num) {
	int i;
	if (display_num == 1) {
		for (i = 0; i < words_num; i++) puts(words[i]);
	} else if (display_num == 2) {
		for (i = 0; i < words_num; i++) printf("%s %s\n", words[0], words[i]);
		if (words_num > 1) {
			printf("%s %s\n", words[1], words[0]);
			if (words_num > 2) printf("%s %s\n", words[1], words[2]);
		}
		for (i = 0; i < 3; i++) puts("・");
		printf("%s %s\n", words[words_num - 1], words[words_num - 1]);
	} else if (display_num > 0) {
		for (i = 0; i < display_num; i++) printf("%s%c", words[0], i + 1 < display_num ? ' ' : '\n');
		for (i = 0; i < 3; i++) puts("・");
		for (i = 0; i < display_num; i++) printf("%s%c", words[words_num - 1], i + 1 < display_num ? ' ' : '\n');
	}
}

int main(void) {
	const char *words[6] = {"egg", "bag", "rose", "chair", "bat", "fish"};
	int i;
	for(i = 1; i <= 5; i++) {
		printf("[%d語]\n", i);
		display_words(words, 6, i);
		if (i < 5) putchar('\n');
	}
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: 総当たりアルゴリズムとはどのような方法がありますか?

#5

投稿記事 by かずま » 10年前

みけCAT さんが書きました:ちなみに、この値は以下のHaskellのコードで求めました。

コード:

main :: IO ()
main = putStrLn $ show $ sum $ map (4055^) [1..5]
python なら 1行で書けます。

コード:

print sum([4055**i for i in range(1,6)])
code= python にすると、括弧が消えるので code=text にしました。
寅一 さんが書きました:英単語だけを記述してある単語帳ファイル(1単語1行で4055行くらい)があるのですが、
その中の単語1語~5語までを総当たりで表示したいのですが、どのようなアルゴリズムがありますか?
正気ですか?
1秒間に 100万個表示できたとして、34774年以上かかりますよ。

閉鎖

“C言語何でも質問掲示板” へ戻る