与数组的虚拟串联
Virtual concatenation with arrays
假设我有3个双精度数组a1[]
、a2[]
、a3[]
,每个数组的长度分别为L1、L2、L3
假设我想"虚拟地"连接这些数组,也就是说,我想创建一个阵列a_virtual[]
,使得a_virtual = {a1[L1], a2[L2], a3[L3]}
在逻辑上(尽管在物理上)这些阵列可能彼此不连续。
因此,如果我想访问a_virtual[5]
和L1=2
、L2=3
、L3=1
,则会获取a3[0]
。为了访问a_virtual[0]
,将提取a1[0]
的
我该怎么做这个
- 在C中
- 在C++中(如何用std::vectors代替数组)也很有用)
- 在CUDA
我怀疑,如果有一种方法可以做到这一点,那么这三种环境都是一样的,但根据提供的功能。
以下是C中使用链表和(尾)递归的可能解决方案:
#include <stdio.h>
struct dblarr {
double *data;
size_t len;
struct dblarr *next;
};
double *fetch(const struct dblarr *arr, size_t index) {
if (arr == NULL) return NULL;
if (index < arr->len) return arr->data + index;
return fetch(arr->next, index - arr->len);
}
int main(void) {
double a1[2] = {1, 2};
double a2[3] = {1, 2, 3};
double a3[1] = {1};
struct dblarr x1, x2, x3;
x1.data = a1; x1.len = sizeof a1 / sizeof *a1; x1.next = &x2;
x2.data = a2; x2.len = sizeof a2 / sizeof *a2; x2.next = &x3;
x3.data = a3; x3.len = sizeof a3 / sizeof *a3; x3.next = NULL;
printf("before %fn", *fetch(&x1, 5));
*fetch(&x1, 5) = 0.42;
printf(" after %fn", *fetch(&x1, 5));
return 0;
}
您可以在http://ideone.com/mY0ix.
下面的内容怎么样?它是非常硬编码的,不是最好/最干净的代码,但也许你可以概括这个逻辑?
#include <iostream>
#include <vector>
using namespace std;
void logicalConcat(vector<int>& a1, vector<int>& a2, vector<int>& a3, int k) {
if(k > a1.size() - 1)
k -= a1.size();
else {
cout << a1[k] << endl;
return;
}
if(k > a2.size() - 1)
k -= a1.size();
else {
cout << a2[k] << endl;
return;
}
cout << a3[k] << endl;
}
这里的k是您想要的虚拟串联的索引。我们没有连接任何东西,只是在向量上迭代。
如果数组不需要连续,那么一种方法是将单个索引转换为两个索引,一个用于指向实际数组的指针数组,另一个用于具有所需元素的数组。
要做到这一点,您需要创建一个指向这些数组的指针数组:
double** arrays = {a1, a2, a3};
然后是它们长度的数组:
int arraysizes = { sizeof(a1) / sizeof(*a1), sizeof(a2) / sizeof(*a2), sizeof(a3) / sizeof(*a3) };
然后,给定一个索引n
,您可以通过进行来计算arrays
的两个索引
int i1 = 0, j = 0;
while (n - arraysizes[j] >= 0)
n -= arraysizes[j++], ++i1;
然后,您可以像这样对指针数组进行索引,以获得实际元素:
arrays[n][i2]
您还可以创建一个包装器类来使用内置的operator[]
执行此运算。
其他一些为基本的C实现提供了答案。
以下是一个类的通用c++实现的一些示例代码,该类在不复制任何数组元素的情况下创建虚拟级联数组。一旦创建,虚拟数组就可以像普通向量一样进行索引(读取或写入):
#include <vector>
#include <map>
#include <iostream>;
using namespace std;
class VirtualArray {
public:
multimap<int,double*> startIndices; // reverse map of starting index to its sub array
int size;
VirtualArray() : size(0) {}
double & operator[](int i) {
// find proper subarray in log(n) time
multimap<int,double*>::iterator iter = --startIndices.upper_bound(i);
double *subarray = iter->second;
int startIndex = iter->first;
// index into subarray
return subarray[i-startIndex];
}
void addArray(double* array, int length) {
startIndices.insert(make_pair(size, array));
size += length;
}
void addVector(vector<double> & vec) {
startIndices.insert(make_pair(size, vec.data()));
size += vec.size();
}
};
int main() {
double a1[3], a2[4], a3[6] = {1, 2, 3, 4, 5, 6};
int L1 = 3, L2 = 4, L3 = 6;
vector<double> a3vec;
a3vec.assign(a3,a3+6);
VirtualArray vArray;
vArray.addArray(a1,L1);
vArray.addArray(a2,L2);
vArray.addVector(a3vec);
cout << vArray[10];
return 0;
}
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 在不使用模板的情况下将多个大小的数组传递给虚拟方法
- 为什么我不能从铸造的字节(char)数组中调用虚拟函数
- 在单个指针数组中调用不同派生类的虚拟方法
- 与数组的虚拟串联
- 使用memcpy从字节数组初始化虚拟类
- g++在虚拟析构函数中给出了删除数组的警告消息,这意味着什么
- C++在派生类指针数组上调用虚拟函数
- 给定64位虚拟地址空间,任何不在堆栈上声明32KB数组的理由