简体   繁体   English

查找x ^ n的所有组合,并检查它们加起来是否等于一个数字,但不包括相同的数字

[英]Find all combinations for x^n and check if they add up to a number excluding same numbers

So I was looking for a program which goes through all combinations of indices of an array and checks if there are corresponding numbers in the array which add up to a specific number (eg with 2 indices: array[0 to 10] + array[1 to 10] == number ? ). 所以我一直在寻找一个程序,它检查数组的所有索引组合,并检查数组中是否有对应的数字加起来等于一个特定的数字(例如,具有2个索引:array [0至10] + array [1到10] ==数字?)。 It should exclude combinations with the same index and preferably also combinations with just an other order (eg only 1,2 and not 2,1). 它应排除具有相同索引的组合,最好还排除仅具有其他顺序的组合(例如,仅1,2,而不是2,1)。 When it finds such a combination it should save the right indices. 当找到这样的组合时,应该保存正确的索引。 My solution would be to do it with for-loops, but then I would have to create a new for-loop for each additional index which would be very tedious for approx. 我的解决方案是使用for循环,但是随后我将不得不为每个附加索引创建一个新的for循环,这对于大约而言非常繁琐。 40 indices. 40个索引。 Here is an example in C++: 这是C ++中的示例:

//3 indices
for (int i = 0; i < iter - 2 && canWork == false; i++) {
    for (int k = i + 1; k < iter - 1 && canWork == false; k++) {
        for (int l = k + 1; l < iter && canWork == false; l++) {
            if (sizes[i] + sizes[k] + sizes[l] == number) {
                indices[0] = i;
                indices[1] = k;
                indices[2] = l;
                canWork = true;
            }
        }
    }
}

//4 indices
for (int i = 0; i < sizeArray - 3 && canWork == false; i++) {
    for (int k = i + 1; k < sizeArray - 2 && canWork == false; k++) {
        for (int l = k + 1; l < sizeArray -1 && canWork == false; l++) {
            for (int m = l + 1; m < sizeArray && canWork == false; m++) {
                if (array[i] + array[k] + array[l] + array[m] == number) {
                    indices[0] = i;
                    indices[1] = k;
                    indices[2] = l;
                    indices[3] = m;
                    canWork = true;
                }
            }
        }
    }
}

The - 2 and -1 after the sizeArray and the start with + 1 serves to skip same sums. sizeArray以及以+ 1开头的-2和-1用于跳过相同的和。 I am a very beginner programmer, so please forgive me if the code is that bad. 我是一个非常初级的程序员,所以如果代码不好那么请原谅我。 I also could not find anything regarding this problem, so I am asking here. 我也找不到有关此问题的任何内容,因此我在这里问。

As I had already hinted at in my comment to your question, the easiest way to solve this problem is by using what is known as dynamic programming . 正如我在对您的问题的评论中已经暗示的那样,解决此问题的最简单方法是使用所谓的动态编程

The idea is to find a relation between the problem when searching for n indices and the problem when searching for n + 1 indices. 想法是找到在搜索n索引时的问题与在搜索n + 1索引时的问题之间的关系。

In this particular case, we can reduce the case of n + 1 indices to the case of n indices by using the following observations: 在这种特定的情况下,就可以减少的情况下, n + 1索引到的情况下n通过使用以下观察指标:

  • There are two possibilities: Either a combination of n + 1 indices that satisfies the constraints uses the very last index of the array, or it doesn't. 有两种可能:满足约束的n + 1索引的组合使用数组的最后一个索引,否则不使用。 In the first case we can find a combination of n + 1 indices that sum to number by searching for n indices in the array up to but excluding the last element that sum to number - v where v is the value of the last element in the array. 在第一种情况下,我们可以找到的组合n + 1该总和到索引number通过搜索n阵列高达索引但不包括最后一个元素总和number - v ,其中v是在最后一个元素的值数组。 If we can't find such a combination (ie we're in the second case) then we can try again to search for n + 1 indices in the array without the last element. 如果我们找不到这样的组合(即我们处于第二种情况),那么我们可以再次尝试在没有最后一个元素的情况下在数组中搜索n + 1索引。
  • There is no combination of n indices that sum to number if the array has less than n elements. 没有的组合n索引该总和number如果阵列具有小于n元件。
  • The case of n = 1 is trivial: We just have to walk through the array once and see if we can find one value that is equal to the number we're looking for. n = 1的情况是微不足道的:我们只需要遍历一次数组,看看是否可以找到一个等于所要查找数字的值。

A straight forward implementation of these observations can look like this: 这些观察结果的直接实现如下所示:

#include <algorithm>
#include <iterator>
#include <vector>

/**
 * returns the `number_of_indices` indices of `input_array` for which 
 * the corresponding elements sum to `sum`, or an empty vector if
 * there is no such combination of indices.
 */
std::vector<std::int64_t> find_n_indices_that_sum_to(std::vector<int> input_array, 
                                                     int number_of_indices,
                                                     int sum)
{
    if (number_of_indices == 1)
    {
        // the trivial case, just search for one element equal to `sum`.
        auto const match = std::find(std::cbegin(input_array),
                                     std::cend(input_array),
                                     sum);

        return match != std::cend(input_array) 
            ? std::vector<std::int64_t>{std::distance(std::cbegin(input_array), match)}
            : std::vector<std::int64_t>{};
    } else if (static_cast<std::size_t>(number_of_indices) > std::size(input_array)) {
        // not enough elements to find the required number of indices
        return std::vector<std::int64_t>{};
    } else {
        auto const last_index = std::size(input_array) - 1;
        auto const value = input_array.back();

        // reduce the size of the array by 1 - either we find
        // `number_of_indices - 1` additional indices that sum to 
        // `sum - value` or we're in case 2 described above and try 
        // to find `number_of_indices` indices in the smaller array
        input_array.pop_back();

        auto indices = find_n_indices_that_sum_to(input_array,
                                                  number_of_indices - 1, 
                                                  sum - value);
        if (!indices.empty()) {
            // case 1 - there is a combination of indices whose corresponding
            //          elements sum to `sum` with one of them being the
            //          very last index of the array
            indices.push_back(last_index);

            return indices;                 
        } else {
            // case 2 - we try again in the smaller array
            return find_n_indices_that_sum_to(input_array,
                                              number_of_indices,
                                              sum);
        }
    }
}

You can also try this solution on wandbox . 您也可以在wandbox上尝试此解决方案。

If you like you can also try to improve the performance of this solution, eg by replacing the input_array vector argument by a gsl::span to avoid copies or by making the function tail-recursive or even fully imperative in order to avoid stack overflows for large number_of_indices . 如果愿意,您还可以尝试提高此解决方案的性能,例如,通过用gsl::span替换input_array矢量参数来避免复制,或者通过使函数尾部递归甚至完全强制,以避免堆栈溢出,从而解决该问题。大量的number_of_indices

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 生成添加到特定数字的所有唯一数字组合 - Generate all of the unique combinations of numbers that add up to a certain number 找出n个数字的公因子数(不包括“ 1”作为公因子) - Find the number of common factors for n numbers excluding “1” as common factor 使用并行线程查找加起来为给定数字的所有组合 - Find all combinations that add upto given number using parallel threads 找到1和N之间的所有数字的总和,可以用x或y整除 - Find the sum of all numbers between 1 and N divisible by either x or y 在数组中查找加起来为给定数字的数字c ++ - find numbers in array that add up to a given number c++ 如何找到添加两个变量的所有可能组合,每个变量都附加到一个乘数,总和为给定的数字(cin)? - How to find all possible combinations of adding two variables, each attached to a multiplier, summing up to a given number (cin)? 给定一个由N个数字组成的数组,求出所有长度为R?的序列的数目。 - Given an array of N numbers,find the number of sequences of all lengths having the range of R? 如何找到可以除以所有数字 1:n 且没有余数的最小数字? - How do I find the smallest number than can be divided by all numbers 1:n with no remainder? 对于给定的数字N,我必须找到它所组成的所有素数 - For a given number N i have to find all the prime numbers it's consisting of 对于给定的整数a,找到总和为a的所有唯一正整数组合 - For a given integer a, find all unique combinations of positive integers that sum up to a
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM