| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
其实这题完全用不着字典树……看Discuss区里的哥们儿都在说字典树,Tries树什么的,把学概B的兄弟吓得够呛。其实这道题大可不必如此费事,简单的比较就能搞定。给初学C++的兄弟们提供个思路:
基本思路:先给字符串排序,之后对于每个字符串,分别和上下两个字符串比较(如果有的话),找到第一个字符不同,或者字符串终止的位置记录下来,则两个位置中比较靠后的,就是最短前缀串的位置。
这样比较只需对相邻两字符串比较一次,算法复杂度为O(n),已经非常好了
输出的时候注意:不要把'\0'也输出去,会WA的!
这是我的代码,仅供参考:
Source: < C++ Memory: 240K Time: 0ms>
#include<iostream>
#include<cstring>
#include<algorithm> //排序提速用的,为了0ms不惜一切代价
using namespace std;
const int MAX = 1001; //要稍微开大一点,防止输入数据中有空行
struct Prefix{
char ch[24]; //字串,24个长度,也是适当的冗余
int PrefixPosition; //最短前缀位置
}str[MAX];
Prefix* pointer[MAX] = {NULL}; //用指针数组操作,排序时只交换指针
//不影响原来的字符串先后顺序
bool cmp(Prefix*a,Prefix*b){ //要返回bool类型,int不行
return strcmp(a->ch,b->ch) < 0;
}
int main(){
int count = 0,pos1 = 0,pos2 = 0;
while(cin>>str[count].ch){
pointer[count] = &str[count];
++count;
}
//sort the strings pointer in alphabetical order
sort(pointer,pointer+count,cmp);
//Compare
for(int i = 0;i < count;++i){
//和前后比较
if(i > 0)pos1 = pos2; //这样可减少一半的重复
pos2 = 0;
if(i < count - 1)while(pointer[i]->ch[pos2] && pointer[i]->ch[pos2] == pointer[i+1]->ch[pos2])++pos2;
//用最大的
pointer[i]->PrefixPosition = max(pos1,pos2);
}
for(int i = 0;i < count;++i){
printf("%s ",str[i].ch);
for(int j = 0;j <= str[i].PrefixPosition;++j)
//不要把'\0'打进去
if(str[i].ch[j])putchar(str[i].ch[j]);
printf("\n");
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator