C++ 与数组的虚拟连接

C++ 与数组的虚拟连接,c++,c,cuda,C++,C,Cuda,假设我有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_虚拟[0],将获取a1[0] 我该怎么做 在C中 在C++中(如何用STD::向量代替数组) (也可

假设我有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_虚拟[0]
,将获取
a1[0]

我该怎么做

  • 在C中
  • 在C++中(如何用STD::向量代替数组) (也可能有用)
  • 在库达
我怀疑,如果有一种方法可以做到这一点,那么这三种环境都是一样的,但在每种环境中可能有更有效的方法来做到这一点,具体取决于环境
提供的能力

如果数组不需要连续,那么一种方法是将单个索引转换为两个索引,一个用于指向实际数组的指针数组,另一个用于具有所需元素的数组

为此,您需要创建指向这些数组的指针数组:

double** arrays = {a1, a2, a3};
然后是其长度的数组:

int arraysizes = { sizeof(a1) / sizeof(*a1), sizeof(a2) / sizeof(*a2), sizeof(a3) / sizeof(*a3) };
然后,给定一个索引
n
,您可以通过执行以下操作来计算
数组的两个索引

int i1 = 0, j = 0;

while (n - arraysizes[j] >= 0)
    n -= arraysizes[j++], ++i1;
然后您可以像这样索引指针数组以获得实际元素:

arrays[n][i2]

您还可以创建一个包装类,使用内置的
操作符[]

执行此算法。如果数组不需要连续,那么一种方法是将单个索引转换为两个索引,一个用于指向实际数组的指针数组,另一个用于具有所需元素的数组

为此,您需要创建指向这些数组的指针数组:

double** arrays = {a1, a2, a3};
然后是其长度的数组:

int arraysizes = { sizeof(a1) / sizeof(*a1), sizeof(a2) / sizeof(*a2), sizeof(a3) / sizeof(*a3) };
然后,给定一个索引
n
,您可以通过执行以下操作来计算
数组的两个索引

int i1 = 0, j = 0;

while (n - arraysizes[j] >= 0)
    n -= arraysizes[j++], ++i1;
然后您可以像这样索引指针数组以获得实际元素:

arrays[n][i2]

您还可以创建一个包装器类,用一个内置的
操作符[]

来完成这个算法,下面的例子怎么样?这是相当硬的编码,不是最好/最干净的代码,但也许你可以推广这种逻辑

#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;
}
#包括
#包括
使用名称空间std;
void logicalConcat(向量和a1、向量和a2、向量和a3、整数k){
如果(k>a1.size()-1)
k-=a1.尺寸();
否则{

cout像下面这样的东西怎么样?它是相当硬的编码,不是最好的/最干净的代码,但也许你可以推广这种逻辑

#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;
}
#包括
#包括
使用名称空间std;
void logicalConcat(向量和a1、向量和a2、向量和a3、整数k){
如果(k>a1.size()-1)
k-=a1.尺寸();
否则{

cout在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;
}
#包括
结构dblarr{
双*数据;
尺寸透镜;
结构dblarr*next;
};
double*fetch(常量结构dblarr*arr,大小索引){
if(arr==NULL)返回NULL;
if(indexlen)返回arr->data+index;
返回获取(arr->next,index-arr->len);
}
内部主(空){
双a1[2]={1,2};
双a2[3]={1,2,3};
双a3[1]={1};
结构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(“在%f\n之前,*fetch(&x1,5));
*取数(&x1,5)=0.42;
printf(“在%f\n之后,*fetch(&x1,5));
返回0;
}

您可以在上“查看代码运行情况”。

这里有一个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;
}
#包括
结构dblarr{
双*数据;
尺寸透镜;
结构dblarr*next;
};
double*fetch(常量结构dblarr*arr,大小索引){
if(arr==NULL)返回NULL;
if(indexlen)返回arr->data+index;
返回获取(arr->next,index-arr->len);
}
内部主(空){
双a1[2]={1,2};
双a2[3]={1,2,3};
双a3[1]={1};
结构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(“在%f\n之前,*fetch(&x1,5));
*取数(&x1,5)=0.42;
printf(“在%f\n之后,*fetch(&x1,5));
返回0;
}

您可以在上“查看代码运行情况”。

其他一些提供了基本C实现的答案

这里是一些通用C++实现的示例代码,它创建了一个不复制任何数组元素的虚拟级联数组。一旦创建,虚拟数组可以像普通向量(被读取或写入)那样索引:

#包括
#包括
#包括,;
使用名称空间std;
类虚拟射线{
公众:
multimap startIndices;//将起始索引反向映射到其子数组
整数大小;
VirtualArray():大小(0){}
双重运算符(&O)[](int i){
//在对数(n)时间内找到合适的子阵列
迭代器iter=--startIndices.上界(i);
双*子阵列=国际热核实验堆->秒;
int startIndex=iter->first;
//索引到子数组
返回子阵[i-startIndex];
}
void addArray(双*数组,整数长度){
开始。插入(组成配对(大小、数组));
尺寸+=长度;
}
void addVector(vector和vec){
startIndices.insert(make_pair(size,vec.data());
大小+=向量大小();
}
};
int main(){
双a1[3],a2[4],a3[6]={1,2,3,4,5,6};
int L1=3,L2=4,L3=6;
载体a3vec;
a3向量赋值(a3,a3+6);
虚拟射线