T9输入法的实现

T9输入法,名字听起来陌生,可是大家却经常使用它。可以说T9输入法是输入法历史中的一次革命。至少自T9输入法开始,输入法有长足的进步。
如图手机中九个数字键。26个英文字母被分配到2至9这8个数字键上。以前想输入英文单词的时候总是需要连续多次按某个键,才能得到目标字母。比如想输入“hello”,就需要按两次4,两次3,三次5,三次5,三次6.输入一个单词需要数十次的按键,更何况还有经常按错的情况。编辑一条短信非常麻烦。
T9输入法很好的解决了这一问题。用户利用9个数字键输入非常杂的英文单词并且不用重复按某个字符。系统将会根据已有词库找出可能性最大的单词。例如,目标单词为“hello”,只需输入4,3,5,5,6即可,系统会自动过滤掉不合法的单词如“gdjjm”。排除非法单词,只考虑合法单词,这样大大加速了输入速度。
然而这只是第一步,因为每次输入数字之后,可能有多个候选单词前缀与此匹配。这就需要按可能性提供可能性最大的(最常用)的英文单词。比如系统已知两个单词:"idea","hello"。idea最常用(可能度最高)。那么当依次输入4,3,5,5,6时,对于每次按键系统给出的候选单词应该是:
i (4)
id (3)
hel (5)
hell (5)
hello (6)
这样的话,通过T9输入法就可以大大提高输入速度和简洁度。
如何实现T9输入法呢?
(1)建立词库
将大量单词储备起来便于快速查找,字典树无疑是很好的选择。每个节点将存储此前缀的可能度,结构如下:

/*
 * 字典树
 */
public class Trie {
	
	public Node root = new Node();//字典树根节点
	
	public class Node{
		public int probablity;
		public Node[] next;
	
		public Node() {
			this.probablity = 0;
			next = new Node[26];
		}
	}
	
	public void insert(String str, int probablity){
		Node p = root;
		int i = 0;
		for(i = 0; i < str.length(); i++){
			if(p.next[str.charAt(i) - 'a'] != null){
				p = p.next[str.charAt(i) - 'a'];
				p.probablity += probablity;
			} else {
				Node q = new Node();
				q.probablity = probablity;
				p.next[str.charAt(i) - 'a'] = q;
				p = p.next[str.charAt(i) - 'a'];
			}
		}
	}
	
	public int search(String str){
		Node p = root;
		int i = 0;
		for(i = 0; i < str.length(); i++){
			if(p.next[str.charAt(i) - 'a'] != null){
				p = p.next[str.charAt(i) - 'a'];
			} else {
				return 0;
			}
		}
		return p.probablity;
	}
	
}



(2)查找
建立好的字典树,每个节点最多有26个孩子分别代表下一个字符。当给出一个查找串“43556”的时候,利用广度优先遍历来搜索长度x的所有前缀的可能度。找出最大的即可。广搜的时候要用到队列。
举例模拟过程:
当输入4(g,h,i)之后,通过字典树遍历发现只有"h","i",找出可能读最大的输出(i),并将h,i都入队。
输入3(d,e,f)后,拿出队列中的"h",分别组成"hd","he","hf",去字典树中查,将其中合法串入队,记录最大可能度对应串。再将h出队。对"i"做同样操作。最终找出最大的可能读最大串。
……
可以看出广搜的过程中大量剪枝,以及常用单词的长度最多不过十几个字母。所以字典树的深度也是十几,加上大量剪枝,性能还不错。

static int[][] ref = {	//手机键盘数字-字母映射表
	{0},
	{0},
	{3, 0, 1, 2},//按钮2,三个字母a,b,c
	{3, 3, 4, 5},
	{3, 6, 7, 8},
	{3, 9, 10, 11},
	{3, 12, 13, 14},
	{4, 15, 16, 17, 18},
	{3, 19, 20, 21},
	{4, 22, 23, 24, 25}
};
public static Queue<String> queue = new LinkedList<String>();	//用于广度优先遍历过程中的队列
public static Trie trie;	//字典树
	
public static void BFS(String str){
	queue.clear();
	queue.offer("");
		
	int i = 0;
	for(i = 0; '1' != str.charAt(i); i++){
		int max_probablity = 0; //最大可能性值
		String probaStr = "";
		int pre_amount = queue.size(); //队列中之前串的个数
		int j = 0;
		for(j = 0; j < pre_amount; j++){
			int k = 0;
			String preStr = queue.peek();
			for(k = 1; k <= ref[str.charAt(i) - '0'][0]; k++){
				String tempStr = preStr.concat((char)(ref[str.charAt(i) - '0'][k] + 97) + "");
				if(trie.search(tempStr) > 0){
					queue.offer(tempStr);
				}
				if(trie.search(tempStr) > max_probablity){
					max_probablity = trie.search(tempStr);
					probaStr = tempStr; 
				}
					
			}
			queue.poll();
		}
		if("".equals(probaStr)){
			break;
		} else {
			System.out.println(probaStr);
		}
	}
	while('1' != str.charAt(i++)){
		System.out.println("MANUALLY");
	}
		
}



思考:
1.以上模拟过程只是给出最大可能度的串,也可以按可能度将所有匹配串按顺序都给出,然后由用户选择。
2.感觉T9输入法打破了之前输入法的僵局,虽然只是用在手机输入。但是个人认为当前流行的智能键盘输入法也采用了类似的处理。比如利用搜狗输入法依次输入"hao""zi""wei""zhi"
给出的最大候选依次为:“好”“耗子”“好滋味”“好自为之”。是不是有点T9输入法的味道?如果有兴趣的话可以交流讨论!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
独立完成项目-----T9输入模拟器 本来这是老师给我们尖子小组三个人的一个合作挑战项目 但是我自己想了想 结构和原理按我的思路应该是可以行的通的 和他们俩住的远 也没得商量 思路上来就自己搞完了 项目名:手机T9输入模拟器 参加人员:小枪 开发平台:window XP 开发工具:visual studio 2005 , sqlserver 2005 重点要点:全程数据库操作语句 全部采用 执行存储过程 模拟手机拼音输入按键 如:2建代表 “abc” 贯彻三层结构数据理念 按不同的键组织成不同的拼音组合 再根据这些拼音组合查询数据库 列出所有符合按键拼音组合的汉字 这个地方相对我们在校的学生应该是比较有挑战的 总结思路 主要的思路构造就是全局做一个list将当前的所有能拼出来的拼音组合存起来 按下一个按键就把它全拆开挨个拼出新的组合 然后将全局的list再用我们新拼的组合来替换掉 替换前要记得清掉我们listviwe 里的所有字和拼音 我觉得难的地方在于那个返回键 也就是退格键 它要干的事就是返回我们的上一个步骤 这里我处理手段使用的是以前依稀记得的冒泡排序 和list的rmove 来挨个处理 先把前面按键组成的所有拼音组合挨个拿出来退一个字符 然后把第一个和所有集合中所有的拼音组合相比 有相同的就去掉 集合中原先第2个组合就成了现在的第一个组合 再把它拿出来挨个比较... 想了好久 靠 确实有点抽象了 说都有点说不明白 真不知道我们那班同学怎么去理解 字库问题 :还有就是字库的问题 据我所知汉字字库大概几千字 还是多少个来着 要做模拟器就得先做字库 这就有点麻烦了 一个一个的添显然麻烦 我偷了个懒 做俩个表 第一个表是我们的汉字表 包含两个字段: 汉字字符 和 我们的拼音外键 (因为一个拼音组合可能会有几十或上百的同音字) 第二个表就是我们的拼音表 这样查询的时候也简单 根据拼音父建直接可以查到这个拼音组合下所有的同音字 为了字库入库方便 我顺便还写了一个入库工具 呵呵 这个就比较简单了 输入流 把同一个拼音组合的汉字放一个文本中 然后把这个文本中这些汉字做成一个数组 加的时候等于说一次就加一个拼音组合的汉字 怎么样 思路还算可以吧 呵呵 字库未加完 我这里带上字库 自己加进去吧 呵呵这样应该可以交差了 在校学生: 小枪

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值