排列/变更

时间:2011-12-10 01:08:18

标签: c# permutation

我正在尝试提出一种能够生成排列和变体的C#方法。我认为最好在一个例子中解释。我是实现这一目标的最佳方式。这就是我脑子里想的。

我正在寻找有关如何处理此问题的建议,也许是伪代码?

ABC成为

步骤1)排列不重复:

ABC
ACB
BAC
BCA
CAB
CBA

步骤2)与|

的变化
ABC
  A|BC
  AB|C

ACB
  A|CB
  AC|B

BAC
  B|AC
  BA|C

BCA
  B|CA
  BC|A

CAB
  C|AB
  CA|B

CBA
  C|BA
  CB|A

所以你最终得到了一套

  A|BC
  AB|C
  A|CB
  AC|B
  B|AC
  BA|C
  B|CA
  BC|A
  C|AB
  CA|B
  C|BA
  CB|A

更新:我写的只是一个快速实施,我知道它很可怕,欢迎任何评论。

        var perms = Permuter.Permute(new Char[] {'a', 'b', 'c'}).ToList();
        DisplayResult(perms);

        foreach (var permutation in perms.ToList())
        {
            var p = permutation.ToList();

            int splitPos = 1;
            do
            {
                for (int i = 0; i < splitPos; i++)
                {
                    Console.Write(p[i]);
                }

                Console.Write("|");

                for (int j = splitPos; j < p.Count; j++)
                {
                    Console.Write(p[j]);
                }

                Console.WriteLine("");
                splitPos++;
            } while (splitPos < p.Count);
        }

2 个答案:

答案 0 :(得分:2)

  

寻找教育目的,只是对permtations和集合和事物感兴趣,试图理解如何把这些东西放在一起。

有许多不同的排列方式,其中很多都是有启发性的。这是一个让你思考的草图。

考虑将问题限制为查找从0到31的整数集子集的所有排列。因此,您可以选择作为集合{2,3,5}并生成排列(2,3,5), (2,5,3),(3,2,5),(3,5,2),(5,2,3)和(5,3,2)。怎么做?

定义包含单个32位整数的不可变结构。使结构实现IEnumerable<int>并使其枚举对应于其中设置的所有位的数字。还可以创建一个方法“Remove”,它可以在删除给定位的情况下返回不同的结构。

现在你可以制作这样的递归算法:

  • 该组是否为空?然后是一个排列,空序列。

  • 套装不是空的吗?然后对于集合中的每个项目:创建原始集合而不是该项目的集合,递归地从较小集合中生成所有序列,并将项目附加到每个序列中。

也就是说,再次假设该集合是{2,3,5}。你是做什么?对于每个项目2,3,5:

Remove the item 2. That leaves 3 and 5. Permute 3, 5. How?
    Remove item 3. That leaves 5. Permute that.
        Remove item 5. That leaves nothing. Permute that.
            The result is the empty sequence.
        Append 5 to the empty sequence. That's (5).
    Append 3. That's (5, 3).
    Remove 5. That leaves 3. Permute that.
        Remove 3. That leaves nothing. Permute that.
            The result is the empty sequence.
        Append 3 to the empty sequence. That's (3).
    Append 5. That's (3, 5).
Append 2 to each of those results. That's (2, 5, 3) and (2, 3, 5).
Remove 3. That leaves 2 and 5. Permute that....

将其转化为代码将会有点棘手,但却很有启发性。

答案 1 :(得分:1)

首先,生成排列。词典排序是最简单的实现;见Wikipedia和Knuth的The Art of Computer Programming。这是Python中的一个实现(source):

def permutations_of( seq ):
    yield seq
    seqlen = len(seq)
    while True:
        j = seqlen - 2
        while j >= 0 and seq[j] >= seq[j+1]:
            j -= 1

        if j < 0: break

        i= seqlen - 1
        while i > j and seq[i] < seq[j]:
            i -= 1

        seq[j],seq[i] = seq[i],seq[j]
        seq[j+1:] = seq[-1:j:-1]
        yield seq

你也可以使用Steinhaus–Johnson–Trotter algorithm,这有点快。

要生成变体,循环播放字符串,并为字符串中的每个可能位置插入|