NkOJ2218(字典树+STL)

2218: 语音识别

Time Limit: 1000 ms    Memory Limit: 65536 kB  
Total Submit : 74  (18 users)    Accepted Submit : 15  (13 users)    Page View : 318 
Font Style: Aa Aa Aa

 

近些年语音识别技术越来越流行,要检验语音识别技术是否精准,可采用如下方法:第一台机器发声读单词,第二台根据第一台发出的声音进行语音识别并发声,第三台接收第二台发出的声音并发声……以此类推,直到最后一台机器发声。

由于这个过程中可能会出现一些偏差,机器很多时,最后听到的话往往会和初始句子有很大出入。经过几轮实验后,我们注意到在两台机器间传达时,有些单词往往会错误地变成其他特定的单词,而有些单词不会改变。我们已经收集到了这样的一个单词转化的列表,现在想要知道初始句子到最后会变成什么样子,请写程序来实现。

Input

输入包括多组数据。

第一行是整数T (1<=T<=100),表示有多少组测试数据。

每组数据第一行包括两个整数N和M (2<=N<=100, 0<=M<=100),分别表示机器的数量和单词转化列表长度。随后有M行,每行包含两个用空格隔开的单词a和b,表示单词a在传话中一定会变成b。输入数据保证没有重复。最后一行包含若干个用单个空格隔开的单词,表示初始句子,句子总长不超过100个字符。同一个单词的不同时态被认为是不同的单词。

当然,如前所述,不在列表中的单词永远不会变化。

Output

对于每组测试数据,单独输出一行“Case #c: s” (不含引号)。 其中,c为测试数据编号,s为最后我们所听到的句子。s的格式与输入数据中初始句子格式相同。

Sample Input

2
4 3
ship sheep
sinking thinking
thinking sinking
the ship is sinking
10 5
tidy tiny
tiger liar
tired tire
tire bear
liar bear
a tidy tiger is tired

Sample Output

Case #1: the sheep is thinking
Case #2: a tiny bear is bear

Source

Best User : cztianshi



我首先用的字典树,但过不了,后来看了大神的模仿可以说完全照抄的吧,改用STL最终解决了,但我弄不明白为什么字典树就错了,可能有其他非大小写字符吧!

/*
我的程序
#include<iostream>
using namespace std;

struct Trie
{
    Trie * next[26];
 char new_word[100];
 bool flag;//标记是否是单词的结尾
}*root;/可以不用存真的数据元素

void insert(char *str1,char *str2)
{
    int len =strlen(str1);
    Trie *s = root;
    for (int i = 0; i < len; i++)
 {
  if (s->next[str1[i] - 'a'])
            s = s->next[str1[i] - 'a'];
        else
  {
            Trie* t = new Trie;
            memset(t, 0, sizeof (Trie));
            s->next[str1[i] - 'a'] = t;
            s = t;
        }
 }
 strcpy(s->new_word,str2);
 //cout<<s->new_word<<" "<<endl;
 s->flag = 1;
}

int find(char *str)
{
    int len = strlen(str);
// cout<<str<<" "<<len<<endl;
    Trie *s = root;
    for (int i = 0; i < len; i++)
 {
  if (s->next[str[i] - 'a'])
            s = s->next[str[i] - 'a'];
        else
            return 0;
 }
 if(s->flag==1)
  strcpy(str,s->new_word);
 return s->flag;/flag可能不标志为单词结尾
}


void del(Trie *root)
{
    Trie *s = root;
    for (int i = 0; i < 26; i++)
 {
        if (s->next[i])
            del(s->next[i]);
    }
    delete s;
    s = NULL;
}


int main()
{
 int t,n,m,i,start,j,k,tag=0;
 char str1[100],str2[100],alticle[100],word[100],new_alticle[100][100];
 cin>>t;
 while(t--)
 {
  tag++;
  root=new Trie;
  memset(root,0,sizeof(Trie));
  cin>>n>>m;
  for(i=0;i<m;i++)
  {
   cin>>str1>>str2;
   insert(str1,str2);
  }
  getchar();
 // cout<<"&&&&&"<<endl;
  gets(alticle);
  puts(alticle);
  // cout<<"&&&&&"<<endl;
  
  start=0;
  k=0;
  for(i=0;alticle[i]!=0;i++)
  {
   
   if(alticle[i]==' ')
   {
    word[start]=0;
   // cout<<word<<" ";
    for(j=0;j<n-1;j++)
    {
     
        find(word);
    }
    strcpy(new_alticle[k++],word);
     // cout<<word<<" ";
    start=0;
   }
   if(alticle[i]!=' ')word[start++]=alticle[i];

  }
  word[start]=0;
   // cout<<word<<" ";
    for(j=0;j<n-1;j++)
    {
     
        find(word);
    }
    strcpy(new_alticle[k++],word);
    cout<<"Case #"<<tag<<": ";
    for(i=0;i<k-1;i++)
     cout<<new_alticle[i]<<" ";

    cout<<new_alticle[i]<<endl;

     del(root);
 }
 return 0;
}
*/
///大神的程序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
using namespace std;

map<string,string>::iterator iter;


int main()
{
 string a,b,word;
 int t,n,m,i,j,tag=0;
 char alticle[1200];
 cin>>t;
 while(t--)
 {
  tag++;
        map<string,string>temp;
  cin>>n>>m;
  for(i=0;i<m;i++)
  {
   cin>>a>>b;
   temp[a]=b;
  }
  
  getchar();
  gets(alticle);
  
  printf("Case #%d:",tag);
  word="";
  for(i=0;alticle[i]!=0;i++)
  {
   if(alticle[i]!=' ')
    word+=alticle[i];
   else 
   {
    for(j=0;j<n-1;j++)
    {
     if((iter=temp.find(word)) !=temp.end())
      word=iter->second;
    }
    
    cout<<" "<<word;
  // printf(" %s",word.c_str());
    word="";
   }
   
  }
  
  for(j=0;j<n-1;j++)
  {
   if((iter=temp.find(word))!=temp.end())
    word=iter->second;
  }
  // printf(" %s\n",word.c_str());
  
  cout<<" "<<word<<endl; 
 }
 return 0;
}

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值