繁体   English   中英

查找条件为给定N的所有排列的算法

[英]Algorithm to find all permutations of a given N with condition

我正在设计一个程序来打印给定N的所有排列,以便每个数字都应大于下一个数字。

例如,如果N = 3:输出应为123,456,789,134,145,178,189等...

初始设计:

  1. 生成所有可能的排列

  2. 将生成的排列传递给检查条件的数字提取函数

  3. 打印结果

这是一个非常幼稚的算法。 但是由于N的动态大小,我不知道实现/初始设计。

由于N将始终小于10,因此我使用了递归

将该函数称为f(3,0,0)

public static void f(int N,int digit,int num)
    {
        if(N > 0 )
        {
            for(int d = digit + 1; d < 11 - N; d++) // earlier d < 10, see comments
            {
                f(N-1,d,num * 10 + d);
            }
        }else {
            System.out.println(num); //add it to a list or whatever
        }
    }

输出:

123
124
...
678
679
689
789

最简单的方法是使用递归。 假设您已经生成了前n位数字,而生成的最后一位数字是i 您还有N - n个数字要生成,并且它们必须以i +1或更高的开头。 由于最后一位数字不能超过9,因此下一位数字不能超过10-( N - n )。 这给出了递归的基本规则。 像这样的东西(在Java中)应该起作用:

void generate(int N) {
    int[] generated = new int[N];
    generate(generated, 0);
}

void generate(int[] generated, int nGenerated) {
    if (nGenerated == generated.length) {
        // print the generated digits
        for (int g : generated) {
            System.out.print(g);
        }
        System.out.println();
        return;
    }
    int max = 10 - (generated.length - nGenerated);
    int min = nGenerated == 0 ? 1 : (generated[nGenerated - 1] + 1);
    for (int i = min; i <= max; ++i) {
        generated[nGenerated] = i;
        generate(generated, nGenerated + 1);
    }
}

只需按照字典顺序生成它们即可:

123
124
125
...
134
135
...
145
...
234
235
...
245
...
345

假设您的数字最多为5。对于更大的边界B ,请继续。 一些简单的代码可以做到这一点:

nextW = w;
for (int i=n-1; i>=0; --i) {
    // THE LARGEST THE iTH DIGIT CAN BE IS B-(n-i-1)
    // OTHERWISE YOU CANNOT KEEP INCREASING AFTERWARDS
    // WITHOUT USING A NUMBER LARGER THAN B
    if w[i]<B-(n-i-1) {
        // INCREMENT THE RIGHTMOST POSITION YOU CAN
        nextW[i] = w[i]+1;
        // MAKE THE SEQUENCE FROM THERE INCREASE BY 1
        for (int j=i+1; j<N; ++j) {
            nextW[j] = w[i]+j-i+1;
        }
        // VOILA
        return nextW;
    }
}
return NULL;

w = [1,2,3,...,N];开头w = [1,2,3,...,N]; (使用for循环很容易制作),打印w ,使用w作为输入调用上面的函数,然后打印并继续。 N = 3B = 5 ,答案将是上面的列表(没有...行)。

如果没有边界B ,那么您就是SOL,因为有无限多个。

通常,您正在计算第N基本对称函数 e_N

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM