搜索数组以查找单词的单独实例

时间:2014-04-24 05:13:54

标签: c++ search dynamic-arrays

这是我在高级C ++课程中的一项任务,我们正在研究指针和动态分配的数组,但这似乎并不是我的麻烦所在......

函数头,Quote,Words和Count是重要的数组,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循环应该使用** char数组中的新值,遍历Quote以查找该值的其他实例,并在该元素的相同索引号处递增Count。似乎工作......

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

计数器在Words数组中存储了多少个单词,以及函数在Quote数组中的位置。

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循环开始,但我似乎无法使其工作。另一件事是,一旦它将一个单词从Quote复制到Words,它就不应该再复制那个单词。

此外,对代码质量等的一般性输入也会被批准。我以后一直努力成为一名软件工程师,我喜欢做我最擅长的事情,所以我需要尽可能多地学习。

1 个答案:

答案 0 :(得分:0)

您的主要问题是您似乎想要使用i单步执行引用,但同时您正在使用它来索引Words。更合乎逻辑的做法是根据已经复制到Words的现有单词检查引用的每个单词,并相应地递增计数或插入单词。您还可以利用NumWords中最多Words并在函数开头分配足够内存的事实:

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;      
}

在任何情况下,数组/指针shenanigans都难以阅读且容易出错,除了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