2014-03-29 32 views
3

我正在爲一所學校的項目工作,但我堅持我認爲只是一小部分,但我無法弄清楚。C語言中的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; 
} 

現在我需要比較從文件存儲在向量str 文字和排列打印出是真實的話的人。

我知道我需要使用set類的find方法。我只是不知道該怎麼去做。我正在嘗試這樣沒有運氣,但我的思維過程可能是錯誤的。

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

如果你們可以幫助或指引我在正確的方向,我將不勝感激。

+0

+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;                      
} 
1

首先,我想說,這是一個精心問的問題。我感謝新用戶花時間詳細闡述他們的問題。

問題是的find()方法返回指向它找到的值的迭代器對象,或者如果容器不能,則返回容器的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<>

setwords.insert(std::istream_iterator<std::string>(infile), 
       std::istream_iterator<std::string>()); 
0

你其實是真的接近做對了。

set::find方法不會返回值,如果它在集中找到,而是an iterator object that points to the value。因此,您的if語句將當前字符串與返回的迭代器對象進行比較,而不是迭代器指向的值。

得到比一個迭代點的值,你就必須取消對它的引用,就像您的指針,用星號前綴它。這意味着你可能是爲了你的if聲明是這樣的:

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

這將工作當值已經在集中找到的情況下,但會爲其中的價值沒有被發現的情況是有問題的。如果未找到該值,則返回指向之後位置的迭代器,並返回該集合中的最後一項 - 並且不應嘗試取消引用這樣的迭代器(因爲它不指向有效對象)。

這些檢查通常進行的方法是通過比較指向集的末尾迭代器中的返回的迭代(例如,設置::端,在這種情況下)。如果迭代器不匹配,則表示該項目已找到。

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