本文背景
博主是一名正在留学的大三学生,因学校毕业要求,需要60天的工作实习,因而趁着假期,在国内的一个科技公司体验实习生活。
前几日再查资料的时候无意中看到一篇关于网易校招的Java面试题的博文,虽然时间已经有些陈旧,但是文章对我这种初出茅庐的菜鸟还是很受用的。链接如下:http://blog.youkuaiyun.com/liu_005/article/details/52267538.
看完了之后,博主开始查找资料,希望可以做一些相关联系,于是就有了下面的关于字典树的训练。
这次训练是博主第一次写字典树,也是参考了百度百科关于字典树的介绍之后才开始编写的(字典树百度百科),一定有不足的地方,希望各位前辈多多留言指教了!
字典树编程
设计
字典树第一版主要实现:插入,删除, 查询,和重置的4块功能。
效果实现
因为是练手之作,所以所有的效果实现均由console完成。
模块
模块分为3部分:字典树,字典树测试,字典树节点
代码
TireTreeNode:(字典树节点)
package tireTreeDemo;
/**
* This is the demo for tireTree
* @author Andy_ZhangZX
* date(dd/mm/yy): 12/01/2018
*/
public class TireTreeNode {
//define the parameters inside the tree node
protected char value;
protected TireTreeNode[] children;
protected boolean isbuttom;
protected int counter; // calculate how many times that the String go through this node
protected final int SIZE = 26;
//constructor
public TireTreeNode(){
this.counter = 1;
this.children = new TireTreeNode[SIZE];
this.isbuttom = false;
this.value = 0;
}
}
TireTree:(字典树)
package tireTreeDemo;
/**
* This is the demo for tireTree
* @author Andy_ZhangZX
* date(dd/mm/yy): 12/01/2018
*/
public class TireTree {
protected TireTreeNode root; //the root of the tire tree
//constructor
public TireTree(){
root = new TireTreeNode();
}
public void insert(String string){
int stringLength = string.length();
TireTreeNode node = root;
char[] letters = string.toCharArray();
if(string == null || string.length() == 0) return;
for(int i = 0; i < stringLength; i++){
int position = letters[i] - 'a'; //use the ASCII code
if(node.children[position] == null){
node.children[position] = new TireTreeNode();//if not exist, create one
node.children[position].value = letters[i];
}else{
node.children[position].counter++;//if exist, update the counter
}
node = node.children[position];
}
node.isbuttom = true;
}
public void delete(String string){
int stringLength = string.length();
TireTreeNode node = root;
char[] letters = string.toCharArray();
if(string == null || string.length() == 0) return;
for(int i = 0; i < stringLength; i++){
int position = letters[i] - 'a'; //use the ASCII code
if(node.children[position].counter > 1){
node.children[position].counter--;
}else{
node.children[position].counter--;
node.children[position].value = 0;
}
node = node.children[position];
}
node.isbuttom = false;
}
public boolean isContain(String string,TireTree tree) throws Exception{
try{
TireTreeNode node = root;
int counter = 0;
char[] stringToArray = string.toCharArray();
int[] stringNum = new int[string.length()];
boolean isbuttom = false;
for(int i=0;i <stringToArray.length;i++){
stringNum[i] = stringToArray[i] - 'a';
}
for(int j = 0;j<stringToArray.length;j++){
if(node.children[stringNum[j]].value == stringToArray[j]){
isbuttom = node.children[stringNum[j]].isbuttom;
counter++;
node = node.children[stringNum[j]];
}
}
if(counter == stringToArray.length && isbuttom == true){
return true;
}else{
return false;
}
}catch(Exception e){
return false;
}
}
}
TireTreeTest:(字典树测试<main>)
package tireTreeDemo;
import java.util.Scanner;
/**
* This is the demo for tireTree
* @author Andy_ZhangZX
* date(dd/mm/yy): 12/01/2018
*/
public class TireTreeTest {
@SuppressWarnings("resource")
public static void main(String[]args) throws Exception{
TireTree tree= new TireTree();
initTree(tree);
Scanner s = new Scanner(System.in);
while(true){
String inPut = s.nextLine();
String[] inputArray = inPut.split(" ");
if(inputArray.length > 2){
System.err.println("Wrong input");
printUsageMessage();
}else{
if(inputArray[0].equals("+")){
insertMethod(inputArray[1],tree);
}else if(inputArray[0].equals("-")){
deleteMethod(inputArray[1],tree);
}else if(inputArray[0].equals("?")){
printSearchResult(inputArray[1],searchMethod(inputArray[1],tree));
}else if(inputArray[0].equals("~")){
tree = resetMethod(tree);
initTree(tree);
}else{
System.err.println("Wrong input");
printUsageMessage();
}
}
}
}
//initialize tire tree
private static void initTree(TireTree tree){
String[]strs= {"apple","bus","cat","dog"};
for(String str:strs){
tree.insert(str);
}
}
//deleteMethod
private static void deleteMethod(String string, TireTree tree) throws Exception{
if(searchMethod(string,tree)){
tree.delete(string);
}else{
System.err.println("The word \"" + string+"\" is not exsit!");
}
}
//insertMethod
private static void insertMethod(String string, TireTree tree) throws Exception{
tree.insert(string);
}
//searchMethod
private static boolean searchMethod(String string, TireTree tree) throws Exception{
boolean isContain = tree.isContain(string,tree);
if(isContain == true){
return true;
}else{
return false;
}
}
//resetMethod
private static TireTree resetMethod(TireTree tree) throws Exception{
tree = new TireTree();
return tree;
}
//print Search result
private static void printSearchResult(String string,boolean b){
if(b == true){
System.out.println("Word \"" + string + "\" found!");
}else{
System.out.println("Word \""+ string +"\" Not found!");
}
}
//print usage message
private static void printUsageMessage(){
System.err.println("Usage: {op} + {SPACE} + [string]");
System.err.println("[op] = '+' or '-' or '?' or '~'");
System.err.println("'+' means insert, '-' means delete, '?' means search, '~' means reset");
System.err.println("when reset the tree, command line don't need to include the string");
}
}
程序操作
由于字典树的操作和效果均由控制台实现,所以用户需要在控制台输入相关的命令代码,以进行程序测试。
命令代码:
Usage: {op} + {SPACE} + [string]
[op] = '+' or '-' or '?' or '~
'+' means insert, '-' means delete, '?' means search, '~' means reset
when reset the tree, command line don't need to include the string
做添加,删除和查询的时候分别使用 ‘+’, ‘-’, ‘?’的操作符,加上空格符,再加上想要实现的字符串。
做重置的时候只需要输出‘~’操作符即可。
结果
因为根据程序,初始化树的时候用的是{"apple", "bus", "cat", "dog"} 数据, 所以在这个数据范围内就进行测试。
绿色部分为用户输入的代码指令,黑色部分为程序响应的结果。
测试一:
查询是否存在“cat”
测试二:
添加并查询 “eye”
测试三:
删除并查询 “bus”
测试四:
1.添加并查询“catch”
2.查询“cat”
3.删除“cat”
4.查询“cat”和“catch”
测试五:
1.添加并查询“fine”
2.重置字典树
3.查询“fine”
未来发展:
本作只是博主刚接触TireTree时的练手之作,定有许多不足,敬请留言指导。
后续希望能够实现整体树结构的打印,JAVAFX的可视化处理,更优化的算法以及相关的配置操作(数据库相关)。