【问题标题】:c# How to set the maximum number when do the find all possible combinations of numbers to reach a given sumc#如何在查找所有可能的数字组合以达到给定总和时设置最大数量
【发布时间】:2017-04-14 09:10:21
【问题描述】:

我是 c# 的新手,然后我的主管要求我找到给定数字集的所有可能组合,我必须设置组合的最大值。我已经得到的组合但无法设置最大数量。最大数量是组合的。从我的图像来看,它有 5,4 和 3 行,这是所有可能的组合。但我只想设置仅显示 3 行的输出。我尝试了很多方法,但仍然无法得到它。对不起我的英语不好。

这里是代码。

class Program
{
static void Main(string[] args)
{

    string input;
    decimal goal;
    decimal element;
    int max = 2;

    do
    {
        Console.WriteLine("Please enter the target:");
        input = Console.ReadLine();
    }
    while (!decimal.TryParse(input, out goal));

    Console.WriteLine("Please enter the numbers (separat`enter code here`ed by spaces)");
    input = Console.ReadLine();
    string[] elementsText = input.Split(' ');
    List<decimal> elementsList = new List<decimal>();
    foreach (string elementText in elementsText)
    {
        if (decimal.TryParse(elementText, out element))
        {
            elementsList.Add(element);
        }
    }

    Solver solver = new Solver();
    List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());



    //foreach (List<decimal> result in results)
    //{
    //    foreach (decimal value in result)
    //    {
    //        Console.Write("{0}\t", value);
    //    }
    //    Console.WriteLine();
    //}


    for (int i = 0; i <= results.Count; i++)
    {

        int x = results.SelectMany(list => list).Distinct().Count();

        if (x <= max)
        {

            for (int j = 0; j <= max; j++)
            {
                Console.Write("{0}\t", results[i][j]);
            }
            Console.WriteLine();
        }
    }


    Console.ReadLine();
}
}

here is the ouput

【问题讨论】:

  • 我只想知道如何设置最大数量而已。谢谢
  • 你应该做什么inputoutput
  • 不清楚你在问什么。如果您不能用语言表达,您应该提供更多信息,至少给出示例输入和所需的输出
  • 数字是单个数字,还是任何可能的数字?例如,输入为 [1, 2, 3],组合为 123, 231, ... 等。或者输入为 [12, 34, 1],组合为 [1, 34, 12], ... 等?
  • 您可以输入的最大数量?这里要说清楚

标签: c# arrays loops for-loop


【解决方案1】:

从问题中的 cmets 和其他答案来看,在我看来,OP 已经知道如何计算总和为目标数的所有组合(这可能是问题中的 Solver 所做的)。我认为他想要的是用最少的数字得到组合。

我有几个解决方案,因为我不确定你想要什么:

1) 如果您想要所有数字最少的组合,请执行以下操作:

public static void Main()
{
    // Here I have hard-coded all the combinations,
    // but in real life you would calculate them.
    // Probably using your `Solver` or any of the other answers in this page.
    var combinations = new List<List<decimal>>{
        new List<decimal>{ 1, 2, 3, 4, 5 },
        new List<decimal>{ 1, 2, 5, 7 },
        new List<decimal>{ 1, 3, 4, 7 },
        new List<decimal>{ 1, 3, 5, 6 },
        new List<decimal>{ 2, 3, 4, 6 },
        new List<decimal>{ 2, 6, 7 },
        new List<decimal>{ 3, 5, 7 },
        new List<decimal>{ 4, 5, 6 }
    };

    // Filter the list above to keep only the lists
    // that have the least amount of numbers.
    var filteredCombinations = LeastNumbers(combinations);

    foreach (var combination in filteredCombinations)
    {
        Console.WriteLine(string.Join("\t", combination));
    }
}

public static List<List<decimal>> LeastNumbers(List<List<decimal>> combinations)
{
    // First get the count for each combination, then get the minimum of those.
    int smallestLength = combinations.Select(l => l.Count).Min();

    // Second, only keep those combinations which have a count equals to the value calculated above.
    return combinations.Where(l => l.Count == smallestLength).ToList();
}

输出:

2    6    7
3    5    7
4    5    6

2) 如果您只想要数字最少的组合之一,请改为:

public static void Main()
{
    // Here I have hard-coded all the combinations,
    // but in real life you would calculate them.
    // Probably using your `Solver` or any of the answers in this page.
    var combinations = new List<List<decimal>>{
        new List<decimal>{ 1, 2, 3, 4, 5 },
        new List<decimal>{ 1, 2, 5, 7 },
        new List<decimal>{ 1, 3, 4, 7 },
        new List<decimal>{ 1, 3, 5, 6 },
        new List<decimal>{ 2, 3, 4, 6 },
        new List<decimal>{ 2, 6, 7 },
        new List<decimal>{ 3, 5, 7 },
        new List<decimal>{ 4, 5, 6 }
    };

    // Filter the list above to keep only the first list
    // that has the least amount of numbers.
    var filteredCombination = LeastNumbers(combinations);

    Console.WriteLine(string.Join("\t", filteredCombination));
}

public static List<decimal> LeastNumbers(List<List<decimal>> combinations)
{
    // First get the count for each combination,
    // then get the minimum of those.
    int smallestLength = combinations.Select(l => l.Count).Min();

    // Second, get only one of the combinations that have a count
    // equals to the value calculated above.
    return combinations.First(l => l.Count == smallestLength);
}

输出:

2    6    7

3) OP 还提到了最大值 3。所以,如果你事先知道这个数字,你可以这样做:

public static void Main()
{
    // Here I have hard-coded all the combinations,
    // but in real life you would calculate them.
    // Probably using your `Solver` or any of the answers in this page.
    var combinations = new List<List<decimal>>{
        new List<decimal>{ 1, 2, 3, 4, 5 },
        new List<decimal>{ 1, 2, 5, 7 },
        new List<decimal>{ 1, 3, 4, 7 },
        new List<decimal>{ 1, 3, 5, 6 },
        new List<decimal>{ 2, 3, 4, 6 },
        new List<decimal>{ 2, 6, 7 },
        new List<decimal>{ 3, 5, 7 },
        new List<decimal>{ 4, 5, 6 }
    };

    // This must be known before hand.
    // That's why I think my first solution is more usefull.
    int max = 3;

    // Filter the list above to keep only the lists
    // that have a count less or equal to a predetermined maximum.
    var filteredCombinations = FilterByMaxLength(combinations, max);

    foreach (var combination in filteredCombinations)
    {
        Console.WriteLine(string.Join("\t", combination));
    }
}

public static List<List<decimal>> FilterByMaxLength(List<List<decimal>> combinations, int max)
{
    return combinations.Where(l => l.Count <= max).ToList();
}
2    6    7
3    5    7
4    5    6

注意:在实际场景中,您还需要检查这些函数,例如检查空列表或空列表。

【讨论】:

  • 我会试试的。顺便说一句,谢谢。
【解决方案2】:

这是我的尝试,您可以根据需要进行调整:

using System.Collections.Generic;
using System.Linq;        
private static void GetMaxPermutation(int max)
        {
            var numbers = new[] { 1, 2, 4, 6, 7 };
            var results = new List<IEnumerable<int>>();
            for (int i = 1; i <= numbers.Length; i++)
            {
                results.AddRange(GetPermutations(numbers, i));
            }
            Console.WriteLine("Result: " + string.Join(" ", results.Select(x => new { Target = x, Sum = x.Sum() }).Where(x => x.Sum <= max).OrderByDescending(x => x.Sum).FirstOrDefault().Target));
        }

    private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count)
    {
        int i = 0;
        foreach (var item in items)
        {
            if (count == 1)
                yield return new T[] { item };
            else
            {
                foreach (var result in GetPermutations(items.Skip(i + 1), count - 1))
                    yield return new T[] { item }.Concat(result);
            }

            ++i;
        }
    }

我从here得到这个排列方法

【讨论】:

    【解决方案3】:

    很难找到你想做的事,是这样的

    List<string> numbers = new List<string>(){"1","2","3","4","5"};
    List<string> possibleCombination = GetCombination(numbers, new List<string>(), "");
    Console.Write(string.Join(", ",possibleCombination.Distinct().OrderBy(itm => itm)));
    

    方法

    static List<string> GetCombination(List<string> list, List<string> combinations, string sumNum, bool addNumberToResult = false)
        {
            if (list.Count == 0) {
                return combinations;
            }
    
            string tmp;
    
            for (int i = 0; i <= list.Count - 1; i++) {
                tmp = string.Concat(sumNum , list[i]);
                if(addNumberToResult){
                    combinations.Add(tmp);
                }
                List<string> tmp_list = new List<string>(list);
                tmp_list.RemoveAt(i);
                GetCombination(tmp_list,combinations,tmp, true);
            }
    
            return combinations;
        }
    

    C# Fiddle可以帮到你吗?

    【讨论】:

    • 感谢您的回答。但我想要只返回 3 个或更少数字的输出。
    猜你喜欢
    • 2011-06-05
    • 2016-12-08
    • 2019-05-24
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多