【C++】机试刷题总结day11——二、枚举和模拟(下)map非线性数据结构

一、枚举和模拟(下)

模拟问题——非线性数据结构map

map词典

对比vector、set学习
可以通过下标访问元素,下标可以是任意类型,元素也可以是任意类型
打破了之前[整数]的限制
这里的下标叫键(key),元素叫值(value),键和值的组合叫键值对(pair)
可以通过key找到value

本质是集合,内容是键值对
分类

同set类比,底层一样
与set区别:set内是单个元素的集合,map内是键值对的集合

头文件

#include <map>
#include <unordered_map>

从2个维度划分:①有序②是否允许重复(对于键)

有序无序
不重复(对于键)mapunordered_map
可重复(对于键)multimapunordered_multimap

unordered_map常用,时间开销小

构建:

两个参数,<键类型,值类型>
pair<char, int> pair1 = {‘w’, 0};//是map的基本元素
pair的函数,first提取键,second提取值

	//构造
	//char是键类型,int是值类型 
	map<char, int> map1;//有序——>省空间,不省时间  不重复 
	multimap<char, int> map2;//有序,可重复
	unordered_map<char, int> map3;//无序,不重复   常用!!!!!时间开销小!!! 
	unordered_multimap<char, int> map4;//无序,可重复 
	
	//键值对
	pair<char, int> pair1 = {'w', 0};//是map的基本元素 
	//pair的函数,first提取键,second提取值
	printf("key  = %c, value = %d", pair1.first, pair1.second); 

增:

insert函数:只能插入键值对 ,用花括号括起来变成pair

	//新增
	//insert函数:只能插入键值对 
	map1.insert(pair1);
	map1.insert({'w', 1}); //插入key为w的值,没有效果 
	map2.insert(pair1);
	map2.insert({'w', 1});
	//map2.insert({'o', 1});//用花括号括起来变成pair 

删:

erase函数:参数只为键值(key)

	//删除
	//erase函数:参数只为键值 
	map1.erase('w'); //只删除1个键值对 
	map2.erase('w');//可以删除多个键值对 

查:

1、遍历

迭代器
it指向键值对——>用first和second提取
it是个指针——>用->运算符

	//查找 
	map<char, int> map1 = {
		{'w',0},{'o',1},{'r',2},{'l',3},{'d',4} 
	};//初始化的map
	//遍历:迭代器
	map<char, int>::iterator it;
	for(it = map1.begin(); it != map1.end(); it++){//end是尾后的位置,最后一个位置的后一个位置 
		printf("key = %c, value = %d\n", it->first, it->second);//it指向键值对——>用first和second提取,it是个指针——>用->运算符 
	} 
		//换成multimap
	printf("\n"); 
	multimap<char, int> map2 = {
		{'w',0},{'o',1},{'r',2},{'l',3},{'d',4} 
	};
	map2.insert({'o',5});
	multimap<char, int>::iterator it2;
	for(it2 = map2.begin(); it2 != map2.end(); it2++){//end是尾后的位置,最后一个位置的后一个位置 
		printf("key = %c, value = %d\n", it2->first, it2->second);//it指向键值对——>用first和second提取,it是个指针——>用->运算符 
	} 
2、查找

(1)通过key找对应的value
找key为o对应的值——>方括号运算符map1[‘o’]
如果访问的键不存在,会新增一个键值对,键为查找的’a’,值为默认初始值0
multimap不支持方括号运算符:因为一个key对应多个值
<1>map

	map<char, int> map1 = {
		{'w',0},{'o',1},{'r',2},{'l',3},{'d',4} 
	};
	
	//找key为o对应的值——>方括号运算符map1['o'] 
	printf("value = %d\n", map1['o']);
	//如果访问的键不存在,会新增一个键值对,键为查找的'a',值为默认初始值0 
	printf("value = %d\n", map1['a']);//查找结果为0,因为新增了键值对 

<2>multimap
通过迭代器访问返回的一堆value
lower_bound(key):返回key对应的第一个值的位置
upper_bound(key):返回key对应的最后一个值的后一个位置

与begin,end的区别:begin、end是整个容器;lower_bound和upper_bound是key对应的值起始和终止位置

	multimap<char, int> map2 = {
		{'w',0},{'o',1},{'r',2},{'l',3},{'d',4} 
	};
	map2.insert({'o',5});
	multimap<char, int>::iterator it2;
	for(it2 = map2.lower_bound('o'); it2 != map2.upper_bound('o'); it2++){
		printf("key = %c, value = %d\n", it2->first, it2->second);
	}

(2)如果不想新增,有才输出,没有报原因——>find函数或count函数

	//如果不想新增,有才输出,没有报原因——>find函数或count函数
	if(map1.find('a') == map1.end()){//说明a不存在 
		printf("key is not in map.\n");
	}else{
		printf("value = %d\n", map1['a']);
	}
	if(map1.find('o') == map1.end()){//说明a不存在 
		printf("key is not in map.\n");
	}else{
		printf("value = %d\n", map1['o']);
	}

改:

方括号运算符+赋值操作

	//5.修改
	//方括号运算符+赋值操作
	map1['o'] = 6;
	printf("value = %d\n", map1['o']);

例题1、手机键盘※※(完全没思考)

思路:

使用2个map
第一个map:记录每个字母的输入时间
键为char表示按键a-z,值为int表示输入时间

第二个map:判断是否为同一个数字键上,是则增加等待时间
键为键为char表示按键a-z,值为int表示在哪个按键

	//两个map
	//每个字母需要花费的时间
	map<char, int> inputTime = {
		{'a',1},{'b',2},{'c',3},
		{'d',1},{'e',2},{'f',3},
		{'g',1},{'h',2},{'i',3},
		{'j',1},{'k',2},{'l',3},
		{'m',1},{'n',2},{'o',3},
		{'p',1},{'q',2},{'r',3},{'s',4},
		{'t',1},{'u',2},{'v',3},
		{'w',1},{'x',2},{'y',3},{'z',4}
	}; 
	//每个字母在哪个按键
	map<char, int> keyMap = {
		{'a',2},{'b',2},{'c',2},
		{'d',3},{'e',3},{'f',3},
		{'g',4},{'h',4},{'i',4},
		{'j',5},{'k',5},{'l',5},
		{'m',6},{'n',6},{'o',6},
		{'p',7},{'q',7},{'r',7},{'s',7},
		{'t',8},{'u',8},{'v',8},
		{'w',9},{'x',9},{'y',9},{'z',9}
	}; 
关键点:用map把关键信息组织起来
易错点:

(1)向字符串数组写入时,不用加取地址符号,因为str本身就是指向数组的指针

	while(scanf("%s",str) != EOF){//这里不用加取地址符号,因为str本身就是指向数组的指针 

(2)

int lastKey = -1;//表示上一次的按键,-1表示之前没有输入

(3)查找用方括号运算符

			if(keyMap[str[i]] == lastKey){
代码:
#include <stdio.h>
#include <map>
using namespace std;

int main(){
	//两个map
	//每个字母需要花费的时间
	map<char, int> inputTime = {
		{'a',1},{'b',2},{'c',3},
		{'d',1},{'e',2},{'f',3},
		{'g',1},{'h',2},{'i',3},
		{'j',1},{'k',2},{'l',3},
		{'m',1},{'n',2},{'o',3},
		{'p',1},{'q',2},{'r',3},{'s',4},
		{'t',1},{'u',2},{'v',3},
		{'w',1},{'x',2},{'y',3},{'z',4}
	}; 
	//每个字母在哪个按键
	map<char, int> keyMap = {
		{'a',2},{'b',2},{'c',2},
		{'d',3},{'e',3},{'f',3},
		{'g',4},{'h',4},{'i',4},
		{'j',5},{'k',5},{'l',5},
		{'m',6},{'n',6},{'o',6},
		{'p',7},{'q',7},{'r',7},{'s',7},
		{'t',8},{'u',8},{'v',8},
		{'w',9},{'x',9},{'y',9},{'z',9}
	}; 
	
	//读取字符串
	char str[200];
	while(scanf("%s",str) != EOF){//这里不用加取地址符号,因为str本身就是指向数组的指针 
		int lastKey = -1;//表示上一次的按键,-1表示之前没有输入
		int totalTime = 0;//统计总时间
		for(int i = 0; str[i] != '\0'; i++){//遍历字符串 
			//判断是否等待
			if(keyMap[str[i]] == lastKey){//若本次与上次同一按键,则总时间+2!!!!!!!查找用方括号运算符 
				totalTime += 2;
			}
			totalTime += inputTime[str[i]];
			lastKey = keyMap[str[i]];//更新上次按键 
		} 
		printf("%d\n", totalTime);
	} 
	return 0;
}

模拟解题关键:判断用什么数据结构存储信息

  • 52
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值