c++ primer案例学习

本文详细介绍了C++中的泛型算法,如消除重复单词的elimDups函数,以及通过稳定排序实现先按长度再按字典序排序的newElimDups函数。此外,还讲解了如何利用关联容器map进行单词转换,包括读取规则文件、构建映射以及实际的转换操作。示例中展示了如何处理文件输入流,并提供了biggies函数用于查找满足特定长度条件的单词。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第十章 泛型算法

消除重复单词
sort函数在头文件中,排序规则为字典序排序。

void elimDups(vector<string> &vec)
{
	sort(vec.begin(), vec.end());
	auto end_unique = unique(vec.begin(), vec.end());
	vec.erase(end_unique, vec.end());
}
// 重新排序,排序规则为先按大小排序,大小相同的按字典序排序。
bool isShorter(const string &s1, const string &s2)
{
	return s1.size() < s2.size();
}
 
void newElimDups(vector<string> &vec)
{
	elimDups(vec);
	stable_sort(vec.begin(),vec.end(),isShorter);
}
/*
* 求大于等于一个给定长度的单词有多少
*/

#include<algorithm>
using namespace std;


void elimDups (vector<string> &words)
{
    // 先排序,以便查找重复单词,sort默认按照字典排序
    sort(words.begin(), words.end());
    // unique重排输入范围,使得每个单词只出现一次
    // 排列在范围的前部,返回指向不重复区域之后一个位置的迭代器
    auto end_unique = unique(words.begin(), words.end());
    // 使用向量操作erase删除重复单词
    words.erase(end_unique, words.end());
}

void biggies (vector<string> &words, vector<string>::size_type sz)
{
    elimDups(words); // words按字典排序,删除重复单词
    // 按照长度排序,长度相同的维持字典序
    stable_sort(words.begin(), words.end(),  // stable_sort 维持相等元素原有顺序
                [](const string &a, const string &b) 
                    { return a.size() < b.size();});
    auto wc = find_if(words.begin(), words.end(),  // find_if查找第一个具有特定大小的元素,返回指向该元素的迭代器
                      [sz](const string &a) 
                      { return a.size() >= sz;});
    // 计算满足size >= sz的单词数目
    auto count = words.end() - wc;
    // 打印长度大于等于sz的单词,每个单词后面接一个空格
    for_each(wc, words.end(),
             [] (const string &s) {cout << s << " " ;});
    cout << endl;
}

第十一章 关联容器

一个单词转换的map
c++ primer P391,第11章
在这里插入图片描述
在这里插入图片描述组织结构:
在这里插入图片描述
main.cpp

//
// Created by j on 2021/9/25.
//

#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <sstream>

using namespace std;

//单词转换函数
const string word_Transform(ifstream &map_file, ifstream &input);
//读入规则文件,生成对应的map映射
map<string, string> buildMap(ifstream &map_file);
//转换操作
const string &Transform(const string &word, const map<string, string> &map);

int main()
{
    ifstream file_stream("D:\\code\\clion_Project\\files\\file.txt"); //待转换的文件,ifstream从文件中读取数据
    ifstream map_stream("D:\\code\\clion_Project\\files\\rule.txt");  //规则文件,创建文件流并与文件绑定
    const string result = word_Transform(map_stream, file_stream);
    cout << result;
    return 0;
}

const string word_Transform(ifstream &map_file, ifstream &input)
{
    string result = "";
    map<string, string> trans_map = buildMap(map_file); // 用map抽象文件的翻译规则
    string line;
    // 每次读入一行待转换的文本
    while (getline(input, line)) {
        stringstream ss(line); // 创建istringsteam对象,从string对象中读入数据
        string word;
        bool first_word = true; // 控制是否打印空格
        // 每次取这行文本中的一个单词
        while (ss >> word) {
            if (first_word) {
                first_word = false;
            }
            else {
                result += " "; // 在单词间打印一个空格
            }
            // 转换每个单词
            result += Transform(word, trans_map);
        }
        result += '\n';
    }
    return result; // 完成一行的转换
}

// 读入规则文件,生成对应的map映射
map<string, string> buildMap(ifstream &map_file)
{
    map<string, string> trans_map; //保存转换规则的map
    string key;                    //键
    string value;                  //值
    string line;
    // 读取第一个单词到key,剩下的所有内容读入value
    while (map_file >> key && getline(map_file, value)) {
        if (value.size() > 1) { // 如果有一个号码则大于1(空格加一个有效的号码)
            trans_map[key] = value.substr(1); // 跳过前导空格(getline会读入前面的空格,遇到换行符结束)
        }
        else {
            throw runtime_error("no rule for " + key);
        }
    }
    return trans_map;
}

//转换操作
const string &Transform(const string &word, const map<string, string> &map)
{
    auto map_iter = map.find(word);
    if (map_iter != map.cend()) {
        return map_iter->second;
    } else {
        return word;
    }
}

rule.txt:

brb be right back
k okay?
y why
r are
u you
pic picture
thk thanks!
18r later

file.txt:

where r u
y dont u send me a pic
k thk 18r

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值