poj 2804 字典 (特里 要么 快排+二分法)
2804:词典
- 总时间限制:
- 3000ms
- 内存限制:
- 65536kB
- 描写叙述
- 你旅游到了一个国外的城市。那里的人们说的外国语言你不能理解。只是幸运的是,你有一本词典能够帮助你。
- 输入
- 首先输入一个词典。词典中包含不超过100000个词条。每个词条占领一行。每个词条包含一个英文单词和一个外语单词,两个单词之间用一个空格隔开。并且在词典中不会有某个外语单词出现超过两次。词典之后是一个空行。然后给出一个由外语单词组成的文档,文档不超过100000行。并且每行仅仅包含一个外语单词。输入中出现单词仅仅包含小写字母。并且长度不会超过10。
- 输出
- 在输出中,你须要把输入文档翻译成英文,每行输出一个英文单词。假设某个外语单词不在词典中。就把这个单词翻译成“eh”。
- 例子输入
-
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay atcay
ittenkay
oopslay - 例子输出
-
cat
eh
loops - 提示
- 输入比較大,推荐使用C语言的I / O函数。
-
-
- 这道题目開始做的时候想到的是字典树;后来由于这道题输入有点特殊。就一直不知道从何下手建树,后来看到别人处理输入的方法;一下子就来了灵感,套用了曾经的模板,把代码敲好提交到百练上就a了,后来在我们学校的oj提交;直接被一个数据难倒了。
。。(百练的数据有点水啊),后来就一直再想解决的方法。開始的那个程序,假设与给的单词部分匹配直到给的单词结束就输出结果了,可是字典树里面还有,不是全然匹配。当时由于a了就没有考虑到这种情况。一直卡在这里;今天看了别人的ac自己主动机的代码;又给了我一点提示;在
- 节点中设置一个单词完结的标记;这种处理,開始我也想了好久,还是有点水啊;一直出现异常的结束。后来最终写好了,感觉还是有点投机取巧的意思,在两个oj上都a了,可是还可以优化;有时候执行还是有问题。我也不知道是什么原因;
- 以下是代码;能ac的,还可以优化啊!
!
-
#include <cstdio>
#include <cstring>
#include <cstdlib>
typedef struct node //节点的结构体
{
char eng[12];
int count; //标记单词是否结束
struct node * next[26];
}node;
int flag;
void Insert(node *T,char *f,char *e) //插入
{
node *p,*q;
p=T;
int len,k;
len=strlen(f);
if(len==0) return ;
for(int i=0;i<len;i++)
{
k=f[i]-'a';
if(p->next[k]==NULL)
{
q=(node*)malloc(sizeof(node)); //添加新节点
for(int i=0;i<26;i++)
{
q->count=0;
strcpy(q->eng,e);
q->next[i]=NULL;
}
p->next[k]=q;
p=q;
}
else
p=p->next[k];
}
p->count++;
}
void Search(node *T,char *s)//查找
{
node *q;
q=T;
int k,i=0,len;
int flag=0;
for(i=0;i<26;i++)
{
k=s[i]-'a';
q=q->next[k];
if(q==NULL)
{
flag=1;
printf("eh\n");
break;
}
if(q->count>0)//单词结束的标记
{
printf("%s\n",q->eng);
flag=1;
break;
}
}
}
void Release(node *T)//销毁
{
for(int i=0;i<26;i++)
if(T->next[i]!=NULL)
Release(T->next[i]);
free(T);
}
int main()
{
//freopen("1.txt","r",stdin);
char english[20],forigen[20];
node *T;
T=(node *)malloc(sizeof(node));
T->count=0;
for(int i=0;i<26;i++)
T->next[i]=NULL;
while(1)
{
english[0]=getchar();
if(english[0]=='\n') break;
scanf("%s %s",english+1,forigen);
Insert(T,forigen,english);
getchar();
}
while(scanf("%s",forigen)!=EOF)
{
flag=0;
Search(T,forigen);
}
Release(T);
return 0;
}第一次ac的水代码;
-
void Search(char *f)
{
node *q;
int len,k;
q=T;
len=strlen(f);
for(int i=0;i<len;i++)
{
k=f[i]-'a';
q=q->next[k];
if(q==NULL)
{
printf("eh\n");
flag=1;
break;
}
}
if(flag==0) printf("%s\n",q->eng);//部分匹配就直接输出了
} - 别人写的字典树代码。好巧妙值得学习;把单词最后一个字符分开处理。做标志,这样就能避免我先前所犯的错误。看了别人的代码,茅塞顿开啊。
-
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "algorithm"
#include "iostream"
using namespace std; typedef struct node
{
struct node *next[26];
char ans[12];
}node; char arr1[12],arr2[12],str[25];
node *T; void Diction()
{
node *q,*p=T;
int i,j,k,len;
len=strlen(arr2);
for(i=0;i<len-1;i++)
{
k=arr2[i]-'a';
if(p->next[k]==NULL){
q=(node*)malloc(sizeof(node));
p->next[k]=q;q->ans[0]=0;
for(j=0;j<26;j++)
q->next[j]=NULL;
p=q;
}else{
p=p->next[k];
}
}
k=arr2[i]-'a';//最后一个字符
if(p->next[k]==NULL){
q=(node*)malloc(sizeof(node));
p->next[k]=q;strcpy(q->ans,arr1);//把arr数组复制给最后一个字符的节点;其它节点都是0
for(j=0;j<26;j++)
q->next[j]=NULL;
}else{
p=p->next[k];
strcpy(p->ans,arr1);
}
} void search()//查询
{
node *p=T;
int i,len,k;
len=strlen(str);
for(i=0;i<len-1;i++)
{
k=str[i]-'a';
if(p->next[k]==NULL){
printf("eh\n");
break;
}else{
p=p->next[k];
}
}
if(i==len-1)//最后一个字符
{
k=str[i]-'a';
if(p->next[k]==NULL){
printf("eh\n");
}else{
p=p->next[k];
if(p->ans[0]!=0)//前面插入那里做的标志
puts(p->ans);
else
printf("eh\n");
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
int i;
T=(node*)malloc(sizeof(node));
for(i=0;i<26;i++)
T->next[i]=NULL;
while(1)
{
gets(str);
if(strcmp(str,"")==0)
break;
sscanf(str,"%s %s",arr1,arr2);
Diction();
}
while(scanf("%s",str)!=EOF)
search();
return 0;
}另一种思路就是直接用快排+二分的组合,这样的使用方法也非经常见;在这个题目中用到了fgets,sscanf这两个函数。都是第一次用。还用了c语言库里面的qsort和bsearch。然后自己又写了一次二分;比写字典树难度还是小了非常多。非常多细节上还是把握的不好啊;
- 以下是ac的代码,直接调用库函数写的。
-
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
struct node //节点的结构体
{
char eng[12];
char fore[12];
};
node dictionary[maxn];
int cmp(const void *a,const void *b){ //比較函数
return strcmp(((node *)a)->fore,((node *)b)->fore);
}
int search(const void *a,const void *b){ //二分查找函数
return strcmp((char *)a,((node *)b)->fore);
}
int main()
{
//freopen("1.txt","r",stdin);
char english[30],forigen[20];
int count=0,flag;
node *p;
while(fgets(english,29,stdin)&&english[0]!='\n')
{
sscanf(english,"%s%s",dictionary[count].eng,dictionary[count].fore);
count++;
}
qsort(dictionary,count,sizeof(node),cmp);
while(scanf("%s",forigen)!=EOF)
{
p=NULL;
p=(node*)bsearch(forigen,dictionary,count,sizeof(node),search);
if(p)
printf("%s\n",p->eng);
else
printf("eh\n");
}
return 0;
}自己写得二分查找;
-
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
struct node //节点的结构体
{
char eng[12];
char fore[12];
};
node dictionary[maxn];
bool Cmp(node one, node two)
{
return strcmp(one.fore, two.fore) < 0;
}
int bsearch(char *s,int n) //二分查找
{
int mid,start,end;
start=0;end=n-1;
int flag=0;
while(start<=end)
{
mid=(start+end)/2;
flag=strcmp(s,dictionary[mid].fore);
if(flag==0)
return mid;
if(flag<0)
{
end=mid-1;
}
else
{
start=mid+1;
}
}
return -1;
}
int main()
{
//freopen("1.txt","r",stdin);
char english[30],forigen[20];
int count=0,flag;
node *p;
while(fgets(english,29,stdin)&&english[0]!='\n')
{
sscanf(english,"%s%s",dictionary[count].eng,dictionary[count].fore);
count++;
}
sort(dictionary,dictionary+count,Cmp);
while(scanf("%s",forigen)!=EOF)
{
flag=bsearch(forigen,count);
if(flag!=-1)
{
printf("%s\n",dictionary[flag].eng);
}
else
printf("eh\n");
}
return 0;
}在平时做题中还是要多积累。
- 总结:这个题目能够用多种思路去做,平时练习能够多去尝试一下,熟悉一下库函数。fgets,sscanf对输入格式的控制;qsort中cmp函数的格式。还用bsearch里面search函数的写法和格式,传递的參数。对于字典树在模板的基础上还要依据题意灵活处理,像这道题的话,设置一个參数表示结束就会非常方便;
- 标题不,在晴朗。。
poj 2804 字典 (特里 要么 快排+二分法)的更多相关文章
- POJ 2503 Babelfish(map,字典树,快排+二分,hash)
题意:先构造一个词典,然后输入外文单词,输出相应的英语单词. 这道题有4种方法可以做: 1.map 2.字典树 3.快排+二分 4.hash表 参考博客:[解题报告]POJ_2503 字典树,MAP ...
- poj 1328 Radar Installation(贪心+快排)
Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea i ...
- iOS常见算法(二分法 冒泡 选择 快排)
二分法: 平均时间复杂度:O(log2n) int halfFuntion(int a[], int length, int number) { int start = 0; int end = l ...
- Java基础进阶:APi使用,Math,Arrarys,Objects工具类,自动拆装箱,字符串与基本数据类型互转,递归算法源码,冒泡排序源码实现,快排实现源码,附重难点,代码实现源码,课堂笔记,课后扩展及答案
要点摘要 Math: 类中么有构造方法,内部方法是静态的,可以直接类名.方式调用 常用: Math.abs(int a):返回参数绝对值 Math.ceil(double a):返回大于或等于参数的最 ...
- STL函数库的应用第二弹——快排sort函数与结构体关键字排序
时隔20多天,本蒟蒻终于记起了他的博客园密码!!! 废话不多说,今天主题:STL快排函数sort()与结构体关键字排序 Part 1:引入和导语 首先,我们需要知道,algorithm库里有一些奇怪的 ...
- F#之旅4 - 小实践之快排
参考文章:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-quicksort.html F#之旅4 - 小 ...
- 快排 快速排序 qsort quicksort C语言
现在网上搜到的快排和我以前打的不太一样,感觉有点复杂,我用的快排是FreePascal里/demo/text/qsort.pp的风格,感觉特别简洁. #include<stdio.h> # ...
- C++ 快排
// 进行一轮快排并返回当前的中间数 int getMiddle( int* arr, int low, int high ) { auto swaparr = [&]( int i, int ...
- 先贴上代码:Random快排,快排的非递归实现
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是, ...
随机推荐
- bridge pattern
10.5 桥接模式总结 桥接模式是设计Java虚拟机和实现JDBC等驱动程序的核心模式之一,应用较为广泛.在软件开发中如果一个类或一个系统有多个变化维度时,都可以尝试使用桥接模式对其进行设计.桥接模 ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...
- firefox os 2.0版模拟器QQ初体验
供firefox os 爱侣.firefox os 手机迟迟没有感到些许遗憾在中国上市会,但是,我们必须相信firefox os 登陆中国是迟早的事,腾讯QQ已经登陆firefox os 应用市场,今 ...
- 达到J2EE在后台action控制接待javascript弹出的对话框
1.后台Action于: request.setAttribute("message", "这项username要么password错误,请重新输入!"); 2 ...
- NFS 配置服务
NFS 配置服务 北京市海淀区 张俊浩 一.NFS.即网络文件系统(Network File System,NFS).一种使用于分散式文件系统的协议,由升阳公司开发.于1984年向外发布.功能是通过 ...
- ORACLE profile列4 --CREATE PROFILE
这个博客是ORACLE profile系列第四部分.主要说一下,假设你创建profile而使用profile资源和password控制 CREATE PROFILE Note: Oracle reco ...
- Akka.NET是Java/Scala 流行框架Akka的一个 .NET 开源移植
Akka.NET v1.0 已发布,支持Mono Akka.NET 是Java/Scala 流行框架Akka的一个 .NET 开源移植.可用于构建高并发,分布式和容错事件驱动的应用在 .NET 和 M ...
- R语言和数据分析十大:购物篮分析
提到数据挖掘,我们的第一个反应是之前的啤酒和尿布的故事听说过,这个故事是一个典型的数据挖掘关联规则.篮分析的传统线性回归之间的主要差别的差别,对于离散数据的相关性分析: 常见的关联规则: 关联规则:牛 ...
- Windows Auzre 微软的云计算产品的后台操作界面
Windows Auzre 微软的云计算产品的后台操作界面,试用期,相比于阿里云后台操作不是人. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTmFvbG ...
- HTML5 CSS3 精美案例 : 达到VCD盒个性幻灯片
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/31015121 哈,首先感谢下w3cfuns教师,行~ 行.这一次分享发夹CSS3 ...