[算法] 上市排列
我将建立程序将列出的排列 {1, 2, …, ñ} 为了解释.
例如,其中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的, N-1, …, 1>.
置换将诞生必须比当前排列更大, 订货时绰绰有余排列更多更大的意义上当前排列不能在它们之间的不同的排列. 假设当前排列为A = <3, 2, 6, 5, 4, 1>, 评测 4 最后一个元素, 我看到他们是降, 这意味着即使我们有置换 4 怎么这个元素, 我还可以得到多一点的排列当前排列. 因此,我们必须考虑[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) 因此,从目前的排列在下生物排列可以如下建:
- 确定最长的锥形端, 元件A I寻找索引[在] 晚启动. 这意味着从结束位置查找范围高达第二元件 2 (因为如果你看看这是你最后的排列的第一个元素,那么就没有必要), 具有:i满足第一索引[I-1] < 该[在].
- 如果发现上述指标i
– 在锥形端, 找到元素[到] 大多数小到满足条件的[到] > 该[I-1]. 由端部的锥形, 这从第一行的末尾搜索上遇到的第索引k满足完成[到] > 该[I-1] (可以使用二进制搜索).
– 岛值得一[到] 和[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,…ñ} 该算法可以跟着你可以使用是如何在使用递归算法对于这个问题,该设备是双喜欢自己学到的最使用的是二进制计数另一种是不。而
感谢您的博客文章的兴趣.
在这篇文章中,我还没有时间来写的博客,但你可以参考如何 ” 列出一组的第k子集元素 {1, 2, …, ñ} 在从填充顺序” 如在页码的书黄先生 20 (上述文件链接). 就是说 1 伟大的方式. 我会尽量尽快写信.
无私的误读de.minh做那么K内存,找到代码视图,如果还是稍后再更新 :ð
这里是我的代码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个字是真实的
是啊,你. 他的潜力, 融资[在] 到[ñ].