【问题标题】:How to find the exact number of numbers that satisfy the condition? [duplicate]如何找到满足条件的数字的确切数量? [复制]
【发布时间】:2015-03-13 02:04:18
【问题描述】:

我在一个数组中有给定数量的整数。假设:{1, 2, 3, 4, 5, 6, 7 }。请注意,这只是一个示例,它们可能不是连续的数字。

我需要找到满足以下条件的数字:

  1. 这些数字有一个总和。
  2. 应指定数字的计数。

所以用上面给定的数字:

  1. 如果总和为 7 且计数为 2,则应输出 {1, 6}。
  2. 如果总和为 7 且计数为 3,则应输出 {1, 2, 4}。
  3. 如果总和为 7 且计数为 1,则应输出 {7}。

我发现了类似的线程:algorithm to find the correct set of numbers。但是,那里的算法不需要指定数字计数。这是感谢Lajos Arpad的算法:

public static List<int> backtrack(List<int> currentNumbers, int[] numbers, int depth, int targetValue, int j)
    {
        for (int i = j; i < numbers.Length; i++)
        {
            int potentialSolution = numbers[i];
            if (currentNumbers.Sum() + potentialSolution > targetValue)
            {
                continue;
            }
            else if (currentNumbers.Sum() + potentialSolution == targetValue)
            {
                /*Store solution*/
                currentNumbers.Add(potentialSolution);

                return currentNumbers;
            }
            else
            {
                currentNumbers.Add(potentialSolution);

                return backtrack(currentNumbers, numbers, depth + 1, targetValue, i + 1);
            }
        }

        return null;
    }

有人可以帮我修改它以添加额外的数字计数条件吗?

【问题讨论】:

  • {7} 的计数是 7 而不是 1?这是一个错误还是您使用了一些非标准的计数含义?
  • 他的意思可能是 numbercount = 1
  • 使用你的例子#1,如果总和是7,并且数量是2,它不会也输出{5,2}{4,3}吗?
  • 谢谢鲁弗斯。我在您发帖后 5 分钟内完成了工作 :) 这是解决方案。

标签: c# backtracking


【解决方案1】:

感谢Rufus L 和他的帖子here。这是对他的代码的简单修改。

    private static void GetSumsRecursively(
        List<int> numbers,
        int sum, 
        List<int> candidates, 
        int numbersCount,
        List<List<int>> results)
    {
        int candidateSum = candidates.Sum(x => x);

        if (candidateSum == sum && candidates.Count == numbersCount)
        {
            results.Add(candidates);
        }

        if (candidateSum >= sum)
            return;

        for (int i = 0; i < numbers.Count; i++)
        {
            var remaining = new List<int>();

            for (int j = i + 1; j < numbers.Count; j++)
            {
                remaining.Add(numbers[j]);
            }

            var filteredCandidates = new List<int>(candidates) { numbers[i] };

            GetSumsRecursively(remaining, sum, filteredCandidates,
                numbersCount, results);
        }
    }

    public static List<List<int>> GetNumbers(
        List<int> numbers,
        int numbersCount, 
        int sum)
    {
        if (numbers == null) throw new ArgumentNullException("numbers");

        var results = new List<List<int>>();

        // Fail fast argument validation
        if (numbersCount < 1 ||
            numbersCount > numbers.Count /*||
            sumDifficulty < numQuestions * Question.MinDifficulty ||
            sumDifficulty > numQuestions * Question.MaxDifficulty*/)
        {
            return results;
        }

        // If we only need single questions, no need to do any recursion
        if (numbersCount == 1)
        {
            results.AddRange(numbers.Where(q => q == sum)
                .Select(q => new List<int> { q }));

            return results;
        }

        // We can remove any questions who have a difficulty that's higher
        // than the sumDifficulty minus the number of questions plus one
        var candidateQuestions =
            numbers.Where(q => q <= sum - numbersCount + 1)
                .ToList();

        if (!candidateQuestions.Any())
        {
            return results;
        }

        GetSumsRecursively(candidateQuestions, sum, new List<int>(),
            numbersCount, results);

        return results;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-05
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多