2014-03-29 10 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

는 첫째, 나는이 잘 묻는 질문이라고 말하고 싶으면 간단한 해결책에게 있습니다 ..... 정렬 된 단어로 비교합니다. 문제를 명확히 밝힐 수있는 시간을 갖는 새로운 사용자에게 감사드립니다.

std::set<>find() 메서드는 발견 된 값을 가리키는 반복자 개체를 반환하거나 그렇지 않으면 컨테이너의 end()을 반환합니다. str[i] (문자열)과 비교하면 iterator와 문자열을 모두 사용하는 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]) 

이 값이 세트에서 발견 된 경우에 작동합니다, 값이 발견되지 않은 경우에 문제가 될 것입니다. 값이 발견되지 않으면 이후의 위치 을 가리키는 반복자가 반환되고 올바른 객체를 가리 키지 않기 때문에 반복자를 참조하지 마십시오.

일반적으로 이러한 검사는 리턴 된 반복자를 세트의 끝을 가리키는 반복자 (예 : set :: end,이 경우)와 비교하는 방식입니다. 반복자가 일치하지 않으면 해당 항목이 발견되었음을 의미합니다.

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