【问题标题】:how to get all combination of an arraylist?如何获得arraylist的所有组合?
【发布时间】:2010-11-13 21:51:32
【问题描述】:

我有一个字符串数组列表“abcde” 我想要一种方法来返回另一个数组列表,其中包含 C# 中给定数组列表(例如:ab、ac、ad ...)的所有可能组合

谁知道一个简单的方法?

注意:长度为2的所有可能组合,如果长度可变(可以更改)会更好

【问题讨论】:

  • 你的意思是length = 2的所有组合吗?
  • 长度为 2 的所有可能组合
  • 除非您的目标是 .NET 1.1,否则您应该使用 List。 ArrayList 已弃用。
  • 在 windows 窗体应用程序上工作
  • @Tergiver:不,ArrayList 类未被弃用。它实际上已经过时了。

标签: c# arraylist combinations


【解决方案1】:

与您的评论相关,需要长度为 2 的组合:

string s = "abcde";
var combinations = from c in s
                   from d in s.Remove(s.IndexOf(c), 1)
                   select new string(new[] { c, d });
foreach (var combination in combinations) {
    Console.WriteLine(combination);
}

回复您的任何长度的编辑:

static IEnumerable<string> GetCombinations(string s, int length) {
    Guard.Against<ArgumentNullException>(s == null);
    if (length > s.Length || length == 0) {
        return new[] { String.Empty };
    if (length == 1) {
        return s.Select(c => new string(new[] { c }));
    }
    return from c in s
           from combination in GetCombinations(
               s.Remove(s.IndexOf(c), 1),
               length - 1
           )
           select c + combination;
}

用法:

string s = "abcde";
var combinations = GetCombinations(s, 3);
Console.WriteLine(String.Join(", ", combinations));

输出:

abc, abd, abe, acb, acd, ace, adb, adc, ade, aeb, aec, aed, bac, bad, bae, bca,
bcd, bce, bda, bdc, bde, bea, bec, bed, cab, cad, cae, cba, cbd, cbe, cda, cdb,
cde, cea, ceb, ced, dab, dac, dae, dba, dbc, dbe, dca, dcb, dce, dea, deb, dec,
eab, eac, ead, eba, ebc, ebd, eca, ecb, ecd, eda, edb, edc

【讨论】:

  • 你也应该这样做 var retComb = GetCombinations(s,2).Distinct().Where(p=>p[0] >= p[p.Length]);删除多余的项目和项目的反向,例如 aabd 测试你的方法
【解决方案2】:

这是我的通用函数,它可以返回 T 类型的所有组合:

static IEnumerable<IEnumerable<T>> GetCombinations<T>(IEnumerable<T> list, int length)
{
    if (length == 1) return list.Select(t => new T[] { t });

    return GetCombinations(list, length - 1)
        .SelectMany(t => list, (t1, t2) => t1.Concat(new T[] { t2 }));
}

用法:

Console.WriteLine(
    string.Join(", ",
        GetCombinations("abcde".ToCharArray(), 2).Select(list => string.Join("", list))
    )
);

输出:

aa, ab, ac, ad, ae, ba, bb, bc, bd, be, ca, cb, cc, cd, ce, da, db, dc, dd, de, ea, eb, ec, ed, ee

更新 请参阅我的回答here 了解其他情况,例如排列和k组合等。

【讨论】:

【解决方案3】:

仅使用数组和递归组合数组中的数字:

    static int n = 4;
    int[] baseArr = { 1, 2, 3, 4 };
    int[] LockNums;

    static void Main(string[] args)
    {
        int len = baseArr.Length;
        LockNums = new int[n];

        for (int i = 0; i < n; i++)
        {
            int num = baseArr[i];
            DoCombinations(num, baseArr, len);
            //for more than 4 numbers the print screen is too long if we need to check the result next line will help
            //Console.ReadLine(); 

        }
    }

    private void DoCombinations(int lockNum, int[] arr, int arrLen )        
    {
        int n1 = arr.Length;
        // next line shows the difference in length between the previous and its previous array
        int point = arrLen - n1; 
        LockNums[n - arr.Length] = lockNum;

        int[] tempArr = new int[arr.Length - 1];
        FillTempArr(lockNum, arr, tempArr);

        //next condition will print the last number from the current combination
        if (arr.Length == 1)
        {
            Console.Write(" {0}", lockNum);
            Console.WriteLine();
        }

        for (int i = 0; i < tempArr.Length; i++)
        {
            if ((point == 1) && (i != 0))
            {
                //without this code the program will fail to print the leading number of the next combination
                //and 'point' is the exact moment when this code has to be executed
                PrintFirstNums(baseArr.Length - n1);
            }
            Console.Write(" {0}", lockNum);
            int num1 = tempArr[i];
            DoCombinations(num1, tempArr, n1);
        }
    }

    private void PrintFirstNums(int missNums)
    {
        for (int i = 0; i < missNums; i++)
        {
            Console.Write(" {0}", LockNums[i]);
        }
    }

    private void FillTempArr(int lockN, int[] arr, int[] tempArr)
    {
        int idx = 0;
        foreach (int number in arr)
        {
            if (number != lockN)
            {
                tempArr[idx++] = number;
            }
        }
    }

    private void PrintResult(int[] arr)
    {
        foreach (int num in arr)
        {
            Console.Write(" {0}", num);
        }
    }

【讨论】:

  • 您好,这是我的数字组合解决方案。该解决方案仅使用数组。我写这篇文章是因为我在任何地方都没有遇到过使用数组的解决方案。代码是为了快速演示而设置的,否则它应该适用于任何数组长度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 2017-05-04
  • 2021-01-19
  • 1970-01-01
相关资源
最近更新 更多