находка — решатель анаграмм в переполнении стека

Я работаю над проектом для школы, и я застрял на том, что я считаю, это лишь малая часть, но я не могу понять это.

Вот что у меня так далеко:

#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
и распечатайте те, которые являются реальными словами.

Я знаю, что мне нужно использовать метод find класса set. Я просто не уверен, как это сделать. Я пытался что-то подобное без удачи, но мой мыслительный процесс, вероятно, неправильно.

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

Если бы вы, ребята, могли помочь или указать мне правильное направление, я был бы очень признателен.

3

Решение

Во-первых, я хотел бы сказать, что это хорошо заданный вопрос. Я ценю новых пользователей, которые нашли время, чтобы подробно сформулировать свою проблему.

Проблема в том, что find() метод 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<>:

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

Другие решения

Вы на самом деле действительно близко к правильному

set::find Метод не возвращает значение, если оно найдено в наборе, а скорее объект итератора, который указывает на значение. Так что ваши if оператор сравнивает текущую строку с возвращенным объектом итератора вместо значения, на которое указывает итератор.

Чтобы получить значение, на которое указывает итератор, нужно просто разыменовать его, как указатель, добавив к нему звездочку. Это означает, что вы, вероятно, намеревались if Заявление выглядит так:

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

Это будет работать для случаев, когда значение было найдено в наборе, но будет проблематичным для случаев, когда значение не найдено. Если значение не найдено, итератор, который указывает на позицию после последний элемент в наборе возвращается — и вы не должны пытаться разыменовать такой итератор (потому что он не указывает на допустимый объект).

Обычно эти проверки выполняются путем сравнения возвращаемого итератора с итератором, который указывает на конец набора (например, в данном случае set :: end). Если итераторы не совпадают, это означает, что элемент был найден.

if (setwords.find(word) != setwords.end())
cout << word << endl;
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;
}
0