C# 从任意数量的列中计算单词的组合

C# calculate combinations of words from an arbitrary number of columns

有很多针对单个数组或数组向量的组合解决方案,您需要各种可能的排列,但我需要稍微不同的解决方案。我试着把碎片拼在一起,但再也见不到树木了。

我需要一个解决方案,它将采用一个 csv 文件,该文件包含最多 50 列和每列任意数量的单词行。每列的行数可以不同。

我需要做的是获取此输入并依次遍历每一列,选择一个词来创建每个可能的行组合,跳过任何 row/column 为空的行。嵌套循环会对预设数量的列执行此操作,但随着列的更改,这是一个问题。编程相当新。希望我缺少一个相当简单的逻辑概念。

例如:

输入:
熊、爪、甜甜圈
鸡肉,沙拉,
金枪鱼,沙拉

输出:
熊、爪、甜甜圈
熊,沙拉,甜甜圈
熊,沙拉
鸡、爪、甜甜圈
鸡肉、沙拉、甜甜圈
鸡爪
鸡肉、沙拉
鸡肉、沙拉、甜甜圈
...
金枪鱼、爪、沙拉
金枪鱼沙拉 等等

我不确定我是否正确回答了您的问题。您似乎缺少一些解决方案。

public static IEnumerable<string[]> GetAllCombinations(string[,] input, Stack<string> current = null, int currentCol = 0)
{
    if (current == null) current = new Stack<string>();

    var rows = input.GetLength(0);
    var cols = input.GetLength(1);

    for (var row = 0; row < rows; row++)
    {
        if (input[row, currentCol] == null) continue;

        current.Push(input[row, currentCol]);
        if (currentCol == cols - 1)
        {
            var result = current.ToArray();
            Array.Reverse(result);
            yield return result;
        }
        else
        {
            var subResults = GetAllCombinations(input, current, currentCol + 1);
            foreach (var subResult in subResults)
                yield return subResult;
        }
        current.Pop();
    }
}

static void Main()
{
    var input = new[,]
    {
        {"bear", "claw", "donut"},
        {"chicken", "salad", null},
        {"tuna", null, "salad"}
    };

    foreach (var comb in GetAllCombinations(input))
        Console.WriteLine(string.Join(",", comb));
}

和输出:

bear,claw,donut
bear,claw,salad
bear,salad,donut
bear,salad,salad
chicken,claw,donut
chicken,claw,salad
chicken,salad,donut
chicken,salad,salad
tuna,claw,donut
tuna,claw,salad
tuna,salad,donut
tuna,salad,salad

我在 , but shortly after, the requirements became unclear, so I refrained from posting it. Now that they are clear, here is an alternative that uses IEnumerable 的同时写了一个答案。它也不需要 Array.Reverse() 每个答案。

原始答案文本

你会想递归地解决这个问题。

下面的代码假定您已经将 CSV 解析为 IEnumerableIEnumerable 部分。

static void Main()
{
    var wordLists = new List<string[]>()
    {
        new string[] { "bear", "chicken", "tuna" },
        new string[] { "claw", null, "salad" },
        null,
        new string[] { "donut", "salad", null },
    };

    foreach (var result in AllPermutations(wordLists)) 
    {
        System.Console.WriteLine(string.Join(",", result));
    }
}

// our recursive function. 
private static IEnumerable<IEnumerable<string>> AllPermutations(IEnumerable<IEnumerable<string>> wordLists, int index = 0, List<string> current = null)
{
    if (current == null) 
    {
        current = new List<string>();
    }
    
    if (index == wordLists.Count()) 
    { // the end condtion. it is reached when we are past the last list
        yield return current;
    }
    else
    { // if we are not at the end yet, loop through the entire list
      // of words, appending each one, then recursively combining
      // the other lists, and finally removing the word again.
        var wordList = wordLists.ElementAt(index);
        if (wordList != null)
        {
            foreach (var word in wordList)
            {
                if (word == null) continue;
                current.Add(word);
                foreach (var result in AllPermutations(wordLists, index + 1, current)) 
                {
                    yield return result;
                }
                current.RemoveAt(current.Count - 1);
            }
        }
        else
        {
            foreach (var result in AllPermutations(wordLists, index + 1, current)) 
            {
                yield return result;
            }
        }
    }
}

请注意,对于 50 列,可能会有 很多 组合非常快