【问题标题】:Permutation....or similar to that排列....或类似的
【发布时间】:2012-11-29 20:06:31
【问题描述】:

我有这个字符数组:private char[] posibilities = { 'a', 'b', 'c' };

我想要它们所有可能的组合,然后我做了三个嵌套:

for (int cont = 0; cont < posibilities.Length; cont++)
{
    for (int i = 0; i < posibilities.Length; i++)
    {
        for (int j = 0; j < posibilities.Length; j++)
        {
            listBox1.Items.Add(posibilities[cont].ToString() + posibilities[i].ToString() + posibilities[j].ToString());
        }
    }
}

我的问题是:如果我想在我的数组中添加更多字符而不向我的嵌套 for 添加更多 fors,我该怎么做?想象一下,如果我在数组上有 20 个字符,我不能为 20 个字符......或者这是唯一的方法?

(顺便说一句,我从 3 个月前就一直在尝试解决这个问题,但仍然无法解决)

【问题讨论】:

  • 结果必须是这样的:aaa aab aac aba abb ... ccb ccc
  • 您可能需要考虑为此使用递归
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 仅供参考,您要求的是所有重复排列,“组合”与“排列”不同
  • 感谢服务!我不知道

标签: c# loops permutation combinations nested


【解决方案1】:

试试这种递归方法:

void RecursiveApproach(char[] possibilities, string cur)
{
    if (cur.Length == c.Length)
    {
        listBox1.Items.Add(cur);
        return;
    }
    for (int i = 0; i < possibilities.Length; i++)
    {
        RecursiveApproach(possibilities, cur + possibilities[i]);
    }
}

// Usage
RecursiveApproach(possibilities, "");

如果无法使其全局可见,可以将listBox1 作为第三个参数传递给该函数。

但要小心数字很大,这个列表会增长得非常快))

【讨论】:

  • 将算法与 UI 交互混合通常不是一个好主意。最好让排列生成器返回(而不是无效的)所有排列的一些集合或序列,然后有单独的 UI 代码调用该方法并执行...不管它。
  • Servy,你是对的,但你需要为工作选择合适的工具。这家伙显然是在询问轻量级解决方案以满足他的需求。他不想要一个通用的模式,比如多重组合的方法。他不知道如何使用递归,我为他展示了它,现在他可以根据自己的需要(UI 或其他东西)采用它
  • 其实我正在学习c#,关于递归,我唯一知道的就是做阶乘,所以再次感谢Servy,我正在一点一点地积累经验。
  • @SergeyS 坏习惯比不学习更容易学习。虽然它使这个方法的实现更容易,但它使 使用 这个方法 much 更难,因为你需要做一个复制/粘贴,每次你想使用时都要改变东西它。那是糟糕的设计。
【解决方案2】:
public static IEnumerable<IEnumerable<T>> PermutationsWithRepitition<T>(IList<T> source)
{
    return PermutationsWithRepitition(source, source.Count);
}

//private recursive method that does all of the work.
private static IEnumerable<IEnumerable<T>> PermutationsWithRepitition<T>(IList<T> source, int resultSize)
{
    if (resultSize == 1)
        return source.Select(item => new[] { item });
    else
    {
        return PermutationsWithRepitition(source, resultSize - 1)
            .SelectMany(permutation => source.Select(item => new[]{item}.Concat(permutation)));
    }
}

示例用法:

char[] posibilities = new[] { 'a', 'b', 'c' };

foreach (var permutation in PermutationsWithRepitition(posibilities))
{
    Console.WriteLine(new string(permutation.ToArray()));
}

【讨论】:

  • 这里看起来有点矫枉过正。 Guy刚开始学习C#,你想让他跑掉??))
  • @SergeyS 不,我只是想从一开始就鼓励好的做法,而不是鼓励那些会导致严重问题的不良做法。
  • 想象一下,你刚刚用 C# 创建了你的第一个桌面应用程序,你对 Lync 和许多其他东西一无所知。你问了一些琐碎的算法问题(!),你得到了和你一样的答案。
  • @Servy 我已经复制了你的代码,我正在努力理解它,我不知道你在那里做了什么,但相信我,我会试着理解它。非常感谢您的支持!
  • @SergeyS 你的前提有缺陷;这不是一个微不足道的算法问题。操作本身需要更多的知识,然后一个全新的程序员必须正确实施。如果我在教别人如何编程,我不会马上给他们这样的任务。
猜你喜欢
  • 2011-04-28
  • 2015-02-07
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
相关资源
最近更新 更多