"Cartiesian Product" C++ 中的方法
"Cartiesian Product" Method in C++
我在 C++ 中有以下代码,我需要将其转换为 C#
int** _cartesianProduct(int sizeA, int sizeB) {
int** array = (int**)malloc(sizeof(int*) * sizeA * sizeB + sizeof(int) * 2 * sizeA * sizeB);
int* ptr = (int*)(array + sizeA * sizeB);
for (int i = 0; i < sizeA * sizeB; ++i)
array[i] = (ptr + 2 * i);
for (int i = 0; i < sizeA; ++i)
for (int k = 0; k < sizeB; ++k) {
array[i * sizeB + k][0] = i;
array[i * sizeB + k][1] = k;
}
return array;
}
这会为传递给它的数字的所有可能组合创建一个 "Cartesian products" 数组。我在这里的具体困惑是这个块在做什么?
int* ptr = (int*)(array + sizeA * sizeB);
for (int i = 0; i < sizeA * sizeB; ++i)
array[i] = (ptr + 2 * i);
或者更具体地说,这一行 int* ptr = (int*)(array + sizeA * sizeB);
?
这将分配单个内存块来存储二维数组,作为数组的数组。数组的 C 数组存储为指向更多数组的指针数组;我的第一个想法是 'yuck',但这里有一些优雅之处在于所有内容都作为单个内存块返回,之后可以一次性释放。
这段代码
- 为 (sizeA * sizeB) 个 int 指针分配 space,然后是 2 * sizeA * sizeB;将它存储为一个 int** 指针,即我们将使用它的第一个块作为我们二维数组的顶层
- (您引用的代码)设置顶级数组的指针指向剩余内存的两个整数块
- 使用二维数组存储 0-sizeA, 0-sizeB 范围内的值对
如何将其移植到 C#?这取决于您希望如何使用生成的值。我可能会将其设为一个值元组数组,
var array = Enumerable.Range(0, sizeA).SelectMany(a =>
Enumerable.Range(0, sizeB).Select(b => (a,b))).ToList();
或.ToArray()
。如果你确实想要锯齿状数组版本,你可以 new[] { a, b }
而不是内部 select.
有点话题。
此代码可能看起来像 C++
代码,但我会这样称呼它。它更像是伪装成 C++
的 C
代码,因为 malloc
的结果被显式转换为 int**
(在 C++
和 [=12= 中需要) ] 已过时)。
它的 C++ 版本可能如下所示:
std::vector<std::array<int, 2>> cartesianProduct(int sizeA, int sizeB) {
std::vector<std::array<int, 2>> result(sizeA * sizeB);
for (int i = 0; i < sizeA; ++i) {
for (int k = 0; k < sizeB; ++k) {
result[i * sizeB + k] = { i, k };
}
}
return result;
}
我在 C++ 中有以下代码,我需要将其转换为 C#
int** _cartesianProduct(int sizeA, int sizeB) {
int** array = (int**)malloc(sizeof(int*) * sizeA * sizeB + sizeof(int) * 2 * sizeA * sizeB);
int* ptr = (int*)(array + sizeA * sizeB);
for (int i = 0; i < sizeA * sizeB; ++i)
array[i] = (ptr + 2 * i);
for (int i = 0; i < sizeA; ++i)
for (int k = 0; k < sizeB; ++k) {
array[i * sizeB + k][0] = i;
array[i * sizeB + k][1] = k;
}
return array;
}
这会为传递给它的数字的所有可能组合创建一个 "Cartesian products" 数组。我在这里的具体困惑是这个块在做什么?
int* ptr = (int*)(array + sizeA * sizeB);
for (int i = 0; i < sizeA * sizeB; ++i)
array[i] = (ptr + 2 * i);
或者更具体地说,这一行 int* ptr = (int*)(array + sizeA * sizeB);
?
这将分配单个内存块来存储二维数组,作为数组的数组。数组的 C 数组存储为指向更多数组的指针数组;我的第一个想法是 'yuck',但这里有一些优雅之处在于所有内容都作为单个内存块返回,之后可以一次性释放。
这段代码
- 为 (sizeA * sizeB) 个 int 指针分配 space,然后是 2 * sizeA * sizeB;将它存储为一个 int** 指针,即我们将使用它的第一个块作为我们二维数组的顶层
- (您引用的代码)设置顶级数组的指针指向剩余内存的两个整数块
- 使用二维数组存储 0-sizeA, 0-sizeB 范围内的值对
如何将其移植到 C#?这取决于您希望如何使用生成的值。我可能会将其设为一个值元组数组,
var array = Enumerable.Range(0, sizeA).SelectMany(a =>
Enumerable.Range(0, sizeB).Select(b => (a,b))).ToList();
或.ToArray()
。如果你确实想要锯齿状数组版本,你可以 new[] { a, b }
而不是内部 select.
有点话题。
此代码可能看起来像 C++
代码,但我会这样称呼它。它更像是伪装成 C++
的 C
代码,因为 malloc
的结果被显式转换为 int**
(在 C++
和 [=12= 中需要) ] 已过时)。
它的 C++ 版本可能如下所示:
std::vector<std::array<int, 2>> cartesianProduct(int sizeA, int sizeB) {
std::vector<std::array<int, 2>> result(sizeA * sizeB);
for (int i = 0; i < sizeA; ++i) {
for (int k = 0; k < sizeB; ++k) {
result[i * sizeB + k] = { i, k };
}
}
return result;
}