动态内存分配,C ++

时间:2012-01-29 03:46:38

标签: c++ arrays vector

我需要编写一个可以读取文件的函数,并将所有唯一字添加到动态分配的数组中。我知道如何创建一个动态分配的数组,例如,如果你要求数组中的条目数:

int value;
cin >> value;
int *number;
number = new int[value];

我的问题是我提前不知道文件中会有多少独特的单词,所以我最初不能只读取该值或要求它。此外,我需要使用数组,而不是向量。有没有办法使用动态分配的数组执行类似于push_back的操作?

现在,我唯一能想到的就是首先创建一个存储文件中所有单词的数组(1000),然后让它通过它并找到唯一单词的数量。然后使用该值创建一个动态分配的数组,然后我再次通过该数组来存储所有唯一的单词。显然,对于应该有更有效解决方案的东西来说,这个解决方案听起来非常落伍。

有人能指出我正确的方向,是否有更好的方法?我觉得这对矢量来说相当容易,所以我认为要求它成为一个数组是有点愚蠢的(除非在这个家庭作业中需要了解动态分配数组的重要事项)。

编辑:这是另一个问题。我知道文件中会有1000个单词,但我不知道会有多少个单词。这是一个想法。我可以创建一个1000个元素的数组,将所有独特的单词写入该数组,同时跟踪我已完成的数量。完成后,我可以配置一个动态分配带有该计数的新数组,然后将这些单词从初始数组复制到第二个数组。不确定这是否最有效,但由于我们无法使用向量,我认为效率不是这项任务中的一个大问题。

6 个答案:

答案 0 :(得分:6)

矢量确实比数组更适合这种情况。真。

但是如果你必须使用一个数组,你至少可以使它像一个向量: - )。

以下是:分配具有一定容量的阵列。将分配的容量存储在“容量”变量中。每次添加到数组时,都会增加一个单独的“length”变量。当您向数组添加内容并发现它不够大(长度==容量)时,分配第二个更长的数组,然后将原始内容复制到新数组,最后释放原始数据。

这为您提供了能够增长数组的效果。如果性能成为一个问题,请一次增加多个元素。

恭喜,在按照这些简单步骤后,您已在数组顶部实现了一小部分std :: vector功能!

答案 1 :(得分:2)

正如你正确地指出,这对于Vector来说是微不足道的。

但是,鉴于您仅限于使用数组,您可能需要执行以下操作之一:

  1. 使用适当大的内容初始化阵列并且内存利用率很低
  2. 编写自己的代码以在运行时动态增加数组的大小(基本上是Vector的内部)
  3. 如果您被允许这样做,某种哈希映射或链接列表也将是一个很好的解决方案。

答案 2 :(得分:2)

如果我必须使用一个数组,我只需要分配一个具有一些初始大小的数组,然后在填充它时保持该大小加倍,以适应任何不适合具有先前大小的数组的新值。 / p>

由于这个问题涉及C ++,内存分配将使用new关键字完成。但更好的是,如果可以使用realloc()函数,它会调整内存大小并保留先前分配的内存中的值。这样就不需要将新值从旧数组复制到新数组。虽然我不太确定realloc()能够很好地使用new分配的内存。

答案 3 :(得分:1)

您可以像这样“调整”数组(N的大小为currentArrayT是其元素的类型):

// create new array
T *newArray = new T[N * 2];
// Copy the data
for ( int i = 0; i < N; i++ )
 newArray[i] = currentArray[i];
// Change the size to match
N *= 2;
// Destroy the old array
delete [] currentArray;
// set currentArray to newArray
currentArray = newArray;

使用此解决方案,您必须复制数据。可能有一个不需要它的解决方案。

但我认为使用std::vectors会更方便。您只需push_back进入它们,它们就会自动为您调整大小。

答案 4 :(得分:1)

你可以作弊:

使用std :: set获取所有唯一的单词,然后将该集合复制到动态分配的数组(或最好是向量)。

#include <iterator>
#include <set>
#include <iostream>
#include <string>


    // Copy into a set
    // this will make sure they are all unique   
    std::set<std::string>   data;
    std::copy(std::istream_iterator<std::string>(std::cin),
              std::istream_iterator<std::string>(),
              std::inserter(data, data.end()));

    // Copy the data into your array (or vector).
    std::string* words  = new std::string[data.size()];
    std::copy(data.begin(), data.end(), &words[0]);

答案 5 :(得分:0)

这可能会有点过分,但你可以在C ++中实现一个链表...它实际上允许你使用类似矢量的实现而不实际使用矢量(这实际上是最好的解决方案)。

实现相当简单:只是指向下一个和上一个节点的指针,并将“head”节点存储在您可以轻松访问的位置。然后只需循环遍历列表就可以检查哪些单词已经存在,哪些不存在。你甚至可以实现一个计数器,并计算一个单词在整个文本中重复的次数。