C++ 在单词中查找字谜
C++ Finding Anagrams in words
我正在开发一个程序,该程序使用std:count
查看特定单词是否是字谜,但是,我认为我的函数逻辑不正确,我似乎无法弄清楚。
假设文件中有以下单词:
Evil
Vile
Veil
Live
我的代码如下:
#include <iostream>
#include <vector>
#include <fstream>
#include <map>
using namespace std;
struct Compare {
std::string str;
Compare(const std::string& str) : str(str) {}
};
bool operator==(const std::pair<int, std::string>&p, const Compare& c) {
return c.str == p.second;
}
bool operator==(const Compare& c, const std::pair<int, std::string>&p) {
return c.str == p.second;
}
std::vector<std::string> readInput(ifstream& file)
{
std::vector<std::string> temp;
string word;
while (file >> word)
{
temp.push_back(word);
}
std::sort(temp.begin(), temp.end());
return temp;
}
int main(int argc, char *argv[]) {
string file = "testing.txt";
ifstream ss(file.c_str());
if(!ss.is_open())
{
cerr << "Cannot open the text file";
}
std::vector<std::string> words = readInput(ss);
std::map<int, std::string> wordsMap;
//std::map<std::string value, int key> values;
for(unsigned i=0; (i < words.size()); i++)
{
wordsMap[i] = words[i];
}
int count = std::count(wordsMap.begin(), wordsMap.end(), Compare("Evil"));
cout << count << endl;
}
我很确定这只是我的逻辑在函数中错误的情况。我希望有人可以帮助:)
最简单的方法是
像下面这样检查(伪代码)
bool isAnagram(string s, string t) {return sort(s) == sort(t); }
所以,用一些像下面这样的想法,不需要std::map
struct Compare {
std::string str;
Compare(const std::string& x) : str(x) {
std::sort(str.begin(),str.end()); std::transform(str.begin(),
str.end(),str.begin(), ::toupper);}
bool operator ()(const std::string& t)
{
std::string s= t;
std::transform(s.begin(), s.end(),s.begin(), ::toupper);
std::sort(s.begin(),s.end());
return s == str;
}
};
然后
int count = std::count_if(words.begin(), words.end(), Compare("Evil"));
看这里
这不是最有效的算法,但对程序的快速更改可能是:
bool operator==(const std::pair<int, std::string>&p, const Compare& c) {
std::string a = c.str;
std::transform(a.begin(), a.end(), a.begin(), ::tolower);
std::sort(a.begin(), a.end());
std::string b = p.second;
std::transform(b.begin(), b.end(), b.begin(), ::tolower);
std::sort(b.begin(), b.end());
return a == b;
}
编辑:似乎在您当前的代码中,您正在检查字符串是否彼此完全相等(不是字谜)。
相反:
对于每个单词,创建一个包含 26 个元素的数组,每个元素对应于字母表中的一个字母。逐个字符解析每个单词,并增加相应数组中特定字符的计数。
例如,对于邪恶,数组将是:
0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0. // It has 1's for letters e,v,i and l
a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
您可以为每个单词创建此数组。在您的情况下,所有单词将具有相同的数组。然后逐个比较这些数组并相应地继续。
现在你只需要看看哪些单词具有相同的对应数组。
如果要成对比较所有 N 个单词,可以使用 O(N^2) 复杂度中的两个嵌套循环来实现。
比较一对的复杂度为 O(1)。
创建数组的复杂性 = O(L),其中 L 是字符串的长度。
请考虑以下事项:
map<string, set<string>> anagrams;
for (auto word : words)
anagrams[sort(word)].insert(word);
const set<string>& find_anagrams(const string& word)
{
return anagrams[word];
}
当你有很多相对较短的单词时(或者如果你可以使用大量的库),那么你可以使用类似于我在这里写的解决方案——
为所有字谜生成相同的唯一哈希代码
本质上 - 将每个字符映射到一个唯一的素数(不必很大,您可以将整个 ABC 映射到最多 101 的素数),并且对于每个单词,乘以从它收到的素数字符。由于乘法是可交换的,字谜会给出相同的结果,所以你只需比较这个结果,散列它,或者做任何你想做的事情
请记住,对于长单词,值会增长得非常快,因此您可能需要一个大数字库
- 在 c++ 中查找字符串中没有循环的数字总和
- 以C++递归方式查找向量中的最大值
- 查找矩阵中单元格的相邻元素
- 当您在此单词中搜索单词时调整字符数组的大小?
- 用于查找网格中最短路径的算法
- 从文件中查找单词并替换到其他文件中
- 如何创建一个函数,该函数在文本中查找单词的匹配项,包括跳过
- 在字典中查找单词模式,高性能
- 查找单词最多的行并将其输出到文本文件中.C++
- 在句子中查找单词
- C++帮助:使用数组和循环在文本中查找单词
- C++ 在单词中查找字谜
- std::regex查找字符串中括号内的单词,然后替换它(和括号)
- 在文件中查找单词
- 如何使用' string::find '通过C++在文件中查找单词
- C++在不带Regex的字符串中查找单词
- 在矢量<string> cocos2d-x 中查找单词
- 通过语音在字典中查找单词
- 在 C++ 的文本中查找单词
- C++ 我们如何从文本文件中查找单词的每一行