C# 在数组中查找最接近目标和的变量
我有一个变量数组{500,450,455,700,800,…},我需要从数组中找到10个变量,它们生成的和最接近4500。在C++或C++中有没有算法或方法?< p>我将用蛮力方法开始。您的需求似乎不太受欢迎,无法发布库或算法 在我实现蛮力方法并使其工作后,我将在工作系统中对其进行分析。如果算法需要更快或占用更少的空间,我会相应地优化它 以下是我建议的算法:C# 在数组中查找最接近目标和的变量,c#,c++,algorithm,C#,C++,Algorithm,我有一个变量数组{500,450,455,700,800,…},我需要从数组中找到10个变量,它们生成的和最接近4500。在C++或C++中有没有算法或方法?< p>我将用蛮力方法开始。您的需求似乎不太受欢迎,无法发布库或算法 在我实现蛮力方法并使其工作后,我将在工作系统中对其进行分析。如果算法需要更快或占用更少的空间,我会相应地优化它 以下是我建议的算法: for index = 0; index < NUMBER_QUANTITY - 10; ++ index { Create a
for index = 0; index < NUMBER_QUANTITY - 10; ++ index
{
Create a vector with 10 numbers from the array.
Create a sum of the 10 numbers.
Store the vector and sum into a std::map<int, vector<int> >.
}
索引=0的;索引<数量\数量-10;++指数
{
从数组中创建一个包含10个数字的向量。
创建10个数字的总和。
将向量和总和存储到std::map中。
}
遍历映射,直到找到大于4500的键。最接近的值将位于(迭代器+0)和(迭代器-1)。
使用迭代器,从映射中提取向量并列出映射中的数字 编辑1:优化
您可以保留一个单独的向量,如果其总和接近目标值,则该向量将被更新,而不是将每个包含10个数字的向量存储到一个映射中
int sum_delta = 4500;
int sum = 0;
for (...)
{
Calculate temporary sum of the 10 numbers.
Calculate temporary sum delta: abs(4500 - sum);
if (temporary sum delta < sum_delta)
{
sum = temporary sum;
sum_delta = temporary sum delta;
copy 10 numbers into vector
}
}
int sum_delta=4500;
整数和=0;
对于(…)
{
计算10个数字的临时总和。
计算临时总额增量:abs(4500-总和);
if(临时总和增量<总和增量)
{
总和=临时总和;
总和δ=临时总和δ;
将10个数字复制到向量中
}
}
这正是0/1背包的问题,可以在这里描述的O(n^2)
中使用动态规划(其中n是我们想要达到的总和,例如4500)来解决。创建的DP数组包含了所需信息。< p> C++ STL库提供了一种迭代排列的功能,但不提供组合。然而,有一种方法可以解决这个问题
给你一个想法:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <cstdlib>
int main()
{
const int numbers[] = { 500, 450, 455, 700, 800, 123, 234, 345, 456, 567, 678, 789, 890, 901, 854, 365, 785, 987, 876, 765, 654, 543, 432, 321};
const std::size_t n = sizeof(numbers) / sizeof(*numbers);
const std::size_t r = 10;
const int targetSum = 4500;
std::vector<int> numvec(&numbers[0], &numbers[n]);
std::vector<bool> indices(n);
std::fill(indices.begin() + n - r, indices.end(), true);
int bestDelta = targetSum;
std::vector<int> bestCombination;
do {
std::vector<int> combination;
for (std::size_t i = 0; i < n; ++i) {
if (indices[i]) {
combination.push_back(numvec.at(i));
}
}
int sum = std::accumulate(combination.begin(), combination.end(), 0);
int delta = abs(sum - targetSum);
if (delta < bestDelta) {
bestDelta = delta;
bestCombination = combination;
for (std::vector<int>::const_iterator it = combination.begin(), end = combination.end(); it != end; ++it) {
if (it != combination.begin()) {
std::cout << "+";
}
std::cout << *it;
}
std::cout << "=" << sum << std::endl;
}
if (sum == targetSum) {
break;
}
} while (std::next_permutation(indices.begin(), indices.end()));
return 0;
}
#包括
#包括组合算法。假设我有一个由20个变量组成的数组,我需要找到10个,这10个变量加起来,结果接近4500。对不起,我说的是英语。你的算法是什么?(请贴出来)我没有,我还在考虑这个问题的解决方案…也许我会找一个更聪明的人给你一些好主意…这个是NP完全的,而你的更难假设你的“说10”是“让我尽可能接近10”,而不是“必须正好是10”。我的意思是你必须从20中得到10个变量,正好是10,总的来说,结果是4500。谢谢!明天就要测试了!再次感谢!如果这有帮助,请单击复选标记。谢谢,这正是我要找的!无论如何,谢谢大家的帮助!迪米特里斯和托马斯·马修斯也感谢你们的建议!