有趣的Trie

在这里插入图片描述

题目:洛谷 P2580 于是他错误的点名开始了

题目描述
这之后校长任命你为特派探员,每天记录他的点名。校长会提供化学竞赛学生的人数和名单,而你需要告诉校长他有没有点错名。(为什么不直接不让他玩炉石。)

输入格式
第一行一个整数 n,表示班上人数。接下来 n 行,每行一个字符串表示其名字(互不相同,且只含小写字母,长度不超过 50)。第 n+2 行一个整数 m,表示教练报的名字。接下来 m 行,每行一个字符串表示教练报的名字(只含小写字母,且长度不超过 50)。

输出格式
对于每个教练报的名字,输出一行。如果该名字正确且是第一次出现,输出“OK”,如果该名字错误,输出“WRONG”,如果该名字正确但不是第一次出现,输出“REPEAT”。(均不加引号)

输入样例:
5
a
b
c
ad
acd
3
a
a
e
输出样例:
OK
REPEAT
WRONG

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

static int tot = 0;//类似内存的东西,表示trie的大小

static Node node[]; //字典树

//对于java来说大量的IO会加大开销,所以将结果存起来,最后在一起输出
static StringBuffer sb = new StringBuffer();

static class Node {
	int next[] = new int[26];  //保存该节点的26个字母
	boolean isDanci, isVisit; // isDanci是否单词结尾,isVisit如果是单词,是否被访问过

}

static void insert(char c[]) {

	int p = 0; //从根节点出发
	
	//遍历
	for (int i = 0; i < c.length; i++) {
		//查看当前节点的c[i]-'a'是否存在
		int next = node[p].next[c[i] - 'a'];
		
		//为0则表示不存在,需要生成
		if (next == 0) {
			
			//生成该节点
			next = node[p].next[c[i] - 'a'] = ++tot;
			node[tot] = new Node();
		}
		//修改当前节点
		p = next;
	}

	//在结尾位置加上单词标记
	node[p].isDanci = true;

}

static void query(char c[]) {
	int p = 0;

	for (int i = 0; i < c.length; i++) {
		
		int next = node[p].next[c[i] - 'a'];
		
		//如果该位置不存在,则证明单词不在树中
		if (next == 0) {
			sb.append("WRONG" + "\n");
			return;
		}
		p = next;
	}
	
	//到了结尾,但是该位置没有单词标记,也证明单词不在树中
	if (!node[p].isDanci) {
		sb.append("WRONG" + "\n");
		return;
	}

	//如果访问过
	if (node[p].isVisit) {
		sb.append("REPEAT" + "\n");
		return;
	}

	sb.append("OK" + "\n");
	//设置访问过的标记
	node[p].isVisit = true;
}

public static void main(String[] args) throws IOException {
	BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	int n = Integer.parseInt(reader.readLine().trim());

	//大小要根据题目所定,题目表示每个单词不超过50,所以考虑最坏的情况,50*n+1,+1是给根节点
	node = new Node[n * 50 + 1];

	//初始化根节点
	node[0] = new Node();
	
	//初始化字典树
	for (int i = 0; i < n; i++)
		insert(reader.readLine().trim().toCharArray());

	int m = Integer.parseInt(reader.readLine().trim());
	
	//查找字典树
	for (int i = 0; i < m; i++)
		query(reader.readLine().trim().toCharArray());
	
	//输出结果
	System.out.println(sb);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值