我在 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;
}
这为传递给它的数字的所有可能组合创建了一个“笛卡尔积”数组。我在这里的具体困惑是这个 block 在做什么?
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 数组存储为指向更多数组的指针数组;我的第一个想法是“讨厌”,但这里有一些优雅之处在于所有内容都作为一个内存块返回,之后可以一次性释放()。
这段代码
- 为 (sizeA * sizeB) 个 int 指针分配空间,然后是 2 * sizeA * sizeB;将它存储为一个 int** 指针,即我们将使用它的第一个 block 作为我们二维数组的顶层
- (您引用的代码)为顶级数组设置指针以指向剩余内存的两个整数 block
- 使用二维数组存储 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 }
。
关于c# - "Cartiesian Product"C++ 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61484388/