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 number of lowercase words, one per line,in alphabetical order. There will be no more than 120,000 words.

Output

Your output should contain all the compound words, one per line, inalphabetical order.

Sample Input

a
alien
born
less
lien
never
nevertheless
new
newborn
the
zebra

Sample Output

alien
newborn

题目大意:

有一堆按照字典序排好的字符串,问你有多少字符串是由其它两个字符串组成。

解题思路:

如果用两个字符串拼接看拼接好的字符串是否在字典中,一定会超时。

我们可以逆向,由于字符串的长度不是很长,所以把一个字符串拆为两个字符串看这两个字符串是否都在字典中即可

解题代码一:

判断字符串是否在字典中,可以用STL set,也是轻松AC

#include <iostream>
#include <set>
#include <cstdio>
#include <string>
using namespace std;

set <string> mys;

int main(){
    string st;
    set <string>::iterator it;
    while(cin>>st) mys.insert(st);
    for(it=mys.begin();it!=mys.end();it++){
        st=*it;
        for(int i=0;i<st.length()-1;i++){
            string sub1=st.substr(0,i+1);
            string sub2=st.substr(i+1,st.length()-(i+1));
            if( mys.find(sub1)!=mys.end() && mys.find(sub2 )!=mys.end() ){
                printf("%s\n",st.c_str());
                break;
            }
        }
    }
    return 0;
}

解题代码二:

判断字符串是否在字典中,可以用hash,于是手写hash,速度会比set快一点,关键看hash编码

一些编码方法:点击查看

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

const int maxn=1000003;

int head[maxn],next[maxn];
string str[maxn];
int cnt;

void initial(){
	cnt=0;
	for(int i=0;i<maxn;i++){
		head[i]=-1;
	}
}

/*int gethash(string st){//BKDRHash 0.146s
    unsigned int sum=0,step=131;
    for(int i=0;i<st.length();i++){
        sum+=st[i]*step;
    }
    return (sum & 0x7FFFFFFF)%maxn;
}*/

int gethash(string st){//DJBHash 0.112s
    unsigned int sum=0;
     for(int i=0;i<st.length();i++){
        sum += (sum << 5) +st[i];
     }
    return (sum & 0x7FFFFFFF)%maxn;
}

void add(string st){
	int c=gethash(st);
	str[cnt]=st;
	next[cnt]=head[c];
	head[c]=cnt++;
}

bool canfind(string st){
    int c=gethash(st);
    for(int i=head[c];i!=-1;i=next[i]){
        if(str[i]==st) return true;
    }
    return false;
}

int main(){
	string st;
	initial();
	while(cin>>st) add(st);
	for(int i=0;i<cnt;i++){
            for(int k=1;k<str[i].length();k++){
                string sub1=str[i].substr(0,k);
                string sub2=str[i].substr(k,str[i].length()-k);
                if(canfind(sub1)  &&  canfind(sub2)){
                    printf("%s\n",str[i].c_str());
                    break;
                }
            }
    }
    return 0;
}

解题代码三:C++ 11 hash函数

判断字符串是否在字典中,可以用hash,,速度比解题代码二快

#include <iostream>
#include <functional>
#include <string>
#include <cstdio>
using namespace std;

const int maxn=1000003;

int head[maxn],nextt[maxn];
string str[maxn];
int cnt;

hash <string> str_hash;

void initial(){
	cnt=0;
	for(int i=0;i<maxn;i++) head[i]=-1;
}

void add(string st){
	int c=str_hash(st)%maxn;
	str[cnt]=st;
	nextt[cnt]=head[c];
	head[c]=cnt++;
}

bool canfind(string st){
    int c=str_hash(st)%maxn;
    for(int i=head[c];i!=-1;i=nextt[i]){
        if(str[i]==st) return true;
    }
    return false;
}

int main(){
    initial();
	string st;
	while(cin>>st) add(st);
	for(int i=0;i<cnt;i++){
            for(int k=1;k<str[i].length();k++){
                string sub1=str[i].substr(0,k);
                string sub2=str[i].substr(k,str[i].length()-k);
                if(canfind(sub1)  &&  canfind(sub2)){
                    printf("%s\n",str[i].c_str());
                    break;
                }
            }
    }
    return 0;
}

uva 10391 Compound Words (字符串-hash),布布扣,bubuko.com

时间: 2024-10-07 05:26:38

uva 10391 Compound Words (字符串-hash)的相关文章

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(查找)

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

uva 10391 Compound Words

题目:给定一个单词本,要求找出其中的单词,是单词本中某两个单词合并起来得. 思路.先把单词本用字典树保存,然后枚举没个单词的切点,把一个单词分成两部分,去字典树中找即可. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f)

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 261 - The Window Property(字符串Hash)

UVA 261 - The Window Property 题目链接 题意:这题题意挺绕的..就是给定一个字符串长度n,扫描长度为k = [1,n],然后每次只能扫描连续k个字符的子串,要求所有扫描中,每次扫描中出现的不同字符串个数都不超过k + 1,那么这个字符串就是window property,如果不是的话,就还要找出下标最小的不符合的位置(就是n次扫描中找最小的) 思路:Hash大法好,长度才100,直接处理出hash,O(n^2)随便搞掉 代码: #include <cstdio>

UVA 257 - Palinwords(字符串HASH)

UVA 257 - Palinwords 题目链接 题意:输出一个文本里面的palinword,palinword的定义为,包含两个不同的回文子串,并且要求回文子串不能互相包含 思路:对于每个单词判断一次,由于不能互相包含,对于每个位置,其实就只要找长度3和4的情况即可,这样复杂度为O(n),至于判断重复的,就用hash即可 代码: #include <cstdio> #include <cstring> char str[260]; int hash[555555], save[

hdu 1880 魔咒词典(字符串hash)

题目链接:hdu 1880 魔咒词典 题意: 给你一个10w的词典,让你输出对应的字段. 题解: map暴力存字符串肯定会卡内存,这里用BKDR字符串hash一下,用map映射一下. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 6 const int N=1e5+7,seed=133

【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】

[题目大意] 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. [字符串hash的小笔记] hash[i]=(hash[i-1]*p+idx(s[i]))%mod,idx为映射值,一般a..z映射1..26: 习惯上,p取一个6到8位的素数即可,mod一般取大素数 1e9+7(1000000007)或1e9+9(1000000009). hash[i]=(hash[i-1]*p+idx(s[i]))%mod 表示第 i 个前缀的hash值,是一个hash的前缀和,那么,要求S[l…r]