C++中的不规则二维数组
技术背景
最近刚学习C++的一些编程技巧,对于一些相对比较陌生的问题,只能采取一些简单粗暴的方案来实现。就比如说,我们可以在Python中定义一个[[0,0,0],[1,2],[1,1,1],[3]]这样的不规则的二维数组(list)。那么如果我们想在C++中实现一个类似的数据结构,应该怎么去设计呢?更具体一点的问题,当我们给C++输入一个固定长度的数组,比如Shape为(4,3),然后再给出一个Shape为(4,)的有效索引数组,保存的是第二个维度中数据的有效长度(这里有个要求是输入的有效位数处于固定长度数组的末尾,因为我们一般去更新数组时也是从末尾处push_back进去)。最后用一个数据结构保存这个不规则的二维数组,并且可以正常索引和打印。
数据结构设计
首先我们能够想到的是,用双重指针来对这样的一个不规则数组进行索引,第一个指针指向第一个维度,第二个指针指向第二个维度,就类似于张量中的两条边。由于第二个维度是不定长度的,因此我们需要使用一个结构体来包含一个不定长数组的指针,和具体的长度信息。
struct bucket{
int num;
int *ptr;
};
就比如这个bucket实现,对于单个bucket来说,可以用其中的*ptr指针来索引一个不定长度的数组,然后在外层定义一个*bucket指针,这样可以索引到对应的结构体中,形成一个二维的不定长度的数据结构。
代码实现
这里我们使用的案例是这样的,首先要构造一个定长的数组,然后对这个定长的数组的第二个维度进行分别的截断,再赋值给我们定义好的数据结构。这样做的好处是,在Python跟C++的接口中也能够使用这种方法来实现,我们只需要传给C++一个定长的数组,以及第二个维度的有效长度,就能在C++中使用这样一个不定长的数组进行高效的计算。详细代码如下所示:
// g++ main.cpp -o main && ./main
#include <iostream>
struct bucket{
int num;
int *ptr;
};
void print_bucket(bucket *bc, int shape[]){
for (int i=0; i<4; i++){
bucket bc_i = bc[i];
printf("%d: ", bc_i.num);
for (int j=0; j<shape[i]; j++){
printf("%d,", bc_i.ptr[j]);
}
printf("\n");
}
}
int main(){
// 定长数组
int arr[4][3] = {{0,1,2},{1,2,3},{2,3,4},{3,4,5}};
// 有效长度
int shape[4] = {2,3,2,1};
// 先构建结构体数组
bucket _bc[4];
for (int i=0; i<4; i++){
_bc[i].num = shape[i];
_bc[i].ptr = arr[i];
_bc[i].ptr += 3-shape[i];
}
// 再把结构体数组赋值给结构体指针
bucket *bc = _bc;
// 打印结构体的所有内容
print_bucket(bc, shape);
return 0;
}
输出结果为:
$ g++ main.cpp -o main && ./main
2: 1,2,
3: 1,2,3,
2: 3,4,
1: 5,
这里第一列输出的是每一个不定长数组的长度,后面的是不定长数组的具体内容。
总结概要
本文介绍了一个在C++中保存不定长二维数组的数据结构。在这个结构中,我们使用了一个含有指针和数组长度的结构体,用这样的一个结构体构造一个结构体数组,用于存储每一个不定长的数组。最后可以将这个不定长数组的内存地址赋值给一个结构体指针,那么这个结构体指针中就包含了所有不定长数组所需的内容。类似的使用场景,更多的出现在Python和C++两个不同的语言进行交互的时候,这样操作可以兼具Python的易开发特性和C++的高性能特性。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/struct.html
作者ID:DechinPhy
更多原著文章:https://www.cnblogs.com/dechinphy/
请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
C++中的不规则二维数组的更多相关文章
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- php中向前台js中传送一个二维数组
在php中向前台js中传送一个二维数组,并在前台js接收获取其中值的全过程方法: (1),方法说明:现在后台将数组发送到前台 echo json_encode($result); 然后再在js页面中的 ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- <转载>c++中new一个二维数组
原文连接 在c++中定义一个二维数组时有多种方式,下面是几种定义方式的说明:其中dataType 表示数据类型,如int byte long... 1.dataType (*num)[n] = n ...
- C++中动态申请二维数组并释放方法
C/C++中动态开辟一维.二维数组是非常常用的,以前没记住,做题时怎么也想不起来,现在好好整理一下. C++中有三种方法来动态申请多维数组 (1)C中的malloc/free (2)C++中的new/ ...
- 如何在C++中动态建立二维数组(转)
http://blog.sina.com.cn/s/blog_7c073a8d0100qp1w.html http://blog.163.com/wujiaxing009@126/blog/stati ...
- 消除VS中动态申请二维数组C6011,C6385,C6386的警告
动态申请二维数组,无非就是通过指针来实现.@wowpH 过程分三步:1.申请内存,2.使用数组,3.释放内存. 代码如下: /************************************* ...
- C++中vecotr表示二维数组并自己实现一个Grid类
1 C++中使用vector来表示二维数组 声明一个二维数组: vector<vector<int>> dp(row, vector<int>(col)); 将变量 ...
- OpenCV中Mat与二维数组之间的转换
---恢复内容开始--- 在OpenCV中将Mat(二维)与二维数组相对应,即将Mat中的每个像素值赋给一个二维数组. 全部代码如下: #include <iostream> #inclu ...
- PHP中如何对二维数组按某个键值进行排序
$arr=[ array( 'name'=>'张三', 'age'=>28 ), array( 'name'=> ...
随机推荐
- 2020美亚个人赛wp
案例背景 2020年9月,数名信用卡持有人向警方报案,指他们的信用卡被不知名人士在一家本地网上商店购买手机.订单大部分来自海外的网络地址,但有一宗订单来自本地.警方经调查后发现该本地网络地址的注册地址 ...
- 推荐系统[四]:精排-详解排序算法LTR (Learning to Rank)_ poitwise, pairwise, listwise相关评价指标,超详细知识指南。
0.前言召回排序流程策略算法简介 推荐可分为以下四个流程,分别是召回.粗排.精排以及重排: 召回是源头,在某种意义上决定着整个推荐的天花板: 粗排是初筛,一般不会上复杂模型: 精排是整个推荐环节的重中 ...
- npm旧淘宝镜像过期,更换新淘宝镜像
1. 清空缓存 npm cache clean --force 2.设置新淘宝镜像 npm config set registry https://registry.npmmirror.com/ 3. ...
- React Hooks 使用指南
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...
- 在K8s中,提供的DNS组件是什么?有什么特性?
在Kubernetes (K8s)集群中,用于内部DNS服务的组件已经从早期的kube-dns过渡到了coredns. kube-dns(已弃用): 在Kubernetes 1.10版本之前,kube ...
- Java并发(五)----线程常见方法总结
常见方法 方法名 static 功能说明 注意 start() 启动一个新线程,在新的线程运行 run 方法中的代码 start 方法只是让线程进入就绪,里面代码不一定立刻运行(CPU 的时间片还 ...
- DBSAT脚本快速收集方法
DBSAT是Oracle官方提供的脚本,用于数据库的安全评估检查,用户可以放心下载使用. 下载链接具体参见MOS: Oracle Database Security Assessment Tool ( ...
- Oracle预防alert日志过大的脚本:del_alertlog.sh
Oracle预防alert日志过大的脚本 参考:https://blog.csdn.net/jc_benben/article/details/88798523 在原文思路的基础上,做了一些修正,实测 ...
- go中的 位预算,反码、补码、原码
https://baike.baidu.com/item/%E4%BD%8D%E8%BF%90%E7%AE%97/6888804 首先关于"位运算",看下百度百科就行了. 总结:在 ...
- [JVM]GC日志解读解析
GC日志解读解析 示例代码 package jvm.test1; import java.util.Random; import java.util.concurrent.TimeUnit; impo ...