POJ 1451 -- T9

T9

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4131   Accepted: 1481

Sample Input

2
5
hell 3
hello 4
idea 8
next 8
super 3
2
435561
43321
7
another 5
contest 6
follow 3
give 13
integer 6
new 14
program 4
5
77647261
6391
4681
26684371
77771

Sample Output

Scenario #1:
i
id
hel
hell
hello

i
id
ide
idea

Scenario #2:
p
pr
pro
prog
progr
progra
program

n
ne
new

g
in
int

c
co
con
cont
anoth
anothe
another

p
pr
MANUALLY
MANUALLY

题意:

现实生活问题:用手机打字

先给出n个单词表示常用单词

然后用户按手机键盘上面的数字键.要求用户每按一个数字键,手机弹出可能性最大的单词

思路:

字典树的应用,使用字典树对单词进行统计

使用深度搜索遍历字典树,进行词义猜测

Tips:

※ 字典树的典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

※ 【网上摘录】

串的快速检索:

  给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。

  在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。

串的排序:

  给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出

  用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。

最长公共前缀问题:

  对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为最近公共祖先问题。

  1 #include<iostream>
  2 #include<string>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxl = 110;
  6 char word[10][5] = {{"\0"},
  7                 {"\0"},{"abc"},{"def"},
  8                 {"ghi"},{"jkl"},{"mno"},
  9                 {"pqrs"},{"tuv"},{"wxyz"}};
 10
 11 char In[maxl];///接受输入字符串,建立字典树
 12 char inNum[maxl];///接受输入的数字按键
 13 char ans[maxl];///输出数组
 14 char tmp[maxl];///输出数组的临时数组,比较概率大小
 15 int pro;
 16
 17 class HashTable{
 18 public:
 19     HashTable *next[26];
 20     int Count;//概率
 21     HashTable()//初始化
 22     {
 23         Count = 0;
 24         memset(next,0,sizeof(next));
 25     }
 26 }*root;//根节点
 27
 28
 29 void Insert(int num)
 30 {
 31     int i = 0;
 32     HashTable *temp = root;
 33     while(In[i])
 34     {
 35         if(!temp->next[In[i]-‘a‘])///为空
 36         {
 37             temp->next[In[i]-‘a‘] = new HashTable;
 38         }
 39         temp = temp->next[In[i]-‘a‘];
 40         temp->Count += num;
 41         i++;
 42     }
 43 }
 44
 45 void find(int End,int pos,HashTable *r)
 46 {
 47     int len = strlen(word[inNum[pos]-‘0‘]);
 48     HashTable *temp = r;
 49     for(int i=0;i<len;i++)
 50     {
 51        int pi = word[inNum[pos]-‘0‘][i] - ‘a‘;
 52        if(!temp->next[pi]) continue;
 53        tmp[pos] = word[inNum[pos]-‘0‘][i];
 54        if(pos == End)//检索结束
 55        {
 56            if(temp->next[pi]->Count > pro)
 57             {
 58                 strcpy(ans,tmp);
 59                 pro = temp->next[pi]->Count;
 60             }
 61        }
 62        else
 63         find(End,pos+1,temp->next[pi]);
 64     }
 65 }
 66
 67 int main()
 68 {
 69     int turn;
 70     int turnCount = 1;
 71     while(cin>>turn)
 72     {
 73         while(turn--)
 74         {
 75             root = new HashTable;
 76             ///输入字符串和频数
 77             int a;
 78             cin>>a;
 79             for(int i=1;i<=a;i++)
 80             {
 81                 int num;
 82                 cin>>In>>num;
 83                 ///将读入的字符插入字典
 84                 Insert(num);
 85             }
 86
 87             cout<<"Scenario #"<<turnCount++<<":"<<endl;
 88
 89             ///输入按键
 90             cin>>a;
 91             while(a--)
 92             {
 93                 cin>>inNum;
 94                 ///将读入的按键进行处理
 95                 int len = strlen(inNum);
 96                 for(int i=0;i<len-1;i++)///注意末尾是1
 97                 {
 98                     pro = 0;
 99                     memset(tmp,0,sizeof(tmp));
100                     find(i,0,root);
101                     if(pro == 0)//没有找到
102                         cout<<"MANUALLY"<<endl;
103                     else{
104                         cout<<ans<<endl;
105                     }
106                 }
107                 cout<<endl;
108             }
109             cout<<endl;
110             delete root;
111         }
112     }
113     return 0;
114 }

原文地址:https://www.cnblogs.com/yxh-amysear/p/8447110.html

时间: 2024-10-09 05:24:51

POJ 1451 -- T9的相关文章

POJ 1451 T9 字典树+优先队列

题目来源:POJ 1451 T9 题意:给你一些单词 和优先值 然后当你按下数字的时候首先会出现哪个单词 就是我们平时手机的按键 思路:建一颗字典树 因为按一个数字对应多个字母 那么就有多种情况 我们要输出权值最大的一个 我用了优先队列 这里每个前缀的优先值是所有单词优先值的和 例如abc 5 abd 6 acd 7 那么a这个前缀的优先值是18 ab的优先值是11 #include <cstdio> #include <cstring> #include <queue>

POJ 1451 T9 字典树

题意和手机的九键输入法一样.输入数据第一行给出有多少组测试数据,每组数据第一行给出w(0<=w<=1000),接下来w行给出一个单词以及该单词的出现频率p(1<=p<=100),每个单词的最大长度不超过100个字母:然后,给出一个整数m,接下来m行给出一个输入串,代表在手机上按了哪些键,每个输入串最多有100个字符,且以数字1作为结尾.要求根据给出输入串,输出在按这些键的过程中,输入法给出的首选项(即出现频率最高的单词),若没有对应输入的单词,则输出"MANUALLY&q

【POJ】1451 T9

DFS+字典树. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 typedef struct Trie { 6 int v; 7 Trie *next[26]; 8 } Trie; 9 10 Trie root; 11 int arr[11] = {0,0,0,3,6,9,12,15,19,22,26}; 12 char buf[105], tmp[105]; 13 char map[

字典树trie的学习与练习题

博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/blog/1166118 http://www.360doc.com/content/12/1116/15/9615799_248213540.shtml http://www.cnblogs.com/tanky_woo/archive/2010/09/24/1833717.html http://bl

POJ 3449 Geometric Shapes --计算几何,线段相交

题意: 给一些多边形或线段,输出与每一个多边形或线段的有哪一些多边形或线段. 解法: 想法不难,直接暴力将所有的图形处理成线段,然后暴力枚举,相交就加入其vector就行了.主要是代码有点麻烦,一步一步来吧. 还有收集了一个线段旋转的函数. Vector Rotate(Point P,Vector A,double rad){ //以P为基准点把向量A旋转rad return Vector(P.x+A.x*cos(rad)-A.y*sin(rad),P.y+A.x*sin(rad)+A.y*co

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

ACM训练方案-POJ题目分类

ACM训练方案-POJ题目分类 博客分类: 算法 ACM online Judge 中国: 浙江大学(ZJU):http://acm.zju.edu.cn/ 北京大学(PKU):http://acm.pku.edu.cn/JudgeOnline/ 杭州电子科技大学(HDU):http://acm.hdu.edu.cn/ 中国科技大学(USTC):http://acm.ustc.edu.cn/ 北京航天航空大学(BUAA)http://acm.buaa.edu.cn/oj/index.php 南京

转载:poj题目分类(侵删)

转载:from: POJ:http://blog.csdn.net/qq_28236309/article/details/47818407 按照ac的代码长度分类(主要参考最短代码和自己写的代码) 短代码:0.01K–0.50K:中短代码:0.51K–1.00K:中等代码量:1.01K–2.00K:长代码:2.01K以上. 短:1147.1163.1922.2211.2215.2229.2232.2234.2242.2245.2262.2301.2309.2313.2334.2346.2348

poj题库分类

初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.     (2)最短路径算法(dijkstra,bellman-ford,floyd,hea