我需要编写一个可以读取文件的函数,并将所有唯一字添加到动态分配的数组中。我知道如何创建一个动态分配的数组,例如,如果你要求数组中的条目数:
int value;
cin >> value;
int *number;
number = new int[value];
我的问题是我提前不知道文件中会有多少独特的单词,所以我最初不能只读取该值或要求它。此外,我需要使用数组,而不是向量。有没有办法使用动态分配的数组执行类似于push_back的操作?
现在,我唯一能想到的就是首先创建一个存储文件中所有单词的数组(1000),然后让它通过它并找到唯一单词的数量。然后使用该值创建一个动态分配的数组,然后我再次通过该数组来存储所有唯一的单词。显然,对于应该有更有效解决方案的东西来说,这个解决方案听起来非常落伍。
有人能指出我正确的方向,是否有更好的方法?我觉得这对矢量来说相当容易,所以我认为要求它成为一个数组是有点愚蠢的(除非在这个家庭作业中需要了解动态分配数组的重要事项)。
编辑:这是另一个问题。我知道文件中会有1000个单词,但我不知道会有多少个单词。这是一个想法。我可以创建一个1000个元素的数组,将所有独特的单词写入该数组,同时跟踪我已完成的数量。完成后,我可以配置一个动态分配带有该计数的新数组,然后将这些单词从初始数组复制到第二个数组。不确定这是否最有效,但由于我们无法使用向量,我认为效率不是这项任务中的一个大问题。答案 0 :(得分:6)
矢量确实比数组更适合这种情况。真。
但是如果你必须使用一个数组,你至少可以使它像一个向量: - )。
以下是:分配具有一定容量的阵列。将分配的容量存储在“容量”变量中。每次添加到数组时,都会增加一个单独的“length”变量。当您向数组添加内容并发现它不够大(长度==容量)时,分配第二个更长的数组,然后将原始内容复制到新数组,最后释放原始数据。
这为您提供了能够增长数组的效果。如果性能成为一个问题,请一次增加多个元素。
恭喜,在按照这些简单步骤后,您已在数组顶部实现了一小部分std :: vector功能!
答案 1 :(得分:2)
正如你正确地指出,这对于Vector来说是微不足道的。
但是,鉴于您仅限于使用数组,您可能需要执行以下操作之一:
如果您被允许这样做,某种哈希映射或链接列表也将是一个很好的解决方案。
答案 2 :(得分:2)
如果我必须使用一个数组,我只需要分配一个具有一些初始大小的数组,然后在填充它时保持该大小加倍,以适应任何不适合具有先前大小的数组的新值。 / p>
由于这个问题涉及C ++,内存分配将使用new
关键字完成。但更好的是,如果可以使用realloc()
函数,它会调整内存大小并保留先前分配的内存中的值。这样就不需要将新值从旧数组复制到新数组。虽然我不太确定realloc()
能够很好地使用new
分配的内存。
答案 3 :(得分:1)
您可以像这样“调整”数组(N
的大小为currentArray
,T
是其元素的类型):
// 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”节点存储在您可以轻松访问的位置。然后只需循环遍历列表就可以检查哪些单词已经存在,哪些不存在。你甚至可以实现一个计数器,并计算一个单词在整个文本中重复的次数。