当前位置:首页 > 技术 > 正文内容

STL算法实践:容器操作与数值计算

访客 技术 2026年6月3日 1

字符串反转与旋转操作

标准库提供了多种用于调整元素顺序的算法。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::tolowerstd::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";
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。