我知道如何使用 for 循环来做到这一点。是否可以使用 LINQ 或 lambdas 做这样的事情?
int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };
int[] c = a * b; //resulting array should be { 20, 80, 300 }
编辑:下面的代码可以工作,但它不像使用显式方法那样可读。LINQ 非常棒,它确实增加了可读性……但这不是其中一种情况。
这是 CMS 答案的简短版本 -let
不需要额外的内容,当您只是进行投影时,使用点表示法更简单:
int[] result = Enumerable.Range(0, a.Length)
.Select(i => a[i] * b[i])
.ToArray();
另一种方法是使用带有索引的 Select 形式:
int[] result = a.Select((value, index) => value * b[index])
.ToArray();
在此处使用 Zip 功能(.NET 4.0 的新功能)详细信息:
int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };
int[] c = a.Zip(b, (a1, b1) => a1 * b1).ToArray();
在 .NET 4 出现之前,您可以使用上面链接中的 zip 实现。
没有内置任何内容,但您始终可以编写自己的函数。下面的第一个是一个简单的扩展方法,可以做你想做的事。第二个允许您指定要应用的函数:
class Program
{
public static void Main(string[] args)
{
int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };
int[] c = a.MatrixMultiply(b);
int[] c2 = a.Zip(b, (p1, p2) => p1 * p2);
}
}
public static class Extension
{
public static int[] MatrixMultiply(this int[] a, int[] b)
{
// TODO: Add guard conditions
int[] c = new int[a.Length];
for (int x = 0; x < a.Length; x++)
{
c[x] = a[x] * b[x];
}
return c;
}
public static R[] Zip<A, B, R>(this A[] a, B[] b, Func<A, B, R> func)
{
// TODO: Add guard conditions
R[] result = new R[a.Length];
for (int x = 0; x < a.Length; x++)
{
result[x] = func(a[x], b[x]);
}
return result;
}
}
查看有关即将发布的 PLINQ(并行 LINQ)的 MSDN 文章。从文章中,这是一个使用 PLINQ 并行化矩阵乘法的示例:
void ParMatrixMult(int size, double[,] m1, double[,] m2, double[,] result)
{
Parallel.For( 0, size, delegate(int i) {
for (int j = 0; j < size; j++) {
result[i, j] = 0;
for (int k = 0; k < size; k++) {
result[i, j] += m1[i, k] * m2[k, j];
}
}
});
}
它使用 LINQ 和 Lambda!作为奖励,它分布在处理器上。
你可以编写一个简单的扩展来处理任何等级的矩阵。
public static class TwodimensionalArrayExtensions
{
public static int[][] MultiplyBy(this int[][] leftMatrix, int[][] rightMatrix)
{
if (leftMatrix[0].Length != rightMatrix.Length)
{
return null; // Matrices are of incompatible dimensions
}
return leftMatrix.Select( // goes through <leftMatrix matrix> row by row
(leftMatrixRow, leftMatrixRowIndexThatIsNotUsed) =>
rightMatrix[0].Select( // goes through first row of <rightMatrix> cell by cell
(rightFirstRow, rightMatrixColumnIndex) =>
rightMatrix
.Select(rightRow => rightRow[rightMatrixColumnIndex]) // selects column from <rightMatrix> for <rightMatrixColumnIndex>
.Zip(leftMatrixRow, (rowCell, columnCell) => rowCell * columnCell) // does scalar product
.Sum() // computes the sum of the products (rowCell * columnCell) sequence.
)
.ToArray() // the new cell within computed matrix
)
.ToArray(); // the computed matrix itself
}
}
以下是一些测试值:
// Test1
int[][] A = { new[] { 1, 2, 3 } };
int[][] B = { new[] { 1 }, new[] { 2 }, new[] { 3 } };
int[][] result = A.MultiplyBy(B);
// Test2
int[][] A = { new[] { 1 }, new[] { 2 }, new[] { 3 } };
int[][] B = { new[] { 1, 2, 3 } };
int[][] result = A.MultiplyBy(B);
// Test3
int[][] A = new int[][] { new[] { 1, 2 }, new[] { 2, 2 }, new[] { 3, 1 } };
int[][] B = new int[][] { new[] { 1, 1, 1 }, new[] { 2, 3, 2 } };
int[][] result = A.MultiplyBy(B);
如果事先将右矩阵转置,则乘法可以更优雅地表示如下。
int[][] Multiply(int[][] left, int[][] right) =>
left.Select(lr =>
right
.Select(rr =>
lr.Zipped(rr, (l, r) => l * r).Sum())
.ToArray())
.ToArray();