c#如何在找到所有可能的数字组合以达到给定总和时设置最大数量

时间:2017-04-14 09:10:21

标签: c# arrays loops for-loop

我是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

3 个答案:

答案 0 :(得分:1)

根据问题和其他答案中的评论,在我看来OP已经知道如何计算其总和是目标数的所有组合(可能是Solver中的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(); } 问题)。我认为他想要的是用最少的数字来组合。

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

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

2    6    7
3    5    7
4    5    6

输出:

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)如果您只想要其中一个号码最少的组合,请改为:

2    6    7

输出:

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();
}

3)OP还提到最大值为3.因此,如果你事先知道这个数字,你可以这样做:

2    6    7
3    5    7
4    5    6
class_name: AcceptanceTester
    modules:
        enabled:
            - WebDriver:
            url: 'http://www.test.com/'
            browser: 'firefox'
            - Asserts
            - \Helper\Acceptance

注意:在实际情况中,您还需要对这些函数进行一些检查,例如检查空列表或空列表。

答案 1 :(得分:0)

很难找到你想要做的事情,就像这样

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可以帮到你吗?

答案 2 :(得分:0)

这是我的尝试,你可以根据你的需要调整这个:

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

获得了这种排列方法