您的函数中有一个小问题,您在其中迭代数组的边界。在 C++ 中,数组从索引 0 开始。因此,最后一个元素索引是数组大小减 1。
示例:包含五个元素的数组
int array[5] = {10,20,30,40,50};
- 索引 0 处的数组 (array[0]) = 10
- 索引 1 处的数组 (array[1]) = 20
- 索引 2 处的数组 (array[2]) = 30
- 索引 3 处的数组 (array[3]) = 40
- 索引 4 处的数组 (array[4]) = 50
而且,如果你想循环遍历数组,那么大小为 5,你需要写:
for (int i = 0; i < 5; ++i)
因此,对于这种情况,总是,而不是。
如果你运行你的程序,你会注意到你得到了双倍的结果,所以,你可能会得到索引 3 和 5,以及索引 5 和 3。如果总和由user 是数组中某个值的两倍。示例:如果您的数组中有值 4,并且正在寻找总和 8,那么您的程序将为您提供具有相同索引的值 4。
所以,你需要了解你对结果的要求
- 如果你想得到有序对,那么: 对于和 10,对 3,7 和 7,3 是不同的。在这种情况下,您需要从 0 开始两个循环索引
- 如果你想避免一个元素是双倍的,比如 sum 8 和一个元素 4,然后得到 pair 4,4.,你需要添加一个额外的
if-statement,比如if (i != j)。
- 如果需要无序对,也就是说,我们不想看到 3,7 和 7,3,那么您需要在索引 i+1 处开始您的第二个循环。
然后,接下来进行一些优化。您可能会注意到术语intArray[i] 是不变的。它永远不会改变。因此,您可以将其从内循环中取出并将其移至外循环。此外,您始终执行相同的加法。这基本上没有必要。你可以重写:
intArray[i] + intArray[j] == sum to
intArray[j]) == sum - intArray[i]
如果我们用delta 替换术语sum- intArray[i],那么我们可以优化我们的循环:
bool error = true;
for (int i = 0; i < SIZE; i++) {
const int delta = sum - intArray[i];
for (int j = i+1; j < SIZE; j++) {
if (intArray[j] == delta) {
cout << "Item " << i << " (With value " << intArray[i] << ") " << "and item " << j << " (With value " << intArray[j] << ") add up to " << sum << endl;
error = false;
}
}
}
我们现在只有一个减法(而不是多次加法),只访问一次 intArray[i],并且只在内循环中进行比较。
然后我们通常可以改进代码并使用更现代的 C++ 元素。我们需要为用户输入添加错误检查并在需要时而不是之前定义变量。
#include <iostream>
#include <fstream>
#include <vector>
int main() {
// First open source file and check, if it could be opened
// If we cannot open it then no need to do something else
if (std::ifstream inFileStream{"r:\\inFile.txt"}; inFileStream) {
// Instructions for the user
std::cout << "\nPlease enter the number for which a matching sum is needed: ";
// Get the required sum and check for a correct input
if (int requiredSum{}; std::cin >> requiredSum) {
// Now, the indicator that shows, if we could find a pair or not
bool matchingPairFound{};
// Container for data
std::vector<int> data{};
// Read next value from source file until end of file and store it
for (int i{}, value{}; inFileStream >> value; i++) {
data.push_back(value);
// Delta value to find
const int delta = requiredSum - value;
for (int j = i - 1; j >= 0; --j) {
if (delta == data[j]) {
// We found a match
matchingPairFound = true;
// Show somedebug output
std::cout << "Item " << i << " (With value " << data[i] << ") " << "and item " << j << " (With value " << data[j] << ") add up to " << requiredSum << '\n';
}
}
}
std::cout << "\nMatching sum was " << (matchingPairFound ? "found" : "not found") << '\n';
}
else std::cerr << "\n\n***Error: Could not read sum value\n\n";
}
else std::cerr << "\n\n***Error: Could not open input file\n\n";
return 0;
}
这还没有结束。如果要求是我们只想知道是否有一对加起来是和,我们不需要读取所有值。我们将逐个读取值,然后在得到结果后立即停止。然后循环将向后运行
#include <iostream>
#include <fstream>
#include <vector>
int main() {
// First open source file and check, if it could be opened
// If we cannot open it then no need to do something else
if (std::ifstream inFileStream{"r:\\inFile.txt"}; inFileStream) {
// Instructions for the user
std::cout << "\nPlease enter the number for which a matching sum is needed: ";
// Get the required sum and check for a correct input
if (int requiredSum{}; std::cin >> requiredSum) {
// Now, the indicator that shows, if we could find a pair or not
bool matchingPairFound{};
// Container for data
std::vector<int> data{};
// Read next value from source file until end of file and store it
for (int i{}, value{}; (inFileStream >> value) and not matchingPairFound; i++) {
data.push_back(value);
// Delta value to find
const int delta = requiredSum - value;
for (int j = i - 1; (j >= 0) and not matchingPairFound; --j) {
if (delta == data[j]) {
// We found a match
matchingPairFound = true;
// Show somedebug output
std::cout << "Item " << i << " (With value " << data[i] << ") " << "and item " << j << " (With value " << data[j] << ") add up to " << requiredSum << '\n';
}
}
}
std::cout << "\nMatching sum was " << (matchingPairFound ? "found" : "not found") << '\n';
}
else std::cerr << "\n\n***Error: Could not read sum value\n\n";
}
else std::cerr << "\n\n***Error: Could not open input file\n\n";
return 0;
}
而且,如果我们不想看到该对的内容而不是索引,那么程序将更加紧凑。我们假设结果是无序对。而且我们不关心源输入文件中的重复项。他们不会增加任何价值。有一个很好的容器可用于此目的。 std::unordered_set 只会存储唯一值并使用快速哈希算法来访问数据。
以下代码
- 从输入文件中读取任意数量的数据
- 只有在无法做出决定时才读取
- 在做出决定之前只存储不同的值
- 已针对该大小和速度进行了优化
- 而且结构紧凑。函数
main中只有10行代码
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_set>
int main() {
// First open source file and check, if it could be opened
// If we cannot open it then no need to do something else
if (std::ifstream inFileStream{"r:\\inFile.txt"}; inFileStream) {
// Instructions for the user
std::cout << "\nPlease enter the number for which a matching sum is needed: ";
// Get the required sum and check for a correct input
if (int requiredSum{}; std::cin >> requiredSum) {
// Now, the indicator that shows, if we could find a pair or not
bool matchingPairFound{};
// Container for data
std::unordered_set<int> alreadySeenData{};
// Read values from input file until End-Of-File or until a matching pair was found
for (int value{}; (inFileStream >> value) and not matchingPairFound; alreadySeenData.insert(value)) {
// Check, if matching pair was found
matchingPairFound = (alreadySeenData.count(requiredSum - value));
}
// Show result
std::cout << "\nMatching sum was " << (matchingPairFound ? "found" : "not found") << '\n';
}
else std::cerr << "\n\n***Error: Could not read sum value\n\n";
}
else std::cerr << "\n\n***Error: Could not open input file\n\n";
}