在C++中,使用基于range的for循环迭代range
文章目录
- 基础概述
- 案例展示
- 案例扩展
基础概述
在C++中,你可以使用基于范围的for
循环(range-based for loop)来迭代一个std::range
类型的对象,如std::vector
,std::array
等。但是,std::range
并不是C++标准库的一部分,而是一个示例性的概念用来描述可以被迭代的对象。
如果你想使用基于范围的for
循环来迭代一个特定的范围,比如从0
到某个数n
,通常的做法是创建一个std::vector
或者使用其他容器,并用std::iota
填充它,或者直接使用一个传统的for
循环。但在某些情况下,如果你只是需要简单地迭代一个整数序列,可以直接使用for
循环与std::generate_n
结合std::count
来实现类似的功能。
下面是如何使用基于范围的for
循环来迭代一个std::vector
的例子,这个向量模拟了一个range
的行为:
#include <iostream>
#include <vector>
#include <algorithm> // std::iota
int main() {
int n = 10;
std::vector<int> numbers(n); // 创建一个大小为n的vector
// 使用std::iota填充vector,从0开始计数
std::iota(numbers.begin(), numbers.end(), 0);
// 使用基于范围的for循环来迭代numbers
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
如果仅仅是想迭代一个整数序列而不必实际创建一个包含这些整数的容器,可以使用传统的for
循环:
int n = 10;
for (int i = 0; i < n; ++i) {
std::cout << i << " ";
}
std::cout << std::endl;
这种方法更直接且不需要额外的内存分配。如果需要的是一个更通用的方法来处理迭代,且不想显式创建容器,可以考虑编写一个自己的迭代器类或使用第三方库如Boost.Range。
案例展示
下面是一个具体的例子,展示如何使用基于范围的for
循环来迭代一个整数序列,并计算其中所有偶数的平方和。
假设我们有一个整数序列,我们需要计算其中所有偶数的平方和。我们可以先创建一个包含这些整数的std::vector
,然后使用基于范围的for
循环来遍历这个序列并执行计算。
下面是完整的代码示例:
#include <iostream>
#include <vector>
#include <numeric> // For std::accumulate with custom lambda
#include <algorithm> // For std::iota
int main() {
int n = 10; // 假设我们的整数序列长度为10
std::vector<int> numbers(n); // 创建一个大小为n的vector
// 使用std::iota填充vector,从0开始计数
std::iota(numbers.begin(), numbers.end(), 0);
// 计算所有偶数的平方和
int sumOfSquares = std::accumulate(numbers.begin(), numbers.end(), 0,
[](int acc, int x) {
return (x % 2 == 0) ? acc + x * x : acc;
});
// 输出结果
std::cout << "Sum of squares of even numbers: " << sumOfSquares << std::endl;
// 使用基于范围的for循环打印所有的数字
std::cout << "Numbers in the vector: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在这个例子中,我们首先创建了一个包含0到9的std::vector
。然后,我们使用std::accumulate
函数结合一个lambda表达式来计算所有偶数的平方和。最后,我们使用基于范围的for
循环打印出向量中的所有数字。
当你运行这段程序时,它会输出偶数的平方和以及向量中的所有数字。这个例子展示了如何使用基于范围的for
循环和一些标准库函数来简化常见的编程任务。
案例扩展
接下来,让我们添加一些额外的功能,例如检查用户输入以确定序列的长度,并处理可能的输入错误。
以下是更新后的代码,它包括了用户输入和简单的错误检查:
#include <iostream>
#include <vector>
#include <numeric> // For std::accumulate with custom lambda
#include <algorithm> // For std::iota
#include <limits> // For std::numeric_limits<int>::max()
int main() {
int n = 0;
std::cout << "Enter the length of the sequence: ";
// 输入检查
while (!(std::cin >> n)) {
std::cout << "Invalid input. Please enter an integer: ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (n <= 0) {
std::cout << "The length must be greater than zero." << std::endl;
return 1;
}
std::vector<int> numbers(n); // 创建一个大小为n的vector
// 使用std::iota填充vector,从0开始计数
std::iota(numbers.begin(), numbers.end(), 0);
// 计算所有偶数的平方和
int sumOfSquares = std::accumulate(numbers.begin(), numbers.end(), 0,
[](int acc, int x) {
return (x % 2 == 0) ? acc + x * x : acc;
});
// 输出结果
std::cout << "Sum of squares of even numbers: " << sumOfSquares << std::endl;
// 使用基于范围的for循环打印所有的数字
std::cout << "Numbers in the vector: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在这个版本中,我们增加了对用户输入的检查,确保输入的是一个有效的正整数。如果用户输入非整数或者负数,程序将提示重新输入。此外,还增加了一个条件判断来确保输入的序列长度大于零。
这样做的好处是:
- 用户交互更加友好,程序不会因为非法输入而崩溃。
- 通过输入检查,程序能够更好地处理异常情况。
当用户输入一个有效的正整数后,程序将继续执行,创建一个相应长度的整数序列,并计算所有偶数的平方和。最后,程序还会打印出整个序列的内容。
让我们可以进一步扩展这个示例,使其功能更加完善,并提供更多的用户交互。接下来,我们将添加以下功能:
- 允许用户选择是否要计算偶数还是奇数的平方和。
- 在计算完成后询问用户是否想要再次进行计算。
- 添加一些美化输出的格式。
下面是更新后的代码:
#include <iostream>
#include <vector>
#include <numeric> // For std::accumulate with custom lambda
#include <algorithm> // For std::iota
#include <limits> // For std::numeric_limits<int>::max()
bool isEven(int num) {
return num % 2 == 0;
}
bool isOdd(int num) {
return num % 2 != 0;
}
int main() {
bool continueLoop = true;
while (continueLoop) {
int n = 0;
std::string choice;
std::cout << "Enter the length of the sequence: ";
// 输入检查
while (!(std::cin >> n)) {
std::cout << "Invalid input. Please enter an integer: ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (n <= 0) {
std::cout << "The length must be greater than zero." << std::endl;
continue;
}
std::cout << "Do you want to calculate the sum of squares of even (E) or odd (O) numbers? [E/O]: ";
std::cin >> choice;
bool evenChoice = (choice[0] == 'E' || choice[0] == 'e');
bool oddChoice = (choice[0] == 'O' || choice[0] == 'o');
if (!evenChoice && !oddChoice) {
std::cout << "Invalid choice. Defaulting to even numbers." << std::endl;
evenChoice = true;
}
std::vector<int> numbers(n);
std::iota(numbers.begin(), numbers.end(), 0);
int sumOfSquares = std::accumulate(numbers.begin(), numbers.end(), 0,
[&evenChoice](int acc, int x) {
return evenChoice ? ((x % 2 == 0) ? acc + x * x : acc) : ((x % 2 != 0) ? acc + x * x : acc);
});
std::cout << "Sequence length: " << n << std::endl;
std::cout << "Sum of squares of " << (evenChoice ? "even" : "odd") << " numbers: " << sumOfSquares << std::endl;
std::cout << "Numbers in the vector: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
char repeat;
std::cout << "Would you like to perform another calculation? [Y/N]: ";
std::cin >> repeat;
continueLoop = (repeat == 'Y' || repeat == 'y');
}
std::cout << "Thank you for using this program. Goodbye!" << std::endl;
return 0;
}
在这个版本中,我们做了以下改进:
- 用户选择:允许用户选择计算偶数还是奇数的平方和。
- 重复计算:程序完成后询问用户是否想要重复进行计算,直到用户选择停止。
- 美化输出:增加了更多的输出信息,使结果更加清晰易读。
现在,用户可以输入序列的长度,并选择计算偶数还是奇数的平方和。每次计算结束后,用户可以选择是否继续进行新的计算。这使得程序变得更加互动和灵活。
————————————————
最后我们放松一下眼睛