2013-04-11 4 views
0

저는 현재 Andrew Koenig와 Barbara Moo가 저술 한 Accelerated C++를 통해 각 장의 모든 연습을하고 C++을 배우고 있습니다.벡터가있는 요소의 발생 횟수를 카운트하십시오.

연습 3-3 : 입력란에 각 단어가 몇 번 나 왔는지 계산하는 프로그램을 작성하십시오.. 나에게이 운동은 특히 다음과 같이 고려하기가 매우 어려워 보였다. 1. 그 장의 예제와 다른 연습은 비교적 간단했다. 2. 오직 벡터 만 사용할 수 있으므로 아무 것도 진전되지 않았다. (또는 단지 내가 어려움을 잘못 판단한 것일뿐입니다)

나는이 웹에서 힌트를 찾았고이 운동에 문제가있는 다른 사람들을 보았습니다. 그러나 사람들이 제공하는 해결책은 저에게 불분명했습니다. 대부분의 사람들은이 책의 뒷부분에 소개 된 정리 방법을 사용하도록 제안했는데, 이는 운동의 요점을 무너 뜨 렸습니다.

#include <algorithm> 
#include <iomanip> 
#include <ios> 
#include <iostream> 
#include <string> 
#include <vector> 

using std::cin; 
using std::setprecision; 
using std::cout; 
using std::string; 
using std::endl; 
using std::streamsize; 
using std::sort; 
using std::vector; 

int main() 
{ 

// Ask for string input 

cout << "Please write some text, followed by end-of-file: " << endl; 

vector<string> word_input; 
string word; 

// input words into string vector word_input 

    typedef vector<string>::size_type vecsize; 


    while (cin >> word) 
    { 
     word_input.push_back(word);     
    } 

// sort the vector in alphabetical order to be able to separate distinct words 

    sort(word_input.begin(),word_input.end()); 

// create two vectors: one where each (string) element is a unique word, and one 
// that stores the index at which a new distinc word appears 

    vector<string> unique_words; 
    vector<int> break_index; 


    for (int i=0; i != word_input.size()-1; ++i) 
    { 
     if(word_input[i+1] != word_input[i]) 
      { 
       unique_words.push_back(word_input[i]); 
       break_index.push_back(i); 
      } 

    } 

// add the last word in the series to the unique word string vector 

    unique_words.push_back(word_input[word_input.size()-1]); 

// create a vector that counts how many times each unique word occurs, preallocate 
// with 1's with as many times a new word occurs in the series (plus 1 to count the first word) 

    vector<int> word_count(1,break_index[0]+1); 

// if a new word occurs, count how many times the previous word occured by subtracting the number of words so far 

    for(int i=0; i != break_index.size()-1;++i) 
     { 
      word_count.push_back(break_index[i+1] - break_index[i]); 
     } 

// add the number of times the last word in the series occurs: total size of text - 1 (index starts at 0) - index at which the last word starts 

    word_count.push_back(word_input.size()-1-break_index[break_index.size()-1]); 


    // number of (distinct) words and their frequency output 

    cout << "The number of words in this text is: " << word_input.size() << endl; 

    cout << "Number of distinct words is: " << unique_words.size() << endl; 

     // The frequency of each word in the text 

     for(int i=0; i != unique_words.size(); ++i) 
      cout << unique_words[i] << " occurs " << word_count[i] << " time(s)" << endl; 



return 0; 
} 

이 사용하는 벡터를 수행하는 더 좋은 방법이 있나요 : 마지막으로, 나는 다른 포럼에서 찾을 방법 내 자신의 해결책을 마련하기 위해 (여기 포함)의 힌트와 비트를 함께 재현? 루프를 결합하여 코드를보다 효율적으로 만들 수 있습니까?

+2

[코드 검토] (http://codereview.stackexchange.com/)에 더 적합합니다. – jrok

+2

Stackoverflow는 코드 리뷰 사이트가 아닙니다. 제 생각에는 운영자 주변의 들여 쓰기와 공간 사용이 이상하게 일치하지 않습니다. 의 std :: unique를 사용하여 두 개의 반복자 사이에서 연속되지 않는 요소를 제거함으로써 단어 목록에서 중복을 제거하는 작업을 통합 할 수 있습니다. – Wug

+0

코드를 매우 빠르게 스캔하면 꽤 많은 로직을 보냈습니다. 이것 때문에. 그것은 컨테이너 (목록/벡터), 모든 단어를 반복하는 루프 및 현재 컨테이너의'if (std :: find())'이어야합니다. 단어가 이미 포함되어있는 경우 (그렇지 않은 경우 삽입하십시오. 소원). 총 단어 수는 컨테이너를 통해 쉽게 검색 할 수 있습니다.size()와 자체적으로 저장해서는 안됩니다. (많이 쓰지 않고, 그냥 necc가 아닙니다) – Najzero

답변

0

누군가 셰익스피어의 전체 작품을 처리하기 위해 코드를 사용한다고 상상한다면, 모든 단어를 저장하여 많은 공간을 낭비하게됩니다. 대신에 "단어"와 "단어의 수"구조를 유지한다면, "the"라는 단어를 한 번만 저장하면됩니다. 심지어 프로그램에 먹이를주는 텍스트가 100000 번 발생하더라도 말입니다. 단어가 한 번 이상 등장했음을 알아야하는 경우도 있습니다. 필요한 모든 단어가 고유 한 단어 목록이라면 필요한 단어를 이미 저장했는지 확인하는 것뿐입니다. [정렬 된 순서로 저장하면 binary_search을 사용하여 코드를 통해 셰익스피어의 800K (고유하지 않은) 단어를 실제로 실행하는 경우 런타임에 도움이됩니다.

+0

인공적인 "벡터 만"제한이 있습니다. – Wug

+0

그래서 "어떤 단어가 있는지"만 필요하다면 벡터에서 "찾기"를 사용하여 이전에이 단어를 본 적이 있는지 확인할 수 있습니다. 모든 단어를 저장하는 대신 나중에 중복을 제거하십시오. –

+0

그래,하지만 그것의 효율성은 끔찍하다. – Wug

1

나에게 효과가있는 해결책 (이 문제를 해결할 때) input_vector, output_vectorcount_vector의 세 벡터를 사용했습니다. 이스케이프 문자를 입력 할 때까지 while을 사용하여 std::cin을 사용하여 사용자 입력을 읽습니다. input_vector.push_back(input_word)을 사용하여 input_vector에 단어를 채 웁니다. <algorithm>std::sort을 사용하여 벡터를 정렬하고 (첫 번째 단어는 input_vector) 및 count_vector (하나의 값 : 1)을 만듭니다.

각 요소에 대해 input_vector (두 번째가 아니라 첫 번째 요소에서 시작)에서 현재 요소가 마지막 요소와 같은지 확인하십시오. 존재하는 경우, count_vector의 현재 요소에 1을 추가하십시오. 그렇지 않은 경우 push_back()을 사용하여 input_vector에서 output_vector까지 현재 단어를 추가하고 count_vector 크기를 한 요소 (값 : 1)만큼 증가시킵니다.

관련 문제