STL算法实践:容器操作与数值计算
字符串反转与旋转操作
标准库提供了多种用于调整元素顺序的算法。std::reverse直接在原容器上执行反转,而std::reverse_copy则将结果写入目标区间,保持源数据不变。std::rotate则通过指定新的起始位置实现循环移位。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
template <typename Container>
void print_elements(const Container& data) {
for (const auto& elem : data) {
std::cout << elem << ' ';
}
std::cout << '\n';
}
void demo_string_reverse() {
using namespace std;
string original{ "abcdefghij" };
cout << "原始: " << original << endl;
string reversed(original);
reverse(reversed.begin(), reversed.end());
cout << "反转: " << reversed << endl;
string copied(original.size(), ' ');
reverse_copy(original.begin(), original.end(), copied.begin());
cout << "复制反转: " << copied << endl;
}
void demo_vector_rotate() {
using namespace std;
vector<int> nums{ 0,1,2,3,4,5,6,7,8,9 };
cout << "原始: "; print_elements(nums);
vector<int> temp1(nums);
rotate(temp1.begin(), temp1.begin() + 3, temp1.end());
cout << "左移3位: "; print_elements(temp1);
vector<int> temp2(nums);
rotate(temp2.begin(), temp2.end() - 2, temp2.end());
cout << "右移2位: "; print_elements(temp2);
}
数值生成与统计分析
std::generate使用可调用对象填充容器,std::minmax_element单次遍历即可获取极值对,效率优于分别调用。
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <cstdlib>
#include <ctime>
int random_0_100() {
return rand() % 101;
}
void demo_statistical_analysis() {
using namespace std;
srand(static_cast<unsigned>(time(nullptr)));
vector<int> data(10);
generate(data.begin(), data.end(), random_0_100);
cout << "随机数据: ";
for (auto v : data) cout << v << ' ';
cout << '\n';
auto [min_pos, max_pos] = minmax_element(data.begin(), data.end());
cout << "最小值: " << *min_pos << ", 最大值: " << *max_pos << '\n';
double mean = accumulate(data.begin(), data.end(), 0.0) / data.size();
cout << "平均值: " << fixed << setprecision(2) << mean << '\n';
sort(data.begin(), data.end());
double trimmed_mean = accumulate(data.begin() + 1, data.end() - 1, 0.0)
/ (data.size() - 2);
cout << "去极值平均: " << trimmed_mean << '\n';
}
字符转换与映射变换
std::transform将一元或二元函数作用于源区间,结果写入目标区间。std::tolower与std::toupper实现大小写转换,需注意C locale依赖。
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
unsigned char shift_letter(unsigned char ch) {
if (ch == 'z') return 'a';
if (ch == 'Z') return 'A';
if (isalpha(ch)) return static_cast<unsigned char>(ch + 1);
return ch;
}
void demo_character_transform() {
using namespace std;
string text{ "Hello World 2024!" };
cout << "原文: " << text << '\n';
string lower_ver;
transform(text.begin(), text.end(), back_inserter(lower_ver),
[](unsigned char c){ return tolower(c); });
cout << "小写: " << lower_ver << '\n';
string upper_ver;
transform(text.begin(), text.end(), back_inserter(upper_ver),
[](unsigned char c){ return toupper(c); });
cout << "大写: " << upper_ver << '\n';
string shifted(text.size(), ' ');
transform(text.begin(), text.end(), shifted.begin(), shift_letter);
cout << "字母移位: " << shifted << '\n';
}
回文检测实现
回文判断可通过反转比较实现,忽略大小写时需先统一转换。
#include <iostream>
#include <string>
#include <algorithm>
bool check_palindrome(const string& src) {
string reversed(src.size(), ' ');
reverse_copy(src.begin(), src.end(), reversed.begin());
return src == reversed;
}
bool check_palindrome_icase(const string& src) {
string normalized;
transform(src.begin(), src.end(), back_inserter(normalized),
[](unsigned char c){ return tolower(c); });
string reversed(normalized.size(), ' ');
reverse_copy(normalized.begin(), normalized.end(), reversed.begin());
return normalized == reversed;
}
void demo_palindrome_check() {
using namespace std;
string input;
while (getline(cin, input)) {
cout << boolalpha
<< "严格回文: " << check_palindrome(input) << '\n'
<< "忽略大小写: " << check_palindrome_icase(input) << "\n\n";
}
}
进制转换算法
通过取模和除法迭代实现十进制到任意进制的转换,结果需反转。
#include <iostream>
#include <string>
#include <algorithm>
std::string convert_base(int value, int base = 2) {
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (value == 0) return "0";
std::string result;
bool negative = value < 0;
unsigned int abs_val = negative ? -value : value;
while (abs_val > 0) {
result.push_back(digits[abs_val % base]);
abs_val /= base;
}
if (negative) result.push_back('-');
reverse(result.begin(), result.end());
return result;
}
void demo_base_conversion() {
using namespace std;
int number;
while (cin >> number) {
cout << "十进制: " << number << '\n'
<< "二进制: " << convert_base(number) << '\n'
<< "八进制: " << convert_base(number, 8) << '\n'
<< "十六进制: " << convert_base(number, 16) << "\n\n";
}
}
凯撒密码表生成
利用std::rotate生成移位密码表,展示26种可能的位移。
#include <iostream>
#include <string>
#include <iomanip>
void print_caesar_table() {
using namespace std;
string alphabet{ "abcdefghijklmnopqrstuvwxyz" };
string uppercase;
transform(alphabet.begin(), alphabet.end(), back_inserter(uppercase),
[](char c){ return toupper(c); });
cout << setw(3) << ' ';
for (char c : alphabet) cout << setw(2) << c;
cout << '\n';
for (int shift = 0; shift < 26; ++shift) {
cout << setw(3) << shift;
string row(uppercase);
rotate(row.begin(), row.begin() + shift, row.end());
for (char c : row) cout << setw(2) << c;
cout << '\n';
}
}
算术练习程序
结合随机数生成与Lambda表达式,构建交互式四则运算测试。
#include <iostream>
#include <ctime>
#include <iomanip>
enum class Operator { Add, Subtract, Multiply, Divide };
struct Question {
int left, right, answer;
char op_symbol;
};
Question generate_question() {
auto rand_1_10 = [](){ return rand() % 10 + 1; };
Operator op = static_cast<Operator>(rand() % 4);
Question q;
switch (op) {
case Operator::Add:
q.left = rand_1_10(); q.right = rand_1_10();
q.answer = q.left + q.right; q.op_symbol = '+';
break;
case Operator::Subtract:
q.left = rand_1_10(); q.right = rand() % q.left + 1;
q.answer = q.left - q.right; q.op_symbol = '-';
break;
case Operator::Multiply:
q.left = rand_1_10(); q.right = rand_1_10();
q.answer = q.left * q.right; q.op_symbol = '*';
break;
case Operator::Divide:
q.right = rand_1_10();
q.answer = rand_1_10();
q.left = q.answer * q.right;
q.op_symbol = '/';
break;
}
return q;
}
void run_quiz(int total_questions = 10) {
using namespace std;
srand(static_cast<unsigned>(time(nullptr)));
int correct = 0;
for (int i = 0; i < total_questions; ++i) {
auto q = generate_question();
cout << q.left << ' ' << q.op_symbol << ' ' << q.right << " = ";
int user_answer;
cin >> user_answer;
if (user_answer == q.answer) ++correct;
}
double percentage = 100.0 * correct / total_questions;
cout << "\n正确率: " << fixed << setprecision(1)
<< percentage << "%\n";
}