C ++中的Anagram求解器

时间:2014-03-29 23:21:54

标签: c++ find anagram

我正在为一所学校的项目工作,我坚持认为只是一小部分,但我无法弄明白。

这是我到目前为止所做的:

#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    set<string> setwords;
    ifstream infile;
    infile.open("words.txt"); //reads file "words.txt"
    string word = argv[1]; // input from command line
    transform(word.begin(), word.end(), word.begin(), tolower); // transforms word to lower case.
    sort(word.begin(), word.end()); // sorts the word
    vector<string> str; // vector to hold all variations of the word

    do {
        str.push_back(word);
    }
    while (next_permutation(word.begin(), word.end())); // pushes all permutations of "word" to vector str         

    if (!infile.eof())
    {
        string items;
        infile >> items;
        setwords.insert(items); //stores set of words from file
    }

    system("PAUSE");
    return 0;
}

现在我需要比较文件中的单词和vector str中存储的排列 并打印出真实的单词。

我知道我需要使用set类的find方法。我只是不确定该怎么做。我在尝试这样的事情没有运气,但我的思考过程可能是错误的。

for (unsigned int i = 0; i < str.size(); i++)
    if (setwords.find(word) == str[i])
        cout << str[i] << endl;

如果你们可以帮助或指出我正确的方向,我将非常感激。

3 个答案:

答案 0 :(得分:1)

首先,我想说这是一个很好问的问题。我感谢新用户花时间详细阐述他们的问题。

问题是find()的{​​{1}}方法返回指向它找到的值的迭代器对象,或者如果它不能返回容器的std::set<>。 。当你将它与end()(一个字符串)进行比较时,它找不到合适的str[i]重载,它接受迭代器和字符串。

您可以将返回值与operator==()进行比较,以确定是否找到字符串,而不是与字符串进行全面比较:

end()

如果表达式返回if (setwords.find(str[i]) != setwords.end()) // ^^^^^^ ^^^^^^^^^^^^^^ ,那么它就成功找到了集合中的字符串。

还有一个我想在您的代码中解决的潜在问题。使用true是调整输入的错误方法。您应该将提取部分作为条件的一部分,如下所示:

if (!file.eof())

这是另一种方式,使用for (std::string item; infile >> item; ) { setwords.insert(item); }

std::istream_iterator<>

答案 1 :(得分:0)

我认为你需要写下这样的东西:

for (unsigned int i = 0; i < str.size(); i++)
    if (setwords.find(str[i]) != setwords.end())
        cout << str[i] << endl;

但我认为你不需要存储所有的排列。您可以使用已排序的字母存储一组单词。并将其与排序的单词进行比较.....

这里是更简单的解决方案

#include <iostream>                                                                                 
#include <fstream>                                                                                  
#include <string>                                                                                   
#include <locale>                                                                                   
#include <vector>                                                                                   
#include <algorithm>                                                                                
#include <map>                                                                                      

using namespace std;                                                                                

int main(int argc, char* argv[])                                                                    
{                                                                                                   
    map<string, string> mapwords;                                                                   
    ifstream infile;                                                                                
    infile.open("words.txt"); //reads file "words.txt"                                              
    string word = argv[1]; // input from command line                                               
    transform(word.begin(), word.end(), word.begin(), tolower); // transforms word to lower case.   
    sort(word.begin(), word.end()); // sorts the word                                               

    if (!infile.eof())                                                                              
    {                                                                                               
        string item;                                                                                
        infile >> item;                                                                             
        string sorted_item = item;                                                                  
        sort(sorted_item.begin(), sorted_item.end()); // sorts the word                             
        mapwords.insert(make_pair(sorted_item, item)); //stores set of words from file              
    }                                                                                               

    map<string, string>::iterator i = mapwords.find(word);                                          
    if(i != mapwords.end())                                                                         
        cout << i->second << endl;
    system("PAUSE");                                                                  
    return 0;                                                                                       
}   

答案 2 :(得分:0)

你实际上真的接近正确。

set::find方法如果在集合中找到了值,则不返回该值,而是an iterator object that points to the value。因此,您的if语句将当前字符串与返回的迭代器对象进行比较,而不是迭代器指向的值。

要获得比迭代器指向的值,您只需要像指针一样取消引用它,方法是在其前面添加星号。这意味着您可能希望您的if语句如下所示:

if (*(setwords.find(word)) == str[i])

这适用于在集合中找到值的情况,但对于未找到值的情况会有问题。如果找不到该值,则返回指向>集合中最后一项位置的迭代器 - 并且您不应该尝试取消引用这样的迭代器(因为它没有&#39 ; t指向有效对象)。

通常进行这些检查的方法是将返回的迭代器与指向集合末尾的迭代器进行比较(例如,在这种情况下为set :: end)。如果迭代器不匹配,则表示找到了该项。

if (setwords.find(word) != setwords.end())
    cout << word << endl;