简体   繁体   English

2d矢量初始化

[英]2d Vector Initialization

I gave up on trying to pass a 2d array to a function, where the dimensions are not known at compile time. 我放弃了尝试将2d数组传递给函数,其中维度在编译时是未知的。 After some research, it seems like a 2d vector may be a good substitute. 经过一些研究,似乎二维矢量可能是一个很好的替代品。 I just want to confirm that this is the correct way to declare a 2d vector of dimension totalRows X totalColumns, initializaing each cell to contain the space character: 我只想确认这是声明一个维度totalRows X totalColumns的二维向量的正确方法,初始化每个单元格以包含空格字符:

vector<vector<char> > world(totalRows, vector<char>(totalColumns, ' '));

The line itself should work and looks fine. 线本身应该工作,看起来很好。 But let me offer a bit more information. 但是,让我提供更多信息。

It is a good idea to try and make use of the standard library. 尝试使用标准库是个好主意。 With that said, you need to understand that the image of a 2D array you have in your head must exist linearly in memory. 话虽如此,你需要了解你头脑中的2D阵列图像必须在内存中线性存在。 You can easily create an m*n element vector of chars (in your example) and index it row-major wise as (i*n + j) (courtesy of zero-based counting). 您可以轻松地创建一个字符的m * n元素向量(在您的示例中),并将其作为行(主要是明确的)索引为(i * n + j)(由零基计数提供)。

In fact, that's the way "two dimensional" arrays work. 事实上,这就是“二维”阵列的工作方式。 For example, when you do a regular array of elements - T[][] , if you try to decay it into a pointer, it'll be a simple T* . 例如,当你做一个常规的元素数组T[][] ,如果你试图将它衰减成一个指针,它将是一个简单的T* Under the hood, memory is laid out contiguously and linearly, there are no shapes, just one long street (as the computer sees it). 在引擎盖下,记忆是连续和线性布局的,没有形状,只有一条长街(就像计算机看到的那样)。 And it simply infers the notion of rows and columns as humans see it by using the expression (or a similar one) in the first paragraph. 它只是通过使用第一段中的表达式(或类似的)来推断行和列的概念。 The computer doesn't care. 电脑不关心。

vector is a nice part of the standard library which encapsulates arrays in a way that is signature C++ (and not just bloated C). vector是标准库的一个很好的部分,它以一种签名C ++(而不仅仅是膨胀的C)的方式封装数组。 Its very design enables easy resizing of the internal array data structure and with the advent of C++11, move semantics can make resizing an even cheaper operation. 它的设计使得内部阵列数据结构的调整变得容易,随着C ++ 11的出现,移动语义可以调整更便宜的操作。 Also, the notions of RAII apply here, ideas of carefully initializing data members in constructors and relieving them in destructors enable you to evade issues of dynamic memory allocation as a user and simply propagate new objects on the stack, passing references when they need to "exit" their scope. 此外,RAII的概念在这里适用,在构造函数中仔细初始化数据成员并在析构函数中释放它们的想法使您能够避免作为用户的动态内存分配问题,并简单地在堆栈上传播新对象,在需要时传递引用“退出“他们的范围。

One thing to note is that vector s create an internal block of memory, an array which might exceed at times the size of the actual array, because of popping and pushing new elements. 需要注意的一点是, vector s创建了一个内部内存块,这个数组可能会超过实际数组的大小,因为弹出和推送新元素。 Also, you're not obliged to define the size of it at first, but can easily extend it by push_back, push_front etc. This means that other things can change on the fly and extending can cost you quite a bit, even with move semantics. 此外,您最初没有义务定义它的大小,但可以通过push_back,push_front等轻松扩展它。这意味着其他东西可以随时改变并且扩展可能会花费你很多,即使使用移动语义。

The only reason to stray from vectors is when you're doing some heavy 3D rendering or simulations that are data-oriented and expect the data to be packed in some very custom, specific ways and be shuffled around manually which the tidy vector might not easily allow. 偏离矢量的唯一原因是当你正在进行一些重型3D渲染或数据导向的模拟时,期望数据以一些非常自定义的特定方式打包并且手动改组,整齐的vector可能不容易允许。 But that will push you into more low-level realms of naked arrays (and you ought to be ready for it). 但这将推动你进入更低级别的裸阵列领域(你应该为此做好准备)。 The key things that you should take from this is that you can simply treat "mental 2D array" vectors(really, data has no real geometric shape, that's just how we, puny humans, see it) as vectors and just index them differently. 你应该从中得到的关键是你可以简单地将“心理二维数组”向量(实际上,数据没有真正的几何形状,这就是我们如何,微不足道的人,看到它)作为向量处理,并且只是对它们进行不同的索引。 Make sure you input all the row data, in sequence, one by one and you'll get a very simple layout which can be simply probed/indexed with (i*n + j) where [i,j] is the classic 2D matrix subscripting/indexing. 确保按顺序逐个输入所有行数据,你将得到一个非常简单的布局,可以用(i * n + j)简单地探测/索引,其中[i,j]是经典的2D矩阵下标/索引。

Then, it could be as simple as: 然后,它可以很简单:

vector<char> world(totalRows*totalColumns, ' ');

And then you simply pass by reference where it needs to go, indexing it as (i*n + j) after you push the data on it properly. 然后你只需通过引用传递它需要去的地方,在正确推送数据之后将其索引为(i * n + j)。

Your code should work, but the unnecessary bloat might introduce unnecessary mental overhead while trying to manipulate your data, shifting it around and writing unnecessary stuff, much less than actually using the i*n+j "manual indexing" approach to keep your mental picture of a 2D array/matrix of chars. 你的代码应该可以运行,但是不必要的膨胀可能会在尝试操纵你的数据,转移它并编写不必要的东西时引入不必要的心理开销,远远低于实际使用i * n + j“手动索引”方法来保持你的心理状态一个二维阵列/字符的字符。 If you're willing, you could even override functionality in order to add syntactic sugar. 如果您愿意,您甚至可以覆盖功能以添加语法糖。

Your code works. 你的代码有效。 As noticed in the comment, vector<vector<T>> is not truly a 2D array. 正如评论中所注意到的那样, vector<vector<T>>并不是真正的2D数组。

The important thing here is that (totalRows, vector<char>(totalColumns, ' ')) and (totalColumns, vector<char>(totalRows, ' ')) are equivalent, as long as you always follow the rule used to create the vector: line x column (or column x line ) 这里重要的是(totalRows, vector<char>(totalColumns, ' '))(totalColumns, vector<char>(totalRows, ' '))是等效的,只要您始终遵循用于创建矢量: line x column (或column x line

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

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