简体   繁体   English

如何将 3d 维度不是固定大小的 3D 数组展平为一维数组?

[英]How to flatten a 3D array where the 3d dimension is not fixed size into 1D array?

Given a 2D array where each (x,y) cell contains a vector of strings (for simplicity) of different size.给定一个二维数组,其中每个 (x,y) 单元包含一个不同大小的字符串向量(为简单起见)。

What's the most efficient way to flatten this data structure into 1D array, ie creating a function mapping injectively each string to {1,...,n} where n is the total number of strings in the data structure.将此数据结构展平为一维数组的最有效方法是什么,即创建一个 function 将每个字符串单射映射到 {1,...,n},其中 n 是数据结构中的字符串总数。

You can map an index i, j, k to linear position p in O(1) and back in O(log N), where N is the size of the 2D array, not the total number of strings.您可以在 O(1) 中将 map 索引i, j, k转换为线性 position p并返回 O(log N),其中N是二维数组的大小,而不是字符串的总数。

First, let's treat your 2D array as a 1D, since that just makes things much easier.首先,让我们将您的 2D 数组视为 1D,因为这会使事情变得更容易。 Index i is the index of a vector in the array.索引i是数组中向量的索引。 Index k is the position of a string in the vector.索引k是向量中字符串的 position。 N is the size of the array. N是数组的大小。

You can create an array of integers (eg size_t ) that holds the zero-based cumulative sum of all the vector lengths:您可以创建一个整数数组(例如size_t ),其中包含所有向量长度的从零开始的累积和:

lengths = array[N]
lengths[0] = 0
for(i = 1 to N)
    lengths[i] = lengths[i - 1] + size(array[i - 1])

If you want, you can compute the total number of strings as total = lengths[N - 1] + size(array[N - 1]) .如果需要,可以将字符串总数计算为total = lengths[N - 1] + size(array[N - 1])

Now, for a given string at index i, k , the position in the expanded array is just现在,对于索引i, k处的给定字符串,扩展数组中的 position 只是

p = lengths[i] + k

Given a position p , you map it to i, k using a bisection algorithm (binary search that returns the index of the left bound when an exact match isn't found):给定一个 position p ,你 map 它到i, k使用二分算法(二进制搜索,当找不到完全匹配时返回左边界的索引):

i = bisect(lengths, p)
k = p - lengths[i]

Bisection is a simplified binary search, so O(log N).二分法是一种简化的二分搜索,所以 O(log N)。

All this works very nicely until you start expanding your vectors.在您开始扩展向量之前,所有这些都非常有效。 At that point, insertion and deletion become O(N) operations, since you need to increment or decrement all the cumulative sums past the insertion point.此时,插入和删除操作变成 O(N) 操作,因为您需要增加或减少插入点之后的所有累积和。 To insert:插入:

array[i][k].push(a_string)
for(z = i + 1 to N)
    lengths[z]++

And to delete:并删除:

array[i][k].pop()
for(z = i + 1 to N)
    lengths[z]--

By the way, if you still want to use indices x, y for the array, you can convert between the linear index i of lengths and back using顺便说一句,如果您仍想对数组使用索引x, y ,您可以在lengths的线性索引i之间转换并使用

i = x + C * y
x = i % C
y = i / C

Here, C is the number of columns in your array.在这里, C是数组中的列数。 You can easily generalize this to any number of dimensions.您可以轻松地将其推广到任意数量的维度。

Doesn't simple direct way work for you?简单直接的方式不适合你吗?

#include <vector>
#include <string>

int main() {
        std::vector<std::string> omg[3][4];
        std::vector<std::string> rv;
        for(auto const &row: omg) {
                for(auto const &cell: row) {
                        for(auto const &str: cell) {
                                rv.push_back(str);
                        }
                }
        }
}

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

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