假设我有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]
我该怎么做
我怀疑是否有办法做到这一点,对于所有这三种环境都是一样的,但是在每个环境中可能有更有效的方法来实现这一点,具体取决于 提供的功能。
答案 0 :(得分:1)
这是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 %f\n", *fetch(&x1, 5));
*fetch(&x1, 5) = 0.42;
printf(" after %f\n", *fetch(&x1, 5));
return 0;
}
您可以在http://ideone.com/mY0ix处“查看正在运行的代码”。
答案 1 :(得分:0)
如果数组不需要连续,那么一种方法是将单个索引转换为两个索引,一个用于指向实数组的指针数组,另一个用于具有所需元素的数组。< / p>
为此,您将创建一个指向这些数组的指针数组:
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[]
创建一个包装类来执行此算术。
答案 2 :(得分:0)
如下所示?它是非常硬编码的,而不是最好/最干净的代码,但也许你可以推广这个逻辑?
#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将是您想要的虚级联的索引。我们不会连接任何东西,只是迭代向量。
答案 3 :(得分:0)
其他一些提供了基本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;
}