简体   繁体   English

动态内存分配,C ++

[英]Dynamic memory allocation, C++

I need to write a function that can read a file, and add all of the unique words to a dynamically allocated array. 我需要编写一个可以读取文件的函数,并将所有唯一的单词添加到动态分配的数组中。 I know how to create a dynamically allocated array if, for instance, you are asking for the number of entries in the array: 我知道如何创建一个动态分配的数组,例如,如果你要求数组中的条目数:

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

My problem is that I don't know ahead of time how many unique words are going to be in the file, so I can't initially just read the value or ask for it. 我的问题是我提前不知道文件中有多少个独特的单词,所以我最初不能只读取值或要求它。 Also, I need to make this work with arrays, and not vectors. 此外,我需要使用数组,而不是向量。 Is there a way to do something similar to a push_back using a dynamically allocated array? 有没有办法使用动态分配的数组执行类似于push_back的操作?

Right now, the only thing I can come up with is first to create an array that stores ALL of the words in the file (1000), then have it pass through it and find the number of unique words. 现在,我唯一能想到的就是首先创建一个存储文件中所有单词的数组(1000),然后让它通过它并找到唯一单词的数量。 Then use that value to create a dynamically allocated array which I would then pass through again to store all the unique words. 然后使用该值创建一个动态分配的数组,然后我再次通过该数组来存储所有唯一的单词。 Obviously, that solution sounds pretty overboard for something that should have a more effective solution. 显然,对于应该有更有效解决方案的东西来说,这个解决方案听起来非常落伍。

Can someone point me in the right direction, as to whether or not there is a better way? 有人能指出我正确的方向,是否有更好的方法? I feel like this would be rather easy to do with vectors, so I think it's kind of silly to require it to be an array (unless there's some important thing that I need to learn about dynamically allocated arrays in this homework assignment). 我觉得这对矢量来说相当容易,所以我认为要求它成为一个数组是有点愚蠢的(除非在这个家庭作业中需要了解动态分配数组的一些重要事项)。

EDIT: Here's another question. 编辑:这是另一个问题。 I know there are going to be 1000 words in the file, but I don't know how many unique words there will be. 我知道文件中会有1000个单词,但我不知道会有多少个单词。 Here's an idea. 这是一个想法。 I could create a 1000 element array, write all of the unique words into that array while keeping track of how many I've done. 我可以创建一个1000个元素的数组,将所有独特的单词写入该数组,同时跟踪我已完成的数量。 Once I've finished, I could provision a dynamically allocate a new array with that count, and then just copy the words from the initial array to the second. 完成后,我可以配置一个动态分配带有该计数的新数组,然后将这些单词从初始数组复制到第二个数组。 Not sure if that's the most efficient, but with us not being able to use vectors, I don't think efficiency is a huge concern in this assignment. 不确定这是否最有效,但由于我们无法使用向量,我认为效率不是这项任务中的一个重要问题。

A vector really is a better fit for this than an array. 矢量确实比数组更适合这种情况。 Really. 真。

But if you must use an array, you can at least make it behave like a vector :-). 但是如果你必须使用一个数组,你至少可以使它像一个向量:-)。

Here's how: allocate the array with some capacity. 方法如下:分配具有一定容量的阵列。 Store the allocated capacity in a "capacity" variable. 将分配的容量存储在“容量”变量中。 Each time you add to the array, increment a separate "length" variable. 每次添加到数组时,都会增加一个单独的“length”变量。 When you go to add something to the array and discover it's not big enough (length == capacity), allocate a second, longer array, then copy the original's contents to the new one, then finally deallocate the original. 当您向数组添加内容并发现它不够大(长度==容量)时,分配第二个更长的数组,然后将原始内容复制到新数组,最后释放原始数据。

This gives you the effect of being able to grow the array. 这为您提供了能够增长阵列的效果。 If performance becomes a concern, grow it by more than one element at a time. 如果性能成为一个问题,一次增加多个元素。

Congrats, after following these easy steps you have implemented a small subset of std::vector functionality atop an array! 恭喜,按照这些简单的步骤,您已经在数组上实现了一小部分std :: vector功能!

As you have rightly pointed out this is trivial with a Vector. 正如你正确指出的那样,这对于Vector来说是微不足道的。

However, given that you are limited to using an array, you will likely need to do one of the following: 但是,鉴于您仅限于使用数组,您可能需要执行以下操作之一:

  1. Initialize the array with a suitably large size and live with poor memory utilization 以适当大的大小初始化阵列,并且内存利用率很低
  2. Write your own code to dynamically increase the size of the array at run time (basically the internals of a Vector) 编写自己的代码以在运行时动态增加数组的大小(基本上是Vector的内部)

If you were permitted to do so, some sort of hash map or linked list would also be a good solution. 如果您被允许这样做,某种哈希映射或链表也将是一个很好的解决方案。

If I had to use an array, I'd just allocate one with some initial size, then keep doubling that size when I fill it to accommodate any new values that won't fit in an array with the previous sizes. 如果我必须使用一个数组,我只需要分配一个具有一些初始大小的数组,然后在填充它时保持该大小加倍,以适应任何不适合具有先前大小的数组的新值。

Since this question regards C++, memory allocation would be done with the new keyword. 由于这个问题涉及C ++,因此内存分配将使用new关键字完成。 But what would be nice is if one could use the realloc() function, which resizes the memory and retains the values in the previously allocated memory. 但更好的是,如果可以使用realloc()函数,该函数调整内存大小并保留先前分配的内存中的值。 That way one wouldn't need to copy the new values from the old array to the new array. 这样就不需要将新值从旧数组复制到新数组。 Although I'm not so sure realloc() would play well with memory allocated with new . 虽然我不太确定realloc()可以很好地分配new内存。

You can "resize" array like this ( N is size of currentArray , T is type of its elements): 您可以像这样“调整”数组( NcurrentArray大小, 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;

Using this solution you have to copy the data. 使用此解决方案,您必须复制数据。 There might be a solution that does not require it. 可能有一个不需要它的解决方案。

But I think it would be more convenient for you to use std::vectors . 但我认为使用std :: vectors会更方便。 You can just push_back into them and they will resize automatically for you. 你可以只的push_back到他们,他们会自动调整你的。

You can cheat a bit: 你可以作弊:

use std::set to get all the unique words then copy the set into a dynamically allocated array (or preferably vector). 使用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]);

This could be going a bit overboard, but you could implement a linked list in C++... it would actually allow you to use a vector-like implementation without actually using vectors (which are actually the best solution). 这可能有点过分,但你可以在C ++中实现一个链表...它实际上允许你使用类似矢量的实现而不实际使用向量(这实际上是最好的解决方案)。

The implementation is fairly easy: just a pointer to the next and previous nodes and storing the "head" node in a place you can easily access to. 实现相当简单:只需指向下一个和上一个节点的指针,并将“head”节点存储在您可以轻松访问的位置。 Then just looping through the list would let you check which words are already in, and which are not. 然后只需循环遍历列表就可以检查哪些单词已经存在,哪些不存在。 You could even implement a counter, and count the number of times a word is repeated throughout the text. 你甚至可以实现一个计数器,并计算一个单词在整个文本中重复的次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM