IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 例题5-4反片语 UVa156--C++STL库映射map的应用 -> 正文阅读

[C++知识库]例题5-4反片语 UVa156--C++STL库映射map的应用

前言

从今天起,不定期更新C++的STL库以及算法练习的笔记
分享给大家 也是督促自己不断努力学习算法
学习算法之前,要想高效简洁的写好代码,还需要熟练掌握STL库的一些方法和数据结构
参考书籍:
《算法竞赛入门经典》(第2版)刘汝佳 著
《挑战程序设计竞赛》巫泽俊 主译
我的笔记和题目将以上两本书中内容精华进行整合,练习题目会依据书后习题从oj,poj等平台选取


一、题目描述

输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本中的另外一个单词。在判断是否满足条件时,字母不分大小写,但在输出时应保留输入中的大小写,按字典序进行排列(所有大写字母在所有小写字母的前面)
Sample Input
ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb eye Rides dealer NotE derail LaCeS drIed
noel dire Disk mace Rob dries
#
Sample Output
Disk
NotE
derail
drIed
eye
ladder
soon
注:文末附有原版英文题目

二、思路分析与代码书写

1.映射map

map就是从键(key)到值(value)的映射。在离散数学中我们学习过单射(x满y可以不满 一对一)、满射(x满y满允许多对一)以及一一映射(二者的结合),这里我们是一一映射。
如用map<string,int>week_name来表示“星期名字到星期编号”的映射,然后用week_name["Monday"]=1来赋值。(参考刘汝佳老师的讲解)
实际应用中,map更多的用在不同类型一对一的计数或者二叉搜索树。
如果对map的使用不熟练,或者第一次接触,可以看这一篇文章:
C++STL映射map用法

2.题目思路分析

因为只要字母重排与另一个单词一致即可算重复了,则我们可以使用map构造单词字母序列与出现次数的映射。map<string,int> cnt
之后可以通过cnt[这个单词的字母序列]++来对每个序列计数
最终我们需要输出的就是计数结果为1的那些字母序列对应的原单词

除了映射,因为题目中没有给出输入单词的数量(也没有允许用户自己决定),故我们还需要一个不定长数组vector来对输入的单词进行存储。想到这里,自然会想到输出的单词数量也是未知的,因此再用一个vector专门保存输出的答案。

由此我们意识到,需要专门定义一个函数,对每一个输入的单词进行“标准化”。将单词先全部转化为小写字母,再对所有字母进行排序,得到字母序列。

最后我们根据映射的结果,找到对应的原单词并输出即可。

3.完整代码书写

该代码参考刘汝佳老师书上的代码,自己根据思路独立完成,可能细节上与老师略有不同。

首先是头文件,一个都不能少。(实际写代码过程中可能是边写边添加的)

#include<iostream>
#include<algorithm>
#include<map>
#include<string>
#include<cctype>
#include<vector>

其中cctype提供tolower()函数
algorithm提供sort()函数

采用自顶向上的写法,先写主函数
先搭好框架:

int main()
{
	string s;//每次接一个单词进入程序
	while(cin>>s){
		
		words.push_back(s);
		
		if()cnt[字母序列]=0;//如果首次出现该单词(的字母序列),初始化
		cnt[字母序列]++;//该单词(的字母序列)次数+1 
	} 
	
	vector<string> ans;//存储所有答案单词
	for(int i=0;i<words.size();i++){
		
	} 
	sort(ans.begin(),ans.end());//按字典序对所有答案进行排序
	for(int i=0;i<ans.size();i++)cout<<ans[i]<<endl; 
	return 0;
}

再完善细节:

int main()
{
	string s;//每次接一个单词进入程序
	while(cin>>s){
		if(s[0]=='#')break;//所有单词输入完毕,退出输入的循环 
		words.push_back(s);
		string r=repr(s);//对单词进行标准化
		if(!cnt.count(r))cnt[r]=0;//如果首次出现该单词(的字母序列),初始化
		cnt[r]++;//该单词(的字母序列)次数+1 
	} 
	
	vector<string> ans;//存储所有答案单词
	for(int i=0;i<words.size();i++){
		if(cnt[repr(words[i])]==1){//该单词(的字母序列)只出现了一次 
			ans.push_back(words[i]);//则该单词为答案 
		}
	} 
	sort(ans.begin(),ans.end());//按字典序对所有答案进行排序
	for(int i=0;i<ans.size();i++)cout<<ans[i]<<endl; 
	return 0;
}

最后实现标准化一个单词的函数:

string repr(const string& s)
{
	string newWord=s;
	for(int i=0;i<newWord.length();i++){
		newWord[i]=tolower(newWord[i]);
	}
	sort(newWord.begin(),newWord.end());//注意string类型排序方式
	return newWord; 
} 

这里传入参数是一个const常量,主要是为了强调不修改原单词,而是生成一个新的字母序列在主函数中用于计数。
另外关注一下单个字符串如何使用sort排序。.begin()和.end()在algorithm里也包含。


附:UVa156原题:

在这里插入图片描述

最后几句话

映射有着其一对一这一独特的特性,因此在许多竞赛和练习中应用广泛。
使用时务必记得头文件#include<map>

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 12:34:13  更:2021-07-30 12:35:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 0:53:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码