6.28
一.最大字母出现次数
1.哈希表的使用
#include< unordered_map>
建立:unordered_map<char, int> Hash;
//建立一个键为char,值为int的Hash表
初始化:Hash.insert(make_pair((char)i, 0));
//插入数据,其中make_pair()意思是让后边的数据作为一个整体。
遍历:
for (auto h : Hash)
{
char c = h.first;
//first代表哈希表的键 int n = h.second;
//second代表哈希表的值 }`
查找:Hash.find(“需要查找的键”)
如果需要返回是否得到结果,则加上:
if (Hash.find(s.at(i)) != Hash.end())//找到了数据
第二种查找方法:
Hash.count('a')
//若Hash表中含有a则返回1否则返回0
赋值:Hash[“键的名字”]="赋给它的值"
其他函数:
m.size() //返回哈希表的大小
m.empty() //判断哈希表是否为空,返回值为true/false
m.clear() //清空哈希表
二.输出成绩
1.动态创建数组
int *grade=new int[n];
//其中n可以后边输入或者定义
使用完数组之后记得清除空间
delete []grade;
2.需要整数相除得到小数时需要类型向上转
double = int 再用 double 相除
结果设置精度:
#include <iomanip>
<<setprecision(2)<<"输出的数据"
三.千年难遇的日子
1.int转字符串 to_string
string s=to_string("int a");
2.字符串常用函数
`string.find("输入要查找的字符串,如果有则返回出现的下标否则-1") string.insert("向指定位置插入字符串")
string.substr(”截取字符串 start 起点(包含),num 字符个数)//若仅一个参数i 则代表从该倒数i第一直到结尾的字符串
string.replace(“替换字符串)
string.at('获取目标字符的下标,没有则返回-1')
string rs = s.substr(4, 4); rs.reserve();//reverse没有返回值 直接对原字符串进行操作
6.29
一.门牌制作
1.提取数字中各位想要的数字(eg 提取数字2)
(1)字符串提取:
s=to_string(int); char aim='目标字符';
for (int i = 0; i < s.length(); i++)
{
if (s.at(i) == aim)count++;
}
(2)逻辑运算:
int num = 0;
for (int i = 1; i <= 2020; i++) { if (i % 10 == 2) num++;//提取个位 if (i / 10 % 10 == 2) num++;//提取十位 if (i / 100 % 10 == 2) num++;//提取百位 if (i / 1000 == 2) num++;//提取千位 }
二.卡牌排序
1.char 转int(数字转换 不是ASSCII码)
string s="10086"; 0<=i<=s.length()
int index = s.at(i)-'0';
2.String 转 int
string a = "123"; int num = atoi(a.c_str());
三.🗡☞Offer字符串
字符串函数概述:
1.将字符串str中的空格换成%20
(1)使用string的replace函数 第一个参数为替换的位置 第二个参数为替换的部分长度 第三个参数为替换的字符串
for (int i = 0; i < str.length(); i++) { char aim = ' '; string result = "%20"; if (str.at(i) == aim) str.replace(i,1,result); } return str; }
(2)不使用函数
原理:由于c++中string 对象是可以修改的,所以先找到所有空格的位置然后将需要的字符串添加进去。
2.左旋字符串若干位到右边
(1)使用库函数 略,直接substr()截取再append()就完事了
(2) 使用翻转的思想,来自句子翻转单词灵感 :
this is a new stage->egats wen a si siht
再将每一个单词翻转:
stage new a is this
就完成了句子单词的翻转。
同理对于一个字符串也可以:
string s2="需要转换得到字符串" reverse(s2.begin(),s2.end() );//第一步反转 所有字符 reverse(s2.begin(), s2.end() - n);//反转 reverse(s2.end() - n, s2.end()); cout << s2;
对于reveres的使用,需要传入字符串的起止位置与结束位置即可。
//char 转 string: string s; char a='a'; s.append(1,a);
8.11
一.IP换算
输入字符串判别是非为IPv6或者IPv4,若均不是则返回Neither
IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1; 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
(1).判别split后是否存在,看返回值 若为-1则表示不存在
(2).判别字符串是否为数字
char c = s[i].charAt(j); if (c < '0' || c > '9') return false;
(3).字符转数字
num = num * 10 + (int)(c - '0');
(4).判别是否为字母
boolean expr = ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ;
(5).进行字符串分割时 "."不能直接写 要进行转义 "\." 不要写反了
String test1="256.256.256.256"; String[] split = test1.split("\\.");
(6)天坑题 1:2:3:4:5:6:7:8: 最后多了个:为无效 要考虑进去
尤其是分割类的题目 按照特定条件进行分割,出现边界要进行判断,非法字符串但能的到合法结果
二.告警抑制__遍历Hashmap以及remove注意事项
(1)注 : 我们不能在遍历Map时使用map.remove()方法 , 否则就会抛出异常 :
可以使用迭代器进行删除 iteRator.remove();
(2)hashmap使用
创建:HashMap map=new HashMap<>();
插入键值:map.put(key,value);
获取:
map.get(key);
判别是否含有键:
boolean b=map.containsKey(key)
遍历:
Set set = map1.entrySet(); Iterator iter = set.iterator(); while (iter.hasNext()) { Map.Entry entry=(Map.Entry) iter.next(); Object key=entry.getKey(); //获取键 Object value=entry.getValue();//获取值 }
删除:
map.remove(key)
排序:
更新:
map.put(key,newVal)
三.排序
1.身高排序2550__自定义比较器
对类中的某一项进行排序
自定义分类器:
**注意:自定义Hash表的比较器(==分类器)时
输入的顺序与看到的顺序不是一致的当比较的值一样时候(由于是链式存储)
比如:abc 13 bca 13 djk 13
若按照值排序 且相等返回0 应该是原来的顺序
但是 链式存储 输入后的顺序被打乱了 “原来的顺序也就是乱的”
但是不相等的情况 升降排序还是没有问题 或者相等时指定键的位置也可以避免这种情况
class AgeComparator implements Comparator<Person> { public int compare(Person object1, Person object2) {// 实现接口中的方法 //return new Integer(object1.getHeigh()).compareTo(object2.getHeigh()); //上诉是:若只需要按照某一项进行排序eg height if (object1.heigh== object2.heigh) return new Integer(object1.getWeight()).compareTo(object2.getWeight()); else return new Integer(object1.getHeigh()).compareTo(object2.getHeigh()); //注意 compareTo方法 是返回一个值 大于0表示前者大于后者(降序排列) 小于1是后者大于前者(升序排列) (注意相等的情况) //return 0时 不对原来的集合对应元素做处理 } }
ArrayList<Person> people=new ArrayList<>();//创建集合然后将类对象装入集合中去 再调用Collections.sort 即可 AgeComparator comparator=new AgeComparator();//比较器 Collections.sort(people,comparator);//集合调用 for (Person p:people//查看结果 ) { System.out.println(p.lable); }
class comparePeople implements Comparator<people>//比较器 降序排列时 { public int compare(people p1,people p2) { if (p1.height==p2.height) { // return new Integer (p1.wight).compareTo(p2.wight); return p1.wight>=p2.wight?-1:1; } else //return new Integer (p1.height).compareTo(p2.height); return p1.height>p2.height?-1:1; }
2.拔河__控制输入
while (scanner.hasNextLine()) { String s1=scanner.nextLine(); if (s1.equals(""))//输入任意行 当输入为空行时结束 break; final String[] s2 = s1.split(" "); int height=Integer.valueOf(s2[0]); int weight=Integer.valueOf(s2[1]); list.add(new people(height,weight)); }
3.根据哈希表的值进行排序/键进行排序 以及entry的使用
//自定义比较器 class compareDesk implements Comparator<Map.Entry<String,Integer>> //对键值对进行排序设定 按照值还是键可以自定义 { public int compare(Map.Entry<String,Integer> entry1, Map.Entry<String,Integer> entry2) { return new Integer (entry1.getValue().compareTo (entry2.getValue()));//按照值进行排序 // return new Integer (entry1.getKey().compareTo (entry2.getKey()));按照键进行排序 } }
//使用哈希map的情况 先将Hashmap转换成Entry集合 然后将集合转为list再传入collection进行sort排序 HashMap<String,Integer> mapp=new HashMap<>(); //初始化 HashMap 略去 Set<Map.Entry<String, Integer>> entries = mapp.entrySet(); List<Map.Entry<String, Integer>>list1=new LinkedList<>(entries); Collections.sort(list1,new compareDesk()); //直接使用Entry的情况 list直接add ArrayList<Map.Entry<String,Integer>> list=new ArrayList<>();//Entry 集合 Map.Entry<String,Integer> map=new AbstractMap.SimpleEntry<>(temp,store);//初始化一个Entry list.add(map); Collections.sort(list,new compareDesk()); for (Map.Entry<String,Integer> a:list ) { System.out.println(a.getKey()); }
Array 进行自定义数组排序 也可以是二维数组 注意Integer不是int 以及重写compare可以写在方法里面new 里面 Integer []arr={23,23,4,1,5}; Arrays.sort(arr,new Comparator <Integer>(){ public int compare(Integer a,Integer b) { return a>=b?-1:1;//降序 return a>b?1:-1;//升序 } });
4.括号检查__栈的应用 *
匹配括号可以借用 hash表
认真读题,先思考好问题的关键,比如嵌套的判定
写好注释
5.篮球比赛
题目完善——当输入需要上次记录但是没有时 直接输出-1;
统计数组 更简洁
while (!stack.isEmpty()){ sum += stack.pop();
6.仿lisp计算
在题目的例子下 自己再给出两三个测试案例
split方法只能去除一个空格,而不能去除多个空格 但可以使用split然后再将分出的数组中为 空的进行改变->error进行标识
遍历后排除error 使用
7.找车位 *注意距离而不是空位数
事先举出所有的例子,包括所有特殊情况
逻辑清楚 返回两个最大-> 二元表达式 或者math.max(int a,int b);
maxDistence = maxDistence > ((i- lastCar) / 2) ?maxDistence : ((i - lastCar) / 2); //或者 maxDistence=Math.max(maxDistence,(i-lastCar)/2);
8.找和的绝对值最小的两个数 *非要从大到小排序(之和一样情况下 去绝对值大的两个数)
if (Math.abs(input[i]+input[j])==min) //相等时的情况 11 -11 222 -222 取后者 { if (Math.abs(input[i])+Math.abs(input[j])>Math.abs(one)+Math.abs(two)) { one=Math.min(input[i],input[j]); two=Math.max(input[i],input[j]); } }
9.求有效子字符串 *子串必须 含有两个连续字母??
复习:求一个字符串的子串
所有子串:利用00000-11111特性
eg:1abcde
连续子串:双指针加substring
eg:1abcde
public static void founction2(String input,int n) { for (int i = 0; i < n; i++) { for (int j = i+1; j < n+1; j++) { System.out.println(input.substring(i,j)); } } }
10.位运算
eg :abc
数字 二进制 子串 0 000 "" 1 001 "c" 2 010 "b" 3 011 "bc"
一定要注意题目中非法的情况 一定要注意题目中非法的情况 一定要注意题目中非法的情况
有限处理非法情况 eg 返回-1等
11.输入变换函数 Arrays.mapToInt
String caces[]={"2","32","4"}; int[] ints = Arrays.stream(caces).mapToInt(Integer::parseInt).toArray(); //可用于 划分为数字的字符串数组 6 15 3 4 5 7 9 10 23/5==5
12.食堂供餐* 解决问题方法:1. 直接法:直接找到(算出)目标 2.穷举法或逼近法 间接得到答案
先找到最小的出餐速度,然后看每小时吃的人够不够,不够直接出餐速度加1
然后再次遍历每小时的人数
13.开放日活动 逆天 注意查看 要求输出有没有空格 //90分
数组统一填充:
int put[]=new int [6]; Arrays.fill(put,6);
12 .消消乐 读取矩阵 DFS
Scanner scanner=new Scanner(System.in); int matrixRows= scanner.nextInt(); int matrixCols= scanner.nextInt(); int matrix[][]=new int[matrixRows][matrixCols]; for (int i = 0; i < matrixRows; i++) { for (int j = 0; j < matrixCols; j++) { matrix[i][j]= scanner.nextInt(); } }
boolean b[][]=new boolean[2][2]; 默认全是false
方向数组与xy轴上有区别 数学上:x,y->x+1,y 数组上:x,y->x,y+1 int [][]nextDirections={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};//八个方向上检测
13.广播服务器
DFS 的套路 关键 设置边界条件 优化 设置已经访问过的路 必要 方向数组,然后遍历 控制输入 错误做法 while (scanner.hasNextLine()) { if (scanner.nextLine().equals(" "))//错误 应该是""null 而不是" "空 break; list.add(scanner.nextLine());//错误 应该使用一个String 暂存 而不是再次调用scanner.nextLine 正确做法 while (scanner.hasNextLine()) { String temp=scanner.nextLine(); if (temp.equals("")) break; list.add(temp); } 6 1 3 15 () 1 20 (2) 2 10 (3,4) 4 23 (5,6,7) 6 10 () 7 10 ()
14.文件目录大小
Arrays.stream(split).mapToInt(Integer::parseInt).toArray();如何处理有空白的情况 //先把”“ 去掉 记得使用equals 而不是== if (split.length>=1&&!split[0].equals("")) { int[] sonFiles = Arrays.stream(split).mapToInt(Integer::parseInt).toArray(); map.put(fileCode, new file(fileSize, sonFiles)); }
15.挖矿 作用域问题 方法可以修改数组但是不能修改变量 除非是全局变量
int c=10; f1(c); System.out.println(c); public static void f1(int count) { count=count+10; } 输出结果是10 而不是20 public void f1(int x) { x=x+1; } public void f2(int x[]) { x[0]=1; x[1]=0; } f1 对x的修改无效 f2对x的修改有效 复制粘贴时注意所有参数需要改变的地方一定要修改 5 5 1 2 3 5 7 9 14 16 15 18 8 10 8 7 8 11 14 8 9 10 3 5 7 7 4
16.机器人走格子 审题 *机器人可以从任何地方开始走
17.linux 发行版关联数量
18.模拟—密码字符串替换 动态修改字符串 拼接技术
sb题
19.BFS算法
队列的使用 没有专门的Queue 可以使用Linkedlist
public class Queue_Exercise { public static void main(String args[]) { // 创造一个实例对象 Queue<Integer> queue = new LinkedList<>(); // 入队操作(尾插法) offer() 添加元素 queue.offer(1); queue.offer(2); queue.offer(3); // 出队操作 poll() 返回队首元素并删除 queue.poll(); queue.poll(); // 输出队首元素 peek() 返回队首元素不删除 System.out.println(queue.peek()); //判断队列是否为空 isEmpty() System.out.println(queue.isEmpty()); } }
20 DP问题 打家劫舍
填充任意数组为0 初始化后不设置值 则默认为0 左闭右开 int array[]={2,3,4,6,4,3}; int a2[]=Arrays.copyOfRange(array,0,3); int a3[]=Arrays.copyOfRange(array,1,4); //a2->2 3 4 //a3->3 4 6
21.火星改造 BFS多源问题 与LeeCode 994. 腐烂的橘子 类似
YES YES NO NA NO NO NO NO NA NA YES NO NO NO YES
重大失误 第二次
BFS与DFS中 for 循环 中的变量不要再外边int 不然循环中会出现累加效应
int x=needCope.peek().x; int y=needCope.peek().y; for (int next[]:Directions //错误 每次会进行累加 导致结果错误 ) { int x=x+next[0]; int y=y+next[1]; } for (int next[]:Directions //正确 ) { int x=needCope.peek().x+next[0]; int y=needCope.peek().y+next[1]; }
22.网络信号衰减
//新建数组 new int[]{2,6}
一维延伸成二维数组
//0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 //matrix[6][5]二维 split2[]一维 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j]=split2[i*cols+j];//6 5 } }
5 720 120
840 120
320 100
320 89
777 100
23.种树 从某个区间中找到某一个值 可以考虑二分查找 然后加上一个判断函数
24.下棋 关于离中间近的判断 cao 6子棋特殊情况
25.回文子串
StringBuffer并没有重写equals方法!!!