哈希表
根据关键码的值而直接进行访问的数据结构。
哈希表的三种数据结构:1.数组 2.set集合 3.map映射
1.数组
出现频率最高的字母
题目描述
给定一个只包含小写字母的字符串,统计字符串中每个字母出现的频率,并找出出现频率最高的字母,如果最高频率的字母有多个,输出字典序靠前的那个字母。
输入描述
包含多组测试数据,每组测试数据占一行。
输出描述
有多组输出,每组输出占一行。
输入示例
2
abcdeef
aabbccddeeff
输出示例
e
a
import java.util.*;
public class Main{
//从字符串中找到出现频率最高的字母
public static char findMostFrequentChar(String str) {
int[] frequency = new int[26];//数组作为简单哈希表
char[] char_array = str.toCharArray();
//数组存储26个字母的出现频率
for(char c:char_array) {
frequency[c-'a']++;
}
int max = 0;
char maxchar = 'a';
for(int i = 0;i<26;i++) {
if(frequency[i]>max) {
max = frequency[i];
maxchar = (char)('a'+i);
}
}
return maxchar;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0;i<n;i++) {
String str = sc.next();
char maxchar = findMostFrequentChar(str);
System.out.println(maxchar);
}
sc.close();
}
}
2.set集合
在 Java 中,Set 是一种集合接口,和数学中的集合类似,它用于存储一组不重复的元素,并且不保证元素的顺序。查找通常是Set最重要的操作,它最常见的用法是判断某个对象是否在Set中和去除集合中的重复元素。
Set 接口的常见实现类包括 HashSet、TreeSet 和 LinkedHashSet,我们通常会选择HashSet作为实现。
HashSet的使用
使用集合前,需要用import语句导入 Set 接口以及它的实现类HashSet
import java.util.Set; // 导入Set
import java.util.HashSet; // 导入HashSet
set结构还提供了一些常见方法方便使用:
add(element):向集合中添加元素,如果元素已存在,则不会重复添加。remove(element):从集合中移除指定元素。contains(element):检查集合中是否包含指定元素。isEmpty():判断集合是否为空。size():返回集合中的元素数量。clear():清空集合中的所有元素。
遍历集合中的元素
1.增强 for 循环(for-each 循环)
// 遍历集合中的元素
for (String name : set) {
System.out.println(name);
}
2.迭代器(Iterator)是一种用于遍历集合类中的元素的接口。
迭代器提供了一种标准的方式来访问集合中的元素,无论集合的具体实现是什么,都可以遍历集合的元素,而不需要了解底层数据结构的细节。
通常,要使用迭代器,需要先获得集合的迭代器对象,使用集合的 iterator() 方法来获取这个迭代器对象,然后可以使用 hasNext() 方法检查是否还有元素,并使用 next() 方法获取下一个元素。
import java.util.HashSet;
import java.util.Iterator; // 需要引入Iterator接口
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> stringSet = new HashSet<>();
stringSet.add("zs");
stringSet.add("ls");
stringSet.add("Mike");
Iterator<String> iterator = stringSet.iterator(); // 获取集合的迭代器
while (iterator.hasNext()) { // 检查是否还有元素可迭代
String element = iterator.next(); // 获取下一个元素
System.out.println(element);
}
}
}
接口和实现类
Set 是一种集合接口,而HashSet是一种实现类。
接口是一种抽象数据类型,定义了一组抽象方法,但是方法通常不包含方法体,而只有方法的声明,主要是用来定义某种行为的规范,
而实现类是具体的类,它实现了一个或多个接口定义的抽象方法,并且提供了这些方法的具体实现。
判断集合成员
题目描述
请你编写一个程序,判断给定的整数 n 是否存在于给定的集合中。
输入描述
有多组测试数据,第一行有一个整数 k,代表有 k 组测试数据。
每组数据第一行首先是一个正整数 m,表示集合中元素的数量(1 <= m <= 1000)。
接下来一行包含 m 个整数,表示集合中的元素。
最后一行包含一个整数 n,表示需要进行判断的目标整数。
输出描述
包含多组输出,每组输出占一行。
如果集合中存在 m,输出“YES”,否则输出“NO”。
输入示例
2
5
1 2 3 4 5
3
6
1 2 3 4 5 6
7
输出示例
YES
NO
import java.util.Scanner;
import java.util.Set;//set接口
import java.util.HashSet;//set的实现类
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0;i<n;i++) {
int set_num = sc.nextInt();
//Set:接口 HashSet:实现类
Set<Integer> set = new HashSet<>();
//元素加入集合
while(set_num-->0) {
set.add(sc.nextInt());
}
//判断元素是否在集合中
if( set.contains(sc.nextInt()) ) {
System.out.println("YES");
}else {
System.out.println("NO");
}
}
}
}
3.map映射
我们常常把map称之为映射,就是将一个元素(通常称之为key键)与一个相对应的值(通常称之为value)关联起来,比如说一个学生的姓名(key)有与之对应的成绩(value),或者说一把钥匙(key)对应一扇门value, 键和值是一一对应的,在map中键是唯一的,也有一个唯一的与之对应的值。
HashMap的使用
在 Java 中,Map 是一种接口(java.util.Map),主要用于存储和管理键值对数据,使用Map可以方便的进行查找操作,Map 接口的常见实现类包括 HashMap、TreeMap、LinkedHashMap 等, 而HashMap(基于哈希表实现),通常是最常用的 Map 实现。
使用HashMap前需要导入对应的包文件。
import java.util.Map; // 引入 Map 接口
import java.util.HashMap; // 引入 HashMap 实现类
下面的代码示例展示了如何创建一个HashMap实例,需要指定键的类型和值的类型,键为String类型,而值为Integer类型。
// 创建一个HashMap实例,用于表示学生分数
Map<String, Integer> studentScores = new HashMap<>();
map结构还提供了一些常见方法方便使用:
put(key, value):将指定的键和值添加到map中,如果键已存在,则替换对应的值。get(key):根据key获取对应的值value。remove(key):根据key移除对应的键值对。containsKey(key):检查map中是否包含key键。containsValue(value):检查map中是否包含value值。keySet():返回包含所有键的集合。values():返回包含所有值的集合。entrySet():返回包含所有键值对的集合。
开房门
题目描述
假设你手里有一串钥匙,这串钥匙上每把钥匙都有一个编号,对应着一个房门的编号。现给你一个房门编号,你需要判断是否能够打开该房门。
输入描述
测试数据共有多组。
第一行为一个整数 s,表示共有多少组测试数据。
每组第一行有一个整数 n,表示钥匙串上有多少把钥匙。
后面共有 n 行输入,每行两个整数,第一个整数 k 表示钥匙编号,第二个整数 d 表示房门编号。
最后一行有一个整数 x,表示需要打开的房门编号。
输出描述
输出多组,每组占一行。 如果能打开,则输出钥匙编号,不能打开则输出“Can't open the door.”。
输入示例
2
5
878788 9373833
837837 3837378
378338 3398939
388733 2329389
878373 3938399
3938399
3
998389 3892393
444323 3892783
883782 5334332
8739833
输出示例
878373
Can't open the door.
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0;i<n;i++) {
Map<Integer,Integer> map = new HashMap<>();
int num = sc.nextInt();
//door是键,key是值,输入键值对
while(num-->0) {
int key = sc.nextInt();
int door = sc.nextInt();
map.put(door,key);
}
Integer find_door = sc.nextInt();
//找到find_door对应的value(钥匙编号)
if(map.containsKey(find_door)) {
System.out.println(map.get(find_door));
}else {
System.out.println("Can't open the door.");
}
}
}
}
1381

被折叠的 条评论
为什么被折叠?



