• Uva10191 复合词


    题目描述:

    给出一个按字母序排列的单词列表,找到其中存在的复合词。复合词的定义是由单词列表中其他的两个单词拼接而成。所有单词均为小写。

    思路:

    如果直接两层遍历所有的单词组合,看他们加在一起是否是单词列表中的一个,在输入如此大的情况下,肯定会超时。我的做法是,定义vector<string> svec[26],将单词按首字母分别存放在svec[i]里,对一个复合词,他的前半部分单词首字母和他相同,先在svec[i]里找前半部分单词,如果存在那么再去找后半部分单词,根据后半部分单词的首字母容易定位到是在svec[j]查找。

    ​需注意的细节:输出的复合词不重复出现,故用set保存答案,同时也完成了按字母序输出的要求。

    代码:

    "点击查看代码"
    
    #include <iostream>
    #include <map>
    #include <string>
    #include <vector>
    #include <set>
    using namespace std;
    

    bool preword(string s1, string s2){ //判断s1是否是s2的前缀
    if(s1.size() > s2.size()) return false;
    int i = 0;
    for(; i < s1.size(); ++i){
    if(s1[i] != s2[i]) break;
    }
    if(i == s1.size()) return true;
    else return false;
    }

    int main()
    {
    string s;
    map<string, int> smap;
    vector svec[26];
    string compound;
    set ans;
    while(cin >> s){
    svec[s[0]-'a'].push_back(s); //按首字母分别存放
    }
    for(int i = 0; i < 26; ++i){ //对a~z的每一个首字母
    for(int j = 0; j < svec[i].size(); ++j){
    for(int k = 0; k < j; ++k){ //因为输入是按字母序输入的,所以svec[i][j]是在svec[i][j]后面的单词
    if(preword(svec[i][k], svec[i][j])){ //如果k是j的前缀
    string s = svec[i][j].substr(svec[i][k].size(), svec[i][j].size() - svec[i][k].size()); //再考虑后半部分字串
    for(int m = 0; m < svec[s[0]-'a'].size(); ++m){ //看后半部分字串是否是svec[s[0]-'a']中的单词
    if(s.compare(svec[s[0]-'a'][m]) == 0) ans.insert(svec[i][j]);
    }
    }
    }
    }
    }
    for(auto c : ans){
    cout << c << " ";
    }
    }

    上述做法的比较麻烦,效率不高,其实还有更好的做法,对每个单词做拆分,利用map来对拆分的子串判断是否是输入之中的单词。代码如下:

    "点击查看代码"
    
    #include <iostream>
    #include <map>
    #include <string>
    #include <vector>
    #include <set>
    using namespace std;
    const int maxn = 120002;
    string sarr[maxn];
    int main()
    {
    	set ans;
    	int cnt = 0;
    	map smap;
    	while(cin >> sarr[cnt]){
    		smap[sarr[cnt]] = 1;
    		++cnt;
    	}
    	for(int i = 0; i < cnt; ++i){
    
    	for(unsigned j = 0; j < sarr[i].size(); ++j){
    		string a = sarr[i].substr(0, j+1);
    		if(!smap.count(a)) continue;
    		string b = sarr[i].substr(j+1);
    		if(!smap.count(b)) continue;
    		ans.insert(sarr[i]); break;
    	}
    }
    for(auto c : ans)
    	cout << c << "
    ";
    

    }

  • 相关阅读:
    包和模块的导入问题
    第9.6节 Python使用read函数读取文件内容
    第9.5节 Python的readlines读取文件内容及其参数hint使用分析
    第9.4节 Python中用readline读取二进制文件方式打开文件
    第9.3节 Python的文件行读取:readline
    第9.2节 Python的文件打开函数open详解
    第9.1节 Python的文件打开函数open简介
    第九章 Python文件操作
    第8.34节 《Python类中常用的特殊变量和方法》总结
    第8.33节 Python中__getattr__以及__getattr__与__ getattribute__的关系深入剖析
  • 原文地址:https://www.cnblogs.com/patrolli/p/11284802.html
Copyright © 2020-2023  润新知