在词典顺序中生成排列与排序?

时间:2012-08-09 01:40:07

标签: algorithm sorting permutation lexicographic

我有点困惑。如何在词典顺序中生成排列的问题与排序问题有什么不同?有人可以用一个例子向我解释一下吗?感谢

4 个答案:

答案 0 :(得分:7)

这是两件不同的事情。有N!个排列,但只有一个排序顺序(排序排列是按字典顺序排列的最小排列)。

以下是排序排列的示例:

brown fox quick

以下是按字典顺序排列的排列列表:

brown fox quick
brown quick fox
fox brown quick
fox quick brown
quick brown fox
quick fox brown

Here是C ++中用于按字典顺序生成排列的程序:

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

int main() {
    vector<string> s;
    s.push_back("quick");
    s.push_back("brown");
    s.push_back("fox");
    sort(s.begin(), s.end());
    do {
        for(int i = 0 ; i != s.size() ; i++) {
            cout << s[i] << " ";
        }
        cout << endl;
    } while (next_permutation(s.begin(), s.end()));
    return 0;
}

答案 1 :(得分:0)

Permutations问题未解决

sorting问题。

他们可能涉及的一种方式是,如果您生成不按字典顺序排列的排列,那么您可以按字典顺序排序。然而,这需要具有阶乘空间。生成通常一次吐出一个元素,因此不必将所有元素都存储在内存中。

答案 2 :(得分:0)

有一种相当简单的方法可以按字典顺序生成第n个排列。你在选择排列元素时所做的选择是:选择N中的1,然后选择N-1中的1,然后选择N-2中的1,...然后选择1中的2,最后只剩下一个。这些选择,作为运行“剩下的东西”列表的索引值,可以看作是一个可变基数。

你可以从右到左开发数字,因为d [1] = n%2,d [2] =(n / 2)%3,d [3] =(n / 6)%4,.. .d [k] =(n / k!)%(k + 1)。结果是第一个(N-1)的d [N-1] == 0!排列,d [N-1] == 1表示下一个(N-1)!,依此类推。您可以看到这些索引值将以lex为单位。订购。然后从排序集中选择符号(如果syms [0],syms [1],...按照您想要的顺序,任何随机访问集合都会执行。)

这是我为处理Project Euler问题而编写的一些代码。它只生成索引值,并允许从n中选择k个符号的排列。头文件默认为k到-1,参数检查代码将其转换为n并生成全长排列。这里还有一个符号的变化:“index”是排列的数字(上面的“n”),“n”是设定的大小(上面的“N”)。

vector<int> pe_permutation::getperm(long long index, int n, int k)
{

if (n<0) throw invalid_argument("permutation order (n)");
if (k<0 || k>n) 
{
    if (k==-1) 
        k=n;
    else throw invalid_argument("permutation size (k)");
}
vector<int> sset(n, 0); // generate initial selection set {0..n-1}
for (int i=1; i<n; ++i)
    sset[i] = i;

//  Initialize result to sset index values.  These are "without replacement"
//  index values into a vector that decreases in size as each result value
//  is chosen.  

vector<int> result(k,0);
long long r = index;
for (int m=n-k+1; m<=n; ++m)
{
    result[n-m] = (int)(r % m);
    r = (r / m);
}

// Choose values from selection set:

for (int i=0; i<k; ++i)
{
    int j = result[i];
    result[i] = sset[j];
    sset.erase(sset.begin()+j);
}
return result;

} // getperm(long long, int, int)

答案 3 :(得分:0)

import java.util.*;
public class Un{

    public static void main(String args[]){
        int[]x={1,2,3,4};

        int b=0;int k=3;
        while(b!=(1*2*3*4)){

            int count=0;
            while(count!=6){
                for(int i=2;i>0;i--){
                    int temp=x[i];
                    x[i]=x[3];
                    x[3]=temp;
                    count++;
                    System.out.println(x[0]+""+x[1]+""+x[2]+""+x[3]);
                 }

            } 
            b+=count;
            int temp=x[0];
            x[0]=x[k];
            x[k]=temp;
            k--;
       }            
 }


}