浅谈多维数组行列布局之间的转换规则
2013-05-20 10:07
405 查看
最近做个项目,需要将行排列的多维数组(如lua、c/c++中)与列排列的多维数组(如matlab、R、Fortune中)进行相互转换。
其实行排列、列排列是个通俗的叫法,严格上说行排列是遍历数组元素时下标从右往左递增的排列,而列排列是下标从左往右的排列。举例:对于int Array[2][2][2],如果按行排列的情况遍历,则为Array[0][0][0],Array[0][0][1],Array[0][1][0],Array[0][1][1],Array[1][0][0],Array[1][0][1],Array[1][1][0],Array[1][1][1];如果按列排列的情况遍历,则为Array[0][0][0],Array[1][0][0],Array[0][1][0],Array[1][1][0],Array[0][0][1],Array[1][0][1],Array[0][1][1],Array[1][1][1]。
如何将lua的一个多维矩阵(行排列)赋值给matlab/R的多维矩阵(列排列)呢?
当然是通过c/c++。毕竟lua、matlab、R等脚本语言都是通过c支持的。另外,在进行矩阵中单个元素赋值的时候,只能通过线性下标的形式。下面给一个思路:
typedef vector<size_t> MATRIX_DIMENSION; // 数组的维度
typedef vector<size_t> MATRIX_INDEX; // 数组下标,遍历数组时使用
MATRIX_DIMENSION mat_dim = ...; // 从lua中读取过来
MATRIX_INDEX subscripts(matrixDim.size(), 0); // 下标从[0][0][0]...开始,线性下标为0
while (subscripts没有遍历完) { // 下标当然是以从右往左的顺序递增
size_t rLinearIndice = calcSingleSubscriptOfRMatrix(mat_dim, subscripts); // 计算subscripts对应的在以列排列的数组中的线性下标
RMatrix[rLinearIndice
] = luaElement;
iterateSubscript(mat_dim, subscripts); // 让下标增一
}
bool iterateSubscript(const MATRIX_DIMENSION &dimensions, MATRIX_INDEX &subscripts)
{
MATRIX_DIMENSION::const_reverse_iterator it1;
MATRIX_INDEX::reverse_iterator it2;
for (it1 = dimensions.rbegin(), it2 = subscripts.rbegin();
it1 != dimensions.rend() && it2 != subscripts.rend();
++it1, ++it2) {
if (*it2 >= *it1)
return false;
if (*it2 < *it1-1) {
*it2 += 1;
return true;
}
else { // *it2 == *it1 - 1
// if (it2 == subscripts.rend()-1)
// return false;
*it2 = 0;
}
}
return true;
}
// 求以列排列的矩阵中元素的线性下标
size_t calcSingleSubscriptOfRMatrix(const MATRIX_DIMENSION &dimensions, const MATRIX_INDEX &subscripts)
{
MATRIX_INDEX vecEx;
size_t temp = 1;
vecEx.push_back(temp);
MATRIX_INDEX::const_iterator it1, it2, it3;
for (it1 = dimensions.begin(); it1 != dimensions.end()-1; ++it1) {
temp *= *it1;
vecEx.push_back(temp);
}
size_t ret = 0;
for (it2 = vecEx.begin(), it3 = subscripts.begin();
it2 != vecEx.end(), it3 != subscripts.end();
++it2, ++it3) {
ret += (*it2) * (*it3);
}
return ret;
}
At last:
希望能对需要的朋友有帮助,同时也是自己对相关知识的一个总结,方便以后用到时回忆。对于这个多维数组行列的转换,小弟还有其它一些方法,要么在时间效率上逊于本方法,要么在空间效率上逊于此,也算是走过的一个弯路,就不写出来了,有兴趣的朋友邮件或qq联系84020702@qq.com。
关于lua、R与c++混合编程的一些技术,以及量化投资技巧,也欢迎与大家讨论
。第一次写博客,且小弟比较喜欢偷懒,写得比较粗略,嘿嘿
,以后会越写越好的。
其实行排列、列排列是个通俗的叫法,严格上说行排列是遍历数组元素时下标从右往左递增的排列,而列排列是下标从左往右的排列。举例:对于int Array[2][2][2],如果按行排列的情况遍历,则为Array[0][0][0],Array[0][0][1],Array[0][1][0],Array[0][1][1],Array[1][0][0],Array[1][0][1],Array[1][1][0],Array[1][1][1];如果按列排列的情况遍历,则为Array[0][0][0],Array[1][0][0],Array[0][1][0],Array[1][1][0],Array[0][0][1],Array[1][0][1],Array[0][1][1],Array[1][1][1]。
如何将lua的一个多维矩阵(行排列)赋值给matlab/R的多维矩阵(列排列)呢?
当然是通过c/c++。毕竟lua、matlab、R等脚本语言都是通过c支持的。另外,在进行矩阵中单个元素赋值的时候,只能通过线性下标的形式。下面给一个思路:
typedef vector<size_t> MATRIX_DIMENSION; // 数组的维度
typedef vector<size_t> MATRIX_INDEX; // 数组下标,遍历数组时使用
MATRIX_DIMENSION mat_dim = ...; // 从lua中读取过来
MATRIX_INDEX subscripts(matrixDim.size(), 0); // 下标从[0][0][0]...开始,线性下标为0
while (subscripts没有遍历完) { // 下标当然是以从右往左的顺序递增
size_t rLinearIndice = calcSingleSubscriptOfRMatrix(mat_dim, subscripts); // 计算subscripts对应的在以列排列的数组中的线性下标
RMatrix[rLinearIndice
] = luaElement;
iterateSubscript(mat_dim, subscripts); // 让下标增一
}
bool iterateSubscript(const MATRIX_DIMENSION &dimensions, MATRIX_INDEX &subscripts)
{
MATRIX_DIMENSION::const_reverse_iterator it1;
MATRIX_INDEX::reverse_iterator it2;
for (it1 = dimensions.rbegin(), it2 = subscripts.rbegin();
it1 != dimensions.rend() && it2 != subscripts.rend();
++it1, ++it2) {
if (*it2 >= *it1)
return false;
if (*it2 < *it1-1) {
*it2 += 1;
return true;
}
else { // *it2 == *it1 - 1
// if (it2 == subscripts.rend()-1)
// return false;
*it2 = 0;
}
}
return true;
}
// 求以列排列的矩阵中元素的线性下标
size_t calcSingleSubscriptOfRMatrix(const MATRIX_DIMENSION &dimensions, const MATRIX_INDEX &subscripts)
{
MATRIX_INDEX vecEx;
size_t temp = 1;
vecEx.push_back(temp);
MATRIX_INDEX::const_iterator it1, it2, it3;
for (it1 = dimensions.begin(); it1 != dimensions.end()-1; ++it1) {
temp *= *it1;
vecEx.push_back(temp);
}
size_t ret = 0;
for (it2 = vecEx.begin(), it3 = subscripts.begin();
it2 != vecEx.end(), it3 != subscripts.end();
++it2, ++it3) {
ret += (*it2) * (*it3);
}
return ret;
}
At last:
希望能对需要的朋友有帮助,同时也是自己对相关知识的一个总结,方便以后用到时回忆。对于这个多维数组行列的转换,小弟还有其它一些方法,要么在时间效率上逊于本方法,要么在空间效率上逊于此,也算是走过的一个弯路,就不写出来了,有兴趣的朋友邮件或qq联系84020702@qq.com。
关于lua、R与c++混合编程的一些技术,以及量化投资技巧,也欢迎与大家讨论
。第一次写博客,且小弟比较喜欢偷懒,写得比较粗略,嘿嘿
,以后会越写越好的。
相关文章推荐
- 浅谈java中字符串数组、字符串、整形之间的转换
- Java_语法基础_4字节的byte数组与int之间的转换
- 十六进制字符串和byte数组之间的各种转换关系
- js中常用数据类型之间转换--字符串转换成数字;----字符串和json;---字符串和数组
- C# 16进制与字符串、字节数组之间的转换(转)
- ArrayList和数组之间的转换和关系
- php数组和字符串之间转换
- 字符串,字节数组,流之间的转换
- C#中List〈string〉和string[]数组之间的相互转换-
- OC-042.数组与字符串之间的转换
- 字符串和字符数组之间的转换
- byte[]数组和int之间的转换
- List、Set、数组之间的转换
- C# 16进制与字符串、字节数组之间的转换
- List、Set、Map、数组之间各种转换
- C#中List〈string〉和string[]数组之间的相互转换
- JAVA中list,set,map与数组之间的转换详解
- 每日一问(常用的集合接口和类有哪些【二】)—ArrayList类和数组之间的转换
- js中数组和对象之间的转换
- 字符串与数组之间的转换