[英]Anagram solver in C++
我正在為一所學校的項目工作,我堅持認為只是一小部分,但我無法弄明白。
這是我到目前為止:
#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;
如果你們可以幫助或指出我正確的方向,我將非常感激。
首先,我想說這是一個很好問的問題。 我感謝新用戶花時間詳細闡述他們的問題。
問題是std::set<>
的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>());
我想你需要寫這樣的東西:
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;
}
你實際上真的很接近正確。
如果在set::find
該值,則set::find
方法不返回該值,而是返回指向該值的迭代器對象 。 所以你的if
語句將當前字符串與返回的迭代器對象進行比較,而不是迭代器指向的值。
要獲得比迭代器指向的值,您只需要像指針一樣取消引用它,方法是在其前面添加星號。 這意味着您可能希望if
語句看起來像這樣:
if (*(setwords.find(word)) == str[i])
這適用於在集合中找到值的情況,但對於未找到值的情況會有問題。 如果未找到該值,則返回指向集合中最后一項之后的位置的迭代器 - 您不應嘗試取消引用此類迭代器(因為它不指向有效對象)。
通常進行這些檢查的方法是將返回的迭代器與指向集合末尾的迭代器進行比較(例如,在這種情況下為set :: end)。 如果迭代器不匹配,則表示找到了該項。
if (setwords.find(word) != setwords.end())
cout << word << endl;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.