[アルゴリズム] リストの順列
私は順列のプログラムのリストを作成します {1, 2, …, N} 注文辞書.
例えば、= Nと 3, 私は十分にリストしました 6 変換:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
したがって、最初の順列は<1であります, 2, …, N>. 最終転置<nの, -1, …, 1>.
現行順列よりも大きくなる順列を生成します, ご注文時に十分な順列よりも大きな電流順列は、それらの間で意味の他の順列を持つことはできません. 現行順列をされていると仮定すると= <3, 2, 6, 5, 4, 1>, レビュー 4 最後の要素, 私は、彼らが下降している参照してください。, それは我々が順列を持っている場合でも、ということを意味します 4 どのようにこの要素, これは、もう少し順列現行順列ました. だから我々は、アカウントAに取らなければなりません[2] = 2, 別の値に置き換え. 私は値に置き換えます?, することはできません 1 とても小さいの順列であるかどうので、, することはできません 3 持つため[1] = 3 すでに (次の要素は、要素を選択し、以前の値に選択されていません). 残りの値 4, 5, 6. 私たちが選択したように、十分に大きな電流順列を必要に応じて[2] = 4. そして、値 (ザ·[3], ザ·[4], ザ·[5], ザ·[6]) 実際にはかかります {2, 6, 5, 1}. また、十分な大きさのためには、私たちは最小の表現を見つけます 4 に割り当てられたこの数[3], ザ·[4], ザ·[5], ザ·[6] すなわち、<1, 2, 5, 6>. だから、新しい順列がある<3, 4, 1, 2, 5, 6>.
私はこの例をその上にコメントを持っています: 現行順列の終わりが下降され、, の[5] = 4 最後の段落内の最小数は、より大きな満足する条件を降順[2] = 2. スワップ場合[5] 以下のために[2] 私は次のようになります[2] = 4 そして最後は、降順にソートすることはまだあります. それは最終的には最小値に対して実行したかったとき、私たちは最後の段落を逆転します. 現在の順列の場合は<2であります, 1, 3, 4>次の順列は<2であります, 1, 4, 3>. 我々はまた、順列を考慮することができる<2, 1, 3, 4>テーパー形状の端, この最後の部分は構成されてい 1 要素 (4) だから、次のように次の順列順列からの学生が今構築することができますエンジニアリング:
- 最長のテーパ状の端部を決定, 要素のインデックスiを探して[で] 後半に始まりました. これは最初の要素の行まで下から見て意味します 2 (あなたは最終転置である最初の要素を見れば、その必要はありませんので、), 私が最初に満たすインデックスを検出しました[iは、1] < ザ·[で].
- あなたは上記のインデックス私を見つけた場合
– エンド降順で, A要素を見つけます[へ] 条件Aを満足する最も小さいです[へ] > ザ·[iは、1]. 末端の減少に起因します, これは、最初のインデックスのkを満たすaを満たすために、範囲の上端から見ることによって行われます[へ] > ザ·[iは、1] (バイナリ検索を使用することができます).
– 島の価値があるのA[へ] と[iは、1]
– 覆さエンド降順 (から[で] へ[へ]) 昇順になります. - あなたが見つからない場合は、全範囲すなわち降順程度でした, これは最終的な構成であります.
C ++コードが示して.
/* code by nguyenvanquan7826 */ #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> // thu vien chua ham swap (hoan vi 2 so) using namespace std; int main(int argc, char **argv) { int n, *a; scanf("%d", &n); a = new int[n]; for (int i=0; i<n; i++) // khoi tao va in ra cau hinh ban dau { a[i] = i+1; printf("%d ", a[i]); } printf("n"); int i = n-1; // i la vi tri ma doan cuoi giam dan while (i>0) // trong khi doan cuoi khong phai bat dau tu vi tri dau tien { i = n-1; while (a[i] < a[i-1]) // tim vi tri dau tien ma doan cuoi giam dan { i--; } if (i>0) // Neu tim duoc i { int k; // tim so a[k] nho nhat trong doan giam dan ma a[k] > a[i-1] for (k = n-1; k >= i; k--) { if (a[k] > a[i-1]) { break; } } swap(a[k], a[i-1]); // hoan vi a[k] va a[i-1] // dao nguoc doan cuoi giam dan thanh tang dan for (int k = i; k < i + (n - i) / 2; k++) { swap(a[k], a[n - 1 - k + i]); } for (int k = 0; k < n; k++) // in hoan vi ra { printf("%d ", a[k]); } printf("n"); } } return 0; }
記事より引用 教科書のデータ構造と氏はル・ミン・ホアンのアルゴリズム. あなたが書いたようにあなたがシラバスで見ることができるパスカルコード.
ようこそ、, あなたの記事は非常にまたはあります, 私はアルゴリズムを書いていないについてあなたを少しお聞きしたいです, n個の要素の集合としてのすべてのサブセットを見つけること多くの順列の問題が関与することはできません {1,2,3,4,…N} このアルゴリズムは、使用可能従うことができますこの問題のための再帰アルゴリズムを使用している場合.ANDされていない方法です、デバイスは他の大部分を学ぶために彼女のような二重のあるバイナリカウントを使用しています
ブログの投稿にご関心をお寄せいただきありがとうございます.
この記事のために私はブログに書く時間がありませんでしたが、あなたはどのように見ることができます ” セットのk個の要素のサブセットを示しています {1, 2, …, N} 充填から順に” ページ番号で、黄氏の本のように、 20 (上記の文書リンク). すなわち 1 良い方法. 私はすぐに書き込むしようとします.
それは私をk個の読み違えde.minh自体はそうしてきたことを忘れ,コードビューを検索します,その長いアップデート以降の場合 :D
ここに私のコードCであります,あなたは星を見るために参照することができます:
ようこそ、! あなたの記事をお寄せいただきありがとうございます. あなたはサブルーチンKOを使用せずにパスカルパーミュテーション問題のコードを書くことができます?
パスカルコードで カリキュラム レオンの見事なショーはあなたを持っています. 彼のコードでのみ 1 サブルーチンは、スワップされています – 変換 2 数, あなたは、サブルーチンを使用せずに直接置き換えることができます.
敬礼, あなた自身をない助けることができる最大tr2inh多くのための彼のこれを行うための本が、私はすべての科目で非常に良いではありませんよ, tìm tất cả các tập hợp của chuỗi số nhập vào ví dụ nhập 012 cho ra 012,021,102,120,201,210 bạn giúp mình ghi chi tiết nhé cám ơn bạn
Cái này hoàn toàn giống mà bạn. Chỉ là thay các số nhập vào bằng các ký tự trong chuỗi của bạn thôi. 😀
mình dùng dev=c++ nhé bạn
cho minh xin mau ben pascal duoc khong
Bạn xem trong giáo trình nhé
cho e hỏi độ phức tạp của thuật toán này là gì có phải là O(n.n!) k ạ
- 最後降順を裏返し (から[で] へ[へ]) 昇順になります.
その兄弟のこの行は、それが奇妙見つけます, 文字kはn個の単語を置き換えることになっては、本当です
[はいああ. 彼逆さま, 財務A[で] へ[N].