【问题标题】:Get combinations of K size based off of a dictionary c#根据字典 c# 获取 K 大小的组合
【发布时间】:2020-02-29 15:13:18
【问题描述】:

我有一本这样的字典。

Dictionary<int, string> Diccionario = new Dictionary<int, string>(){
        {1,"124"}  ,  {4,"1457"}  ,  {7,"478"},
        {2,"1235"} ,  {5,"24568"} ,  {8,"05789"},
        {3,"236"}  ,  {6,"3569"}  ,  {9,"698"},
        {0,"08"}   
};

我想获得n 整数的所有组合。例如。

对于n = 11 - 11, 12, 14, 21, 22, 24, 41, 42, 44.

对于n = 24-11, 14, 15, 17, 21, 24, 25, 27, 31, 34, 35, 37, 51, 54, 55, 57.

对于n = 339 - 236, 256, 259...

等等...但是我不知道如何遍历所有这些数字,因为每个数字的长度并不总是相同的。 (1 有三种可能的组合,2 有四种;以此类推)

谢谢!

既然你们问我数据是从哪里来的……它来自这里。

假设 PIN 是 1273,那么有必要根据相邻的数字(水平和垂直)创建所有可能的组合,例如(1 有 2、3 和数字本身),这样更容易我做了前面可以看到的字典,为每个键赋予其可能的值。

由于答案已关闭,我不确定我可以添加什么样的信息,因为我不能对这个问题说太多。就像我有一本颜色字典,例如:

Dictionary<int, string> Diccionario = new Dictionary<int, string[]>(){
        {1,{"red"}, {"blue"}, {"green"}} , 
        {2,{{"green"}, {"orange"} },
        {3, {{"dark"}}

};

因此,如果我得到 32 号组合,则为:Dark GreenDark Orange

不确定我是否在说明我的观点。

【问题讨论】:

  • n=11 的结果如何从 11 到 44?而其他的开始结果低于n?如果与 n 的值不相关,那么该最小值从何而来?
  • 我想只要您为数据和创建该输出的规则提供一些有意义的输入,您就可以自己解决这个问题。目前我不知道这些数字是如何得出的。没有 11、31 或 24 或其他所有这些。
  • 抱歉耽搁了,我更新了帖子,所以你可以看到数据来自哪里......
  • “周围的数字(水平和垂直)例如(1 有 2、3 和数字本身)”不。 1 有 2 和 4 作为相邻的数字。但除此之外,它正在慢慢开始变得有意义。我的回答是正确的:你需要一个Dicitonary&lt;int, int[]&gt;
  • 我越了解这个问题,这个设计就越是错误的。 Diccionario 应该是Dictionary&lt;int, int[]&gt;。永远不要把完美的整数变成字符串。字符串很难使用。充其量是 I/O 的必要之恶n 也应该是int[]。分别为“1,1”、“2,4”和“3,3,9”。您不应该将两个完全独立且不相关的整数变成一个整数。

标签: c# dictionary combinations


【解决方案1】:

您正在尝试做笛卡尔积。这在这里解决了:Generating all Possible Combinations(所有归功于 Eric Lippert)

使用该功能,任务真的很简单:

private static readonly int[][] adjacent = new int[][]
    {
        new int[]{0,8},//0
        new int[]{1,2,4},//1  
        new int[]{1,2,3,5},//2
        new int[]{2,3,6},//3
        new int[]{1,4,5,7},//4  
        new int[]{2,4,5,6,8},//5
        new int[]{3,5,6,9},//6
        new int[]{4,7,8},//7
        new int[]{0,5,7,8,9},//8
        new int[]{6,9,8}//9                
    };

public static IEnumerable<IEnumerable<int>> GetCombinations(int[] input)
{
    if (input.Length == 0) { return new int[0][]; }

    return CartesianProduct(input.Select(n => adjacent[n]));
}

您将输入中的每个数字替换为相邻数字的数组并进行笛卡尔积。空输入有一种特殊情况,CartesianProduct 函数返回一个空序列,我猜这不是正确的结果。它应该返回空序列。

【讨论】:

    【解决方案2】:

    在一些 cmet 之后,我想我弄清楚了你的问题(不止一个)。

    • Diccionario 应该是Dictionary&lt;int, int[]&gt;。 String 是一种糟糕的类型。而且由于您似乎没有使用 * 和 # 键,因此我也没有看到对 char 的调用。
    • 即使是字典也可能过火。一个简单的索引集合也可以做到这一点。您通常应该只在索引不连续的情况下使用它。但是为了便于阅读,这本词典可以在这里使用。
    • 输入的n也不是单个数字,而是int[]的数组

    对于输入{3, 3, 9},您需要{2, 3, 6}{2, 3, 6}{ 6, 8, 9} 的所有组合。使用 4 层以上的嵌套循环可以做到这一点,但您可能希望研究递归。这是一个固有的递归操作。

    但是,我在命名参数和变量时不知所措。这使得编写示例代码非常困难。

    【讨论】:

    • 这如何回答这个完全不清楚的问题?这只是理解一些概念的相关点的列表。
    • @HimBromBeere 我特别引用了我所回答的问题。它似乎是一个基本的“嵌套迭代”问题。
    • @HimBromBeere 我在那里占了 50%。现在我 100% 在那里。
    • @Christopher Wo,现在我想我明白了,至少我知道如何让它发挥作用。甚至认为我不确定如何将嵌套迭代 for(for(for))) 转换为递归函数。谢谢!
    • @Omar 循环和递归之间的转换通常很容易。然而,固有递归问题的罕见情况,不能有效地转换成循环。这听起来像是一种罕见的情况:youtu.be/HXNhEYqFo0o
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2018-06-26
    • 2020-07-29
    • 1970-01-01
    • 2015-11-27
    • 2022-12-02
    相关资源
    最近更新 更多