首先,很抱歉回答太长了:)
问题:我认为您的蛮力问题在于您每次检查都执行了两次(在两个方向上)。此外,不需要进行大量检查。
您可以通过只进行一次检查(并且只进行必要的检查)来轻松减少迭代次数。
关键思想:你不应该从0开始内循环。
注意:以下部分中的第一部分仅介绍第二部分,但第二部分是回答您问题的部分。
此处提供的整个代码仅用于说明所述想法,仅此而已。
1 - 找出所有可能的魔法对
这里我们试图找到给定向量中所有可能的魔法对,避免多次检查同一对。
解决方案可能是:
std::vector<std::pair<int, int>> magical_pairs(const std::vector<int> & data)
{
std::vector<std::pair<int, int>> result;
for(size_t i = 0; i < data.size()-1; ++i) // Stop at second to last
{
for(size_t j = i+1; j < data.size(); ++j) // Start from i+1 and not 0
{
if((data[i] & data[j]) == 0)
result.push_back(std::make_pair(data[i], data[j]));
}
}
return result;
}
这样,您只需检查一次。
根据我的说法,如果你想获得所有可能的魔法对,你不能将复杂性降低到只检查一次所有可能的配对所需要的程度。
但如果有人有更好的解决方案,我很想听听(阅读)。
你可以这样运行一个例子:
std::vector<int> input_array {3, 12, -6, 27, 8, 18, -66, 47, 11}; // input example
for(const std::pair<int, int> & mp : magical_pairs(input_array))
std::cout << mp.first << " : " << mp.second << std::endl;
这个例子的结果:
3 : 12
3 : 8
12:18
8 : 18
2 - 检查一个数字是否有一个神奇的对
现在我们知道如何避免检查已经检查的对,我们将重用相同的原理来实现您想要的功能。
你想检查数组中的每个数字是否在数组中都有一个神奇的对。
在这种情况下,我们不想检查所有可能的神奇对,只有一个匹配就足够了确定一个数字是否有一对。此外,当我们找到匹配项时,我们可以一次设置两个结果(对的每个数字一个)。
您可以看到,这样,我们将能够显着减少迭代次数。
它引导我们进行如下操作:
- 每对只检查一次
- 在第一次匹配时停止计算数字
- 每次匹配确定两个结果 --> 如果已设置则不执行搜索
知道了这一点,解决方案可能是:
std::vector<bool> has_magical_pair(const std::vector<int> & data)
{
std::vector<bool> result(data.size(), false);
for(size_t i = 0; i < data.size()-1; ++i) // From 0 to second to last
{
if(!result[i]) // search for a magical pair only if not already found
{
for(size_t j = i+1; j < data.size(); ++j) // From i+1 to last
{
if((data[i] & data[j]) == 0)
{
// Set two results at a time
result[i] = true;
result[j] = true;
break; // Exit the inner loop at first match
}
}
}
}
return result;
}
这样,您将比蛮力方法更有效率。
你可以这样运行一个例子:
std::vector<int> input_array {3, 12, -6, 27, 8, 18, -66, 47, 11};
for(bool hmp : has_magical_pair(input_array))
std::cout << hmp << ", ";
std::cout << std::endl;
这个例子的结果:
1, 1, 0, 0, 1, 1, 0, 0, 0,
我认为您将能够很容易地使本示例的代码适应您的用例。
希望对你有帮助。