[英]How to flatten a 3D array where the 3d dimension is not fixed size into 1D array?
给定一个二维数组,其中每个 (x,y) 单元包含一个不同大小的字符串向量(为简单起见)。
将此数据结构展平为一维数组的最有效方法是什么,即创建一个 function 将每个字符串单射映射到 {1,...,n},其中 n 是数据结构中的字符串总数。
您可以在 O(1) 中将 map 索引i, j, k
转换为线性 position p
并返回 O(log N),其中N
是二维数组的大小,而不是字符串的总数。
首先,让我们将您的 2D 数组视为 1D,因为这会使事情变得更容易。 索引i
是数组中向量的索引。 索引k
是向量中字符串的 position。 N
是数组的大小。
您可以创建一个整数数组(例如size_t
),其中包含所有向量长度的从零开始的累积和:
lengths = array[N]
lengths[0] = 0
for(i = 1 to N)
lengths[i] = lengths[i - 1] + size(array[i - 1])
如果需要,可以将字符串总数计算为total = lengths[N - 1] + size(array[N - 1])
。
现在,对于索引i, k
处的给定字符串,扩展数组中的 position 只是
p = lengths[i] + k
给定一个 position p
,你 map 它到i, k
使用二分算法(二进制搜索,当找不到完全匹配时返回左边界的索引):
i = bisect(lengths, p)
k = p - lengths[i]
二分法是一种简化的二分搜索,所以 O(log N)。
在您开始扩展向量之前,所有这些都非常有效。 此时,插入和删除操作变成 O(N) 操作,因为您需要增加或减少插入点之后的所有累积和。 插入:
array[i][k].push(a_string)
for(z = i + 1 to N)
lengths[z]++
并删除:
array[i][k].pop()
for(z = i + 1 to N)
lengths[z]--
顺便说一句,如果您仍想对数组使用索引x, y
,您可以在lengths
的线性索引i
之间转换并使用
i = x + C * y
x = i % C
y = i / C
在这里, C
是数组中的列数。 您可以轻松地将其推广到任意数量的维度。
简单直接的方式不适合你吗?
#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.