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)建立词库
将大量单词储备起来便于快速查找,字典树无疑是很好的选择。每个节点将存储此前缀的可能度,结构如下:

[java]  view plain copy
  1. /* 
  2.  * 字典树 
  3.  */  
  4. public class Trie {  
  5.       
  6.     public Node root = new Node();//字典树根节点  
  7.       
  8.     public class Node{  
  9.         public int probablity;  
  10.         public Node[] next;  
  11.       
  12.         public Node() {  
  13.             this.probablity = 0;  
  14.             next = new Node[26];  
  15.         }  
  16.     }  
  17.       
  18.     public void insert(String str, int probablity){  
  19.         Node p = root;  
  20.         int i = 0;  
  21.         for(i = 0; i < str.length(); i++){  
  22.             if(p.next[str.charAt(i) - 'a'] != null){  
  23.                 p = p.next[str.charAt(i) - 'a'];  
  24.                 p.probablity += probablity;  
  25.             } else {  
  26.                 Node q = new Node();  
  27.                 q.probablity = probablity;  
  28.                 p.next[str.charAt(i) - 'a'] = q;  
  29.                 p = p.next[str.charAt(i) - 'a'];  
  30.             }  
  31.         }  
  32.     }  
  33.       
  34.     public int search(String str){  
  35.         Node p = root;  
  36.         int i = 0;  
  37.         for(i = 0; i < str.length(); i++){  
  38.             if(p.next[str.charAt(i) - 'a'] != null){  
  39.                 p = p.next[str.charAt(i) - 'a'];  
  40.             } else {  
  41.                 return 0;  
  42.             }  
  43.         }  
  44.         return p.probablity;  
  45.     }  
  46.       
  47. }  



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

[java]  view plain copy
  1. static int[][] ref = {  //手机键盘数字-字母映射表  
  2.     {0},  
  3.     {0},  
  4.     {3012},//按钮2,三个字母a,b,c  
  5.     {3345},  
  6.     {3678},  
  7.     {391011},  
  8.     {3121314},  
  9.     {415161718},  
  10.     {3192021},  
  11.     {422232425}  
  12. };  
  13. public static Queue<String> queue = new LinkedList<String>();   //用于广度优先遍历过程中的队列  
  14. public static Trie trie;    //字典树  
  15.       
  16. public static void BFS(String str){  
  17.     queue.clear();  
  18.     queue.offer("");  
  19.           
  20.     int i = 0;  
  21.     for(i = 0'1' != str.charAt(i); i++){  
  22.         int max_probablity = 0//最大可能性值  
  23.         String probaStr = "";  
  24.         int pre_amount = queue.size(); //队列中之前串的个数  
  25.         int j = 0;  
  26.         for(j = 0; j < pre_amount; j++){  
  27.             int k = 0;  
  28.             String preStr = queue.peek();  
  29.             for(k = 1; k <= ref[str.charAt(i) - '0'][0]; k++){  
  30.                 String tempStr = preStr.concat((char)(ref[str.charAt(i) - '0'][k] + 97) + "");  
  31.                 if(trie.search(tempStr) > 0){  
  32.                     queue.offer(tempStr);  
  33.                 }  
  34.                 if(trie.search(tempStr) > max_probablity){  
  35.                     max_probablity = trie.search(tempStr);  
  36.                     probaStr = tempStr;   
  37.                 }  
  38.                       
  39.             }  
  40.             queue.poll();  
  41.         }  
  42.         if("".equals(probaStr)){  
  43.             break;  
  44.         } else {  
  45.             System.out.println(probaStr);  
  46.         }  
  47.     }  
  48.     while('1' != str.charAt(i++)){  
  49.         System.out.println("MANUALLY");  
  50.     }  
  51.           
  52. }  



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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值