こんにちは
組み合わせと順列についてです。
順序関係のある要素で構成される集合から一定の数をとり、順列を辞書順で生成する方法がわかりません。
うまく説明できないので、例を示します。
たとえば26文字のアルファベットから4文字を選んで辞書順に生成するプログラムはどのようにやればいいのでしょうか?
このアルファベットの例だと
abcd
abce
abcf
・・・
abcz
abdc
abde
・・・
zyxw
のようになると思います。
要素と長さが決まっている場合で順列を生成する部分は大丈夫です。(C++ STLのnext_permutationにあたる部分)
一応自分なりに考えたやり方は26進数4桁のように考えて、それを1ずつ増やし、全体で2回以上使われていないかを調べる と思ったんですが、あまりスマートじゃないし要素がとびとびのアルファベットのときなどに応用が利かないと思いました。
指摘していただければ補足しますので、よろしくお願いします。
No.4ベストアンサー
- 回答日時:
これでどうだ。
#include <iostream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
// nPr : 13枚のカードから5枚選んで並べる
int main() {
const int N = 13;
const int R = 5;
string rank = "23456789TJQKA";
// select = { -1, -1, ... -1, 0, 1, 2, 3, 4 }
array<int,N> select;
fill(select.begin(), select.end(), -1);
iota(select.end()-R, select.end(), 0);
int perm = 0;
do {
++perm;
string result(R,' ');
for ( int i = 0; i < N; ++i ) {
if ( select[i] >= 0 ) result[select[i]] = rank[i];
}
cout << result << endl;
} while ( next_permutation(select.begin(), select.end()) );
cout << perm << endl;
}
回答ありがとうございます。
こんなやり方もあるんですね。
さっきのでも工夫すればできたと思いますけどこれだと一部かえるだけで使いまわせますね。
とても参考になりました!
本当にありがとうございました。
No.2
- 回答日時:
#1の方法だと左側のアルファベットより若い文字は出力されないのでは?
つまり質問者の例にあるような
"abdc"
や
"zyxw"
といった文字列は出力されないはず。
とりあえずあまりスマートなコードではないけどどうぞ。
#include <stdio.h>
#define ALPHABET_NUM 2
static char buffer[ ALPHABET_NUM + 1 ];
void permutate( unsigned int alpha, int depth )
{
if( ALPHABET_NUM <= depth )
{
buffer[ depth ] = '\0';
printf( "%s\n", buffer );
return;
}
unsigned int mask = 1;
for( int bit = 0; bit < 26; bit++ )
{
if( alpha & mask )
{
buffer[ depth ] = 'a' + bit;
permutate( alpha ^ mask, depth + 1 );
}
mask = mask << 1;
}
}
int main()
{
unsigned int alpha = 0x3FFFFFF;
permutate( alpha, 0 );
return 0;
}
なるほど!
完璧ですね!
確かにこういう全探索かけば辞書順になりますね。
排他的論理輪でビット落としたりしてるのも参考になります。
本当にありがとうございました。
No.1
- 回答日時:
next_permutationで26個から4個えらびだしてみた。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string alpha = "abcdefghijklmnopqrstuvwxyz";
string digit = "00000000000000000000001111";
do {
string result;
for ( string::size_type i = 0; i < digit.size(); ++i ) {
if ( digit[i] == '1' ) result += alpha[i];
}
cout << result << endl;
} while ( next_permutation(digit.begin(), digit.end()) );
}
あとは result をnext_permutationで並び替えればいんじゃないかと。
回答ありがとうございます。
これだとコードが短い上にわかりやすくていいですね。
next_permutationの使い方がとても勉強になりました。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
switch文のエラーについて
-
includeファイルが開けない
-
ヘッダーファイルがインクルー...
-
LinuxのQtに関する質問です。
-
boost::serializationについて
-
#include "fstream.h"
-
C++ iteator const を使ったプ...
-
enumの値から定義名を文字列化...
-
cygwinとUnixのコンパイルの違い。
-
std::lower_boundについて
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
2の補数を計算するプログラム
-
マイナスからプラスへ転じた時...
-
Aの値からBの値を除するとは??
-
ある商品のロス率を5%見込み、...
-
反転した数値を表示させるやり方
-
O(n log n)について2
-
C言語 関数プロトタイプ宣言の...
-
配列を使って魔方陣
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
switch文のエラーについて
-
構文エラーが出ているのですが...
-
VC++で文字列から任意の文字を...
-
#defineの使い方について
-
空ENTERの判別
-
C++でShowCursorを使いたい。
-
enumの値から定義名を文字列化...
-
C++での <iostream.h>と<iostre...
-
VS2019でofstreamが未定義になる
-
std::wstringのメモリリークに...
-
wstringの主力
-
JPEGやPNGが読めるLoadImage関数
-
なぜ、C++の標準ヘッダをインク...
-
#include "fstream.h"
-
C言語のエラーを修正したい
-
C言語のポインターで詰まっている
-
#define中の#のエスケープ
-
リモートデスクトップの接続元I...
-
CStringとString
-
【C++】複素数で配列を使いたい
おすすめ情報