zoukankan      html  css  js  c++  java
  • 全是套路——全排列

    输入一个数比如:5.产生序列:1 2 3 4 5.

    然后输出它的全排列,有5!个组合。

    具体产生方法:

    【例】 如何得到346987521的下一个
        1,从尾部往前找第一个P(i-1) < P(i)的位置
                3 4 6 <- 9 <- 8 <- 7 <- 5 <- 2 <- 1
            最终找到6是第一个变小的数字,记录下6的位置i-1
        2,从i位置往后找到最后一个大于6的数
                3 4 6 -> 9 -> 8 -> 7 5 2 1
            最终找到7的位置,记录位置为m
        3,交换位置i-1和m的值
                3 4 7 9 8 6 5 2 1
        4,倒序i位置后的所有数据
                3 4 7 1 2 5 6 8 9
        则347125689为346987521的下一个排列

    这4步很形象。我的程序也是按照这4步来的。

    #include <stdlib.h>
    #include <string>
    #include <string.h>
    #include <iostream>
    #include <vector>
    #include <algorithm> 
    #include <forward_list>
    #include <list>
    #include <deque>
    #include <numeric>
    
    using namespace std;
    
    int main(int argc, char*argv[])
    {
        int  n;
        while (cin>>n)
        {
            int *a = (int*)malloc(sizeof(int)*n);
            for (int i = 1; i < n + 1; i++)
            {
                a[i-1] = i;
            }
            //获得数组
            int nn = 1;
            for (int i = n; i>0; i--)
            {
                nn *= i;
            }
            nn--;//产生阶乘,但是要--,因为没有顺序的那个数组
            while (nn--)
            {
                int index = 0;
                for (int j = n - 1; j>0; j--)
                {
                    index = j - 1;
                    if (a[j - 1] < a[j])
                    {
                        index = j - 1;
                        break;
                    }
                }//找到第一个降序的下标
                int min = a[index];
                int index_swap = index;
                for (int j = index; j < n; j++)
                {
                    if (a[j]>min)
                    {
                        index_swap = j;
                    }
                }//在那个i-1下标后面找到最后一个比降序第一个元素大的元素
                int tmp = a[index_swap];
                a[index_swap] = a[index];
                a[index] = tmp;
            //交换两个元素
    for (int i = index + 1; i < n - 1; i++) { for (int j = index + 1; j < n - 1 - i + index + 1; j++)//冒泡是每个次方最后一个,加入i=index+1,则第一次j的最后值肯定是n-1,所以为n-1-i+index+1 { if (a[j]>a[j + 1]) { int tmp = a[j]; a[j] = a[j + 1]; a[j + 1] = tmp; } } }
            //用冒泡排列i-1(index)后面的所有元素,注意第二个循环的变量
    int i; for (i = 0; i < n; i++) { cout << a[i]; } cout << endl; } free(a); a = NULL; } return 0; }
  • 相关阅读:
    Nand flash uboot 命令详解【转】
    uboot命令分析+实现【转】
    UBoot常用命令手册
    第一个Linux驱动-流水灯【转】
    lcd ram/半反穿技术解析【转】
    使用 .gitignore来忽略某些文件【转】
    git常见操作--忽略文件以及常用命令【转】
    Git忽略文件方法【转】
    Git查看、删除、重命名远程分支和tag【转】
    SPA与DPA 攻击【转】
  • 原文地址:https://www.cnblogs.com/wyc199288/p/5626924.html
Copyright © 2011-2022 走看看