2014-04-24 6 views
0

이것은 내 고급 C++ 클래스에서의 할당이며, 포인터와 동적으로 할당 된 배열을 처리합니다. 그러나 내 문제가있는 곳에서는 보이지 않습니다.배열을 검색하여 단어의 개별 인스턴스를 찾습니다.

함수 머리글, 따옴표, 단어 및 개수는 중요한 배열이며 NumWords는 Quote 배열에있는 요소 수를 계산합니다.

void CountWords (char ** Quote, char **& Words, int *& Count, int NumWords) 
{ 

변수 등 일부 변수는 main에서 포인터로 전달됩니다.

char ** Temp = nullptr; 
    int * ITemp = nullptr; 
    int WordCount = 0; 
    int QuoteCount = 0; 

다음은 For 루프의 프라이밍 읽기입니다. 동적으로 할당 된 두 개의 배열을 생성합니다. 하나는 Quote 배열에 단어의 새로운 인스턴스를 저장하고, 다른 하나는 Quote 배열에 단어가 몇 번 있었는지를 저장하는 것입니다. 이 모든 것이 잘 작동하는 것처럼 보입니다. 그러나 나는이 모든 것이 얼마나 다르게 시작되었는지에 대한 조언이 우수 할 것입니다 (Code Bloat)가 얼마나 큰지는 싫어합니다.

char의 첫 번째 동적 배열입니다.

Temp = new char * [WordCount + 1]; 
    for (int z = 0; z < WordCount; z++) 
    { 
     Temp[z] = Words[z]; 
    } 
Temp[WordCount] = new char[ strlen(Quote[WordCount]) +1 ]; 
strcpy(Temp[WordCount], Quote[WordCount]); 
delete [] Words; 
Words = Temp; 

int의 두 번째 동적 배열. 루프

ITemp = new int [ WordCount + 1 ]; 
    for (int z = 0; z < WordCount; z++) 
    { 
     ITemp[z] = Count[z]; 
    } 
ITemp[WordCount] = 0; 
delete [] Count; 
Count = ITemp; 

은 ** 문자 배열 새로운 값을 사용하여 그 값의 다른 예를 찾을 견적을 반복하고, 단위는 그 요소에 대해 동일한 인덱스 번호에 개수로되어있다. 말씀 배열에 저장하고, 어디 기능이있는 견적 배열되어 얼마나 많은 단어를 ...

for (int j = 0; j < NumWords; j++) 
{ 
    if (_stricmp(Words[ WordCount ], Quote[j]) == 0) 
    { 
    Count[ WordCount ]++; 
    } 
} 

카운터를 작동하는 것 같다.

WordCount++; 
QuoteCount++; 

일이 남았습니다 이동하기 시작하는 곳은 ...

for (int i = 0; i < NumWords; i++) 
{ 

//Right here is where the program breaks, after the second iteration of this 
//For-loop. What happens is the loop counter (i) increments to 2 shortly 
//before Words[2] gets created. I've tried decrementing i inside the If, 
//where QuoteCount gets incremented, but that causes an out-of-bounds error 
//on the Quote array on the last iteration. 

//Check to see if Quote value is in Words 
if (_stricmp(Quote[ QuoteCount ], Words[ i ]) == 0) 
{ 
    //If true, move on to next element in Quote array. 
    QuoteCount++; 
} 

//If false, write Quote value to Words 
else 
{ 
     Temp = new char * [WordCount + 1]; 
     for (int z = 0; z < WordCount; z++) 
     { 
      Temp[z] = Words[z]; 
     } 
     Temp[WordCount] = new char[ strlen(Quote[WordCount]) +1 ]; 
     strcpy(Temp[WordCount], Quote[WordCount]); 
     delete [] Words; 
     Words = Temp; 

//Create new array element in Count to track new value in Words 
     ITemp = new int [ WordCount + 1 ]; 
     for (int z = 0; z < WordCount; z++) 
     { 
      ITemp[z] = Count[z]; 
     } 
     ITemp[WordCount] = 0; 
     delete [] Count; 
     Count = ITemp; 


//Check Quote for other instances of Word 
     for (int j = 0; j < NumWords; j++) 
     { 
      if (_stricmp(Words[ WordCount ], Quote[j]) == 0) 
      { 
      Count[ WordCount ]++; 
      }//if 
     }//for 
//Increment word counter, indicating a new word was stored. 

     WordCount++; 

    }//else 
}//for 
}//function 

나는이 훨씬 더 복잡가 필요 이상이되었다 생각합니다. for-loops를 중첩 시키려고했지만 그 중 하나를 작동시키지 못했습니다. 또 다른 한 가지는 인용문에서 단어로 단어를 복사 한 후에는 해당 단어를 다시 복사해서는 안됩니다.

또한 코드 품질 등에 대한 일반적인 입력이 가능합니다. 나는 나중에 인생에서 소프트웨어 엔지니어가되기 위해 노력하고 있으며, 나는 내가하는 일에서 최고가되고 싶다. 그래서 나는 항상 할 수있는 한 많이 배워야한다.

+0

당신이'string'와'vector' 같은 표준 컨테이너를 사용하는 것을 금지하고 있습니까? – user657267

+0

'벡터'가 없습니다. 우리는 아직 그것에 도달하지 않았습니다. 'string'에 대해서는'cstring'을 의미합니까? 제 생각에는'strstr','strtok','strchr' 함수가이 장에서 소개되었습니다. – Teravian

+0

아니요,'std :: string'을 의미하는 것은 아니지만 지금은 어려운 일을하는 것처럼 붙어있는 것 같습니다. – user657267

답변

0

귀하의 주된 문제는 i을 사용하여 견적을 단계별로 진행하고 싶지만 동시에 색인을 사용하여 Words입니다. 일을하는 더 논리적 인 방법은 이미 Words에 복사 한 기존 단어에 대한 견적의 각 단어를 확인하고 그에 따라 단어를 추가하거나 삽입하는 것입니다. 또한 Words에서에서 가장 NumWords이있을 것이라는 사실을 활용하고 함수의 시작 부분에 충분한 메모리를 할당 할 수 있습니다 : 어떤 경우 배열에

void CountWords(char const** Quote, char**& Words, int*& Count, int NumWords) 
{ 
    Words = new char*[NumWords]; 
    Count = new int[NumWords]; 

    int words = 0; 

    for (int i = 0; i < NumWords; ++i) { 

    int j = 0; 
    for (; j < words; ++j) { 

     if (!strcmp(Quote[i], Words[j])) { // Duplicate word 
     ++Count[j]; 
     break; 
     } 
    } 

    if (j == words) { // New word found 
     Words[words] = new char[strlen(Quote[i]) + 1]{}; 
     strcpy(Words[words], Quote[i]); 
     Count[words] = 1; 
     words++; 
    } 
    } 

    Count[words] = 0; 
} 

int main() 
{ 
    char const* quote[] = {"Hello", "world", "hello", "world"}; 
    char** words; 
    int* count; 
    CountWords(quote, words, count, 4); 

    for (int i = 0; count[i]; ++i) { 
    std::cout << words[i] << ' ' << count[i] << '\n'; 
    delete[] words[i]; 
    } 

    delete[] words; 
    delete[] count;  
} 

/포인터 헛소리를 읽기 어려울 오류가 발생하기 쉬운입니다 new을 제외하고 "C++"라고 불릴 수있는 코드는 거의 없습니다. 원래 코드는 C++의 대시로 c입니다.전체 응용 프로그램은 더 쉽게이 같은 현대 C++로 작성할 수 있습니다 :

#include <iostream> 
#include <unordered_map> 

int main() 
{ 
    std::string word; 
    std::unordered_map<std::string, int> map; 

    while (std::cin >> word) 
    ++map[word]; 

    for (auto const& w : map) 
    std::cout << w.first << " : " << w.second << '\n'; 
} 

그리고 다음과 같이 사용 : app < textfile.txt

+0

이것은 완벽하게 작동하는 것 같습니다. 새로운 Count 배열의 모든 요소에 0을 쓰려면 시작 부분에 For 루프를 넣어야했습니다. 그 외, 환상! 정말 고맙습니다. 나는 내 머리카락을 꺼내려고했다 ... – Teravian

+0

@Teravian Good catch! 이 물건을 잘못 먹는 것이 얼마나 쉬운 지 보여줍니다. 또 다른 옵션은'Count [words] ++;를 Count [words] = 1;로 변경하는 것입니다. 다음과 같이 배열을 0으로 만들 수도 있습니다 :'Count = new int [NumWords] {};' – user657267