浏览器地址栏输入提示功能

要求当用户在浏览器的地址栏输入地址时,浏览器能够根据用户输入的历史记录对用户现在的输入进行匹配,提示用户可能要输入的字符。大概意思就是要实现和现在浏览器差不多的效果,比如用户之前输入过aaa,abcd,abcc(简化以下,不考虑前缀”www.”和后缀”.com”),当用户再次在浏览器地址栏输入a时,系统能够提示aaa,aaaa,abcd,abcc。输入ab时,系统能够提示abcd,abcc。

 

思路:感觉可以用树的结构解决该问题,解决过程如下:

1.数据结构选择

用户输入aaa,aaaa,abcd,abcc,后,内部存储结构为:


树的数据结构为:

class Tree {
	Tree tParent;
	char val;
	boolean flag;
	List<Tree> children;

	Tree(Tree p, char c, boolean b) {
		tParent = p;
		val = c;
		flag = b;
		children = new ArrayList<Tree>();
	}
}

其中flag用于表明是否至此为止可得到一条路径。

2.建树过程。

用户输入aaa,aaaa,abcd,abcc,后,树的变化过程如下图所示:


图V即为存储历史数据aaa&aaaa&abcd&abcc后的最终结果,其中黄色节点即表示flag=true,表明输入的历史数据中存有一条历史数据到黄色节点为止。

3.搜索过程。

以用户输入aa&ac为例。输入aa后,系统在树中找到符号条件的点(即图中红色节点)。以该节点为根遍历,以黄色的点为结尾,即可得到a&aa。加上前缀,即得到最终结果:aaa、aaaa。输入ac后,无法在树中找到ac,因此无提示


4.CODE:

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

class Tree {
	Tree tParent;
	char val;
	boolean flag;
	List<Tree> children;

	Tree(Tree p, char c, boolean b) {
		tParent = p;
		val = c;
		flag = b;
		children = new ArrayList<Tree>();
	}
}

public class Solution {
	/**
	 * 向root中插入节点,返回插入的节点。插入过程中注意flag的设置
	 * 
	 * @param root
	 * @param c
	 * @param b
	 * @return
	 */
	public static Tree insert(Tree root, char c, boolean b) {
		Tree node = new Tree(root, c, b);
		if (!isContain(root.children, node)) {
			root.children.add(node);
		} else {
			for (Tree temp : root.children)
				if (temp.val == node.val) {
					if (b == true)
						temp.flag = b;
					return temp;
				}
		}
		return node;
	}

	/**
	 * 判断children中是否已存在node
	 * 
	 * @param children
	 * @param node
	 * @return
	 */
	public static boolean isContain(List<Tree> children, Tree node) {
		for (Tree temp : children) {
			if (temp.val == node.val)
				return true;
		}
		return false;
	}

	/**
	 * 打印以node为根节点的路径
	 * 
	 * @param node
	 */
	public static void printPath(Tree node) {
		Queue<Tree> queue = new ArrayDeque<Tree>();
		Tree temp = new Tree(null, '.', false);
		queue.add(node);
		while (queue.size() != 0) {
			temp = queue.poll();
			if (temp.flag == true) {
				Tree ori = new Tree(null, ',', false);
				ori = temp;
				String strTemp = "";
				while (temp.tParent != null) {
					strTemp += temp.val;
					temp = temp.tParent;
				}
				for (int i = strTemp.length() - 1; i >= 0; --i)
					System.out.print(strTemp.charAt(i));
				System.out.println();
				temp = ori;
			}
			for (Tree t : temp.children)
				queue.add(t);
		}
	}

	/**
	 * 查找&遍历
	 * 
	 * @param root
	 * @param str
	 */
	public static void SendHint(Tree root, String str) {
		Tree node = searchNode(root, str);
		if (node == null) {
			System.out.println("No Hint");
			return;
		}
		printPath(node);
	}

	/**
	 * 根据输入的string在历史树中进行查找,找到符合条件的节点返回(对该节点进行遍历即可得到最终提示)
	 * 
	 * @param root
	 * @param str
	 * @return
	 */
	public static Tree searchNode(Tree root, String str) {
		if (str == null || str.length() == 0)
			return root;
		for (int i = 0; i < str.length(); ++i) {
			for (Tree node : root.children) {
				if (node.val == str.charAt(i)) {
					return searchNode(node, str.substring(i + 1, str.length()));
				}
			}
		}
		return null;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Tree origin = new Tree(null, '.', false);
		Tree root = new Tree(null, '.', false);
		origin = root;
		String[] str = { "aaa", "aaaa", "abcd", "abcc", "adbc", "adddd" };
		// 建树
		for (String temp : str) {
			for (int i = 0; i < temp.length(); ++i) {
				root = insert(root, temp.charAt(i), (i == temp.length() - 1));
			}
			root = origin;
		}
		// 搜索
		SendHint(origin, "ab");
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值