uva 10391 Compound Words

题目:给定一个单词本,要求找出其中的单词,是单词本中某两个单词合并起来得。

思路。先把单词本用字典树保存,然后枚举没个单词的切点,把一个单词分成两部分,去字典树中找即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn=1e5;
const int N=26;//26个小写字母
struct node
{
    int flag;//标记以这个字母结尾为一个单词
    int count;//标记以这个字母结尾为一个前缀
    struct node *pNext[N];//26枚字符指针
}tree[maxn*N];//大小通常设为 单词个数*单词长度
int t;//表明现在用到了那个节点
struct node *create ()
{
    //需要新开一个字符节点,就是有abc这样,插入abd,则d需要新开节点
    struct node *p=&tree[t++];
    p->flag=0;    //初始值为0,不是整个单词
    p->count=1;    //前缀是必须的,本身就是一个了
    for (int i=0;i<N;i++)
    {
        p->pNext[i]=NULL;//初始化指针
    }
    return p;
}
void insert (struct node **T,const char str[])
{
    struct node *p=*T;
    if (!p)//空树
    {
        p=*T=create();
    }
    int lenstr=strlen(str+1);
    for (int i=1;i<=lenstr;i++)        //把单词拆开放进树
    {
        int id=str[i]-‘a‘;        //压缩下标
        if (p->pNext[id])    //存在过,则前缀++
        {
            p->pNext[id]->count++;        //p->pNext[id]表明是id这个字母
        }
        else
        {
            p->pNext[id]=create();
        }
        p=p->pNext[id];
    }
    p->flag=1;        //表明这字母为结尾是一个单词,上一次已经是p=p->pNext[id]了
//就是现在已经去到了单词的最后一个字母的那个节点了!!
    return ;
}
int find (struct node *T,const char str[])
{
    struct node *p = T;
    if (!p)        //空树
    {
        return 0;
    }
    int lenstr=strlen(str+1);
    for (int i=1;i<=lenstr;i++)
    {
        int id=str[i]-‘a‘;
        if (!p->pNext[id])
        {
            return 0;        //单词中断,找不到
        }
        p=p->pNext[id];
    }
    return p->flag;        //看看是不是一个单词的结尾
}
string str[120000+20];

void work ()
{
    struct node * T = NULL;
    int n=1;
    while (scanf("%s",str[n].c_str()+1) != EOF )
    {
        insert(&T,str[n].c_str());
        ++n;
    }
    for (int i=1;i<=n-1;++i)
    {
        //printf ("%s\n",str[i].c_str()+1);
        int len = 1;
        while (str[i][len] != ‘\0‘) ++len;
        --len;
//        printf ("%d\n",len);
        for (int j=1;j<=len-1;++j)
        {
            string a,b;
            a+="0";
            b+="0";
            for (int k=1;k<=j;++k) a += str[i][k];
            for (int k=j+1;k<=len;++k) b += str[i][k];
            //cout<<a<<"  "<<b<<"***"<<endl;
            if (find(T,a.c_str())&&find(T,b.c_str()))
            {
                printf ("%s\n",str[i].c_str()+1);
                break;
            }
        }
    }
    return ;
}
int main()
{
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}

时间: 2024-08-06 07:53:25

uva 10391 Compound Words的相关文章

uva 10391 Compound Words (字符串-hash)

Problem E: Compound Words You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is theconcatenation of exactly two other words in the dictionary. Input Standard input consists of a

UVa 10391 Compound Words(复合词)

题意  输出所有输入单词中可以由另两个单词的组成的词 STL set的应用  枚举每个单词的所有可能拆分情况  看拆开的两个单词是否都存在  都存在的就可以输出了 #include <bits/stdc++.h> using namespace std; string a, b; set<string> s; set<string>::iterator i; int main() { int l; while(cin >> a) s.insert(a); f

紫书第五章训练 uva 10391 Compound Words by crq

You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary. Input Standard input consists of a number of lowercase words

UVA 10391 Compound Words(哈希,逆向思维)

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 /** 5 学习: 6 逆向思维:将复合词拆分成两个词,看是否在set中出现 7 string类 的 substr 8 9 */ 10 11 int main(){ 12 set<string> myset; 13 set<string>::iterator it; 14 string str; 15 int cnt =

uva 10391 Compound Words(查找)

哈哈,这个事自己敲的,而且运用了set容器,就是查找而已,用set容器挺方便的,网上用的hash做的都好长好 麻烦,我觉得hash表有点难,特别是要自己想出一个函数,不太想学这个... 贴代码: #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<string> #include<set> using namespace

UVa 10391 (水题 STL) Compound Words

今天下午略感无聊啊,切点水题打发打发时间,=_=|| 把所有字符串插入到一个set中去,然后对于每个字符串S,枚举所有可能的拆分组合S = A + B,看看A和B是否都在set中,是的话说明S就是一个复合词. 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <

uva 10391复合词compound words(Trie+set)

给定一个词典,要求求出其中所有的复合词,即恰好有两个单词连接而成的词 trie存储以该单词为前缀的单词数量,然后对于每个单词,看在字典中的以该单词为前缀的单词"减去"原单词剩下的单词是否在字典中,如果是储存这个答案到ans的set中 #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include&l

UVA - 10391

Problem E: Compound Words You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary. Input Standard input consists of a

UVA 10391(把符合单词输出,map)

Compound Words Time Limit: 3000ms                        Memory Limit: 131072KB [PDF Link] Problem E: Compound Words You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is the con