在数组中查找一个变量,哪个和最接近目标和
Find a variables in array, which sum is closest to target sum
我有一个变量数组{500450455700800,…},我需要从数组中找到10个变量,比如说,它生成的和最接近4500。C#或C++中有算法或方法吗?
这正是0/1背包的问题,可以在这里描述的O(n^2)
中使用动态编程(其中n是我们想要达到的和,例如4500)来解决http://en.wikipedia.org/wiki/Knapsack_problem#0.2F1_Knapsack_Problem.创建的dp数组包含所需的信息。
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;
}
当然可以优化。。。这篇文章的组合算法值得称赞。
我会从蛮力方法开始。您的需求似乎不够流行,无法发布库或算法。
在我实现了蛮力方法并使其工作后,我会在工作系统中对其进行评测。如果算法需要更快或占用更少的空间,我会相应地进行优化。
这是我建议的算法:
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> >.
}
在映射中循环,直到找到一个大于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
}
}
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 我应该如何在没有变量的情况下将相同的参数传递给 CMAKE 中的多个目标?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 如果输入类型与目标类型不同,"cin"变量是否重置为某个默认值?
- 目标-C 变量布局
- Google Mock:在目标类的构造函数中实例化的模拟私有变量成员
- 如何在不定义目标变量大小的情况下逐个字符将字符串变量复制到另一个字符
- 目标C C++ if(cin >>变量) 等价
- 在数组中查找一个变量,哪个和最接近目标和
- 在c++中将只读变量更改为目标
- 针对不同生成文件目标的不同变量集
- 如何定义一个变量,然后在目标[Makefile]中编译
- GNU Make -在规则/目标中设置shell命令输出中的MAKEFILE变量
- 根据Makefile中的目标更改变量
- 如何设置一个目标后的变量
- 目标 C - 使用局部变量声明的dispatch_apply无法在方法实现中编译C++