【问题标题】:How to subtract every element from one array to another?如何将一个数组中的每个元素减去另一个数组?
【发布时间】:2021-08-04 14:36:17
【问题描述】:

我有两个大小相等的数组。

double[] array1;
double[] array2; //array1 size == array2 size

我还有一个常数double constant = 5。比如说5 我想创建一个新数组double[] array3;,我们在其中获取array1 中的每个元素,并从array1 中减去array2 中相同索引处的元素。 所以:

array3[i] = array1[i] - array2[i]

然后我想在 array3 中的所有元素中减去常数。

我可以使用 for 循环来完成这一切,但是我的数组非常庞大,因此需要很长时间来计算。有没有办法在不使用 for 循环的情况下专门做减法?

示例数据:

如果:

array1 = {1, 2, 3, 4, 5, 6};
array2 = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6};

然后

array3 = {0.9, 1.8, 2.7, 3.6, 4.5, 5.4}

现在减去constant

array3 = {-4.1, -3.2, -2.3, - 1.4, -0.5, 0.4}

【问题讨论】:

  • 您可以使用array1.Zip(array2, (x, y) => x - y),但这不一定比for 循环更快...
  • " 有没有办法在不使用 for 循环的情况下专门进行减法运算?" - 您需要在数组上循环的地方 - 至少一次。
  • 如上所述,即使你没有明确使用for循环,你最终也会循环遍历你的数组(可能在内部 i> 但仍然)
  • 如果 array1array2 的大小相同,则只能使用 1 个 for 循环。 for(int i = 0; i < array1.Length; i++) { array3[i] = (array1[i] - array2[i]) - const); },我看不出有什么理由你不能在一次迭代中完成所有操作,减去数组值和每次迭代中的 const。
  • 有一个Parallel.For Method;但是,只有当要执行的工作量很大时,它才会加快速度。还有SIMD-accelerated types in .NET

标签: c# arrays linq math


【解决方案1】:

确实不可避免地必须至少循环一次数组,但是有内置的 LINQ Zip 方法可以为您完成大部分繁重的工作。

要做的事情是循环超过必要的,所以不要在做初始减法后减去常数值 - 同时做

var array1 = new[]{1, 2, 3, 4, 5, 6};
var array2 = new[]{0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
var constant = 5;
var array3 = array1.Zip(array2, (x,y) => x-y-constant).ToArray();

现场示例:https://dotnetfiddle.net/An8IuE

这最终会比简单的 for 循环慢一点

var array1 = new[]{1, 2, 3, 4, 5, 6};
var array2 = new[]{0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
var constant = 5;
var array3 = new double[array1.Length];
for(int i=0,j=array1.Length; i<j;i++)
    array3[i] = array1[i] - array2[i] - constant;

现场示例:https://dotnetfiddle.net/r5JQKN

【讨论】:

    【解决方案2】:

    如果顺序实际上并不重要,那么您可以使用 AsParallel 通过 PLINQ 并行化您的 Zip

    var array1 = new[]{1, 2, 3, 4, 5, 6};
    var array2 = new[]{0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
    var constant = 5;
    var array3 = array1.AsParallel().Zip(array2.AsParallel(), (x,y) => x-y-constant);
    

    因为它是并行发生的,所以结果会乱序(但仍然是正确的)。

    Demo

    编辑:

    并行是否比顺序更快取决于您的硬件和输入大小。对我来说,许多在线编译器(rextester、C# fiddle)显示顺序执行更快(很可能是因为它们的资源有限且输入大小不能太大),在我的本地机器上,我能够随着输入大小接近每个数组约 1000 万个元素,并行执行变得更快。给你的收获是“基准,基准,基准”

    【讨论】:

      【解决方案3】:
      Enumerable.Range(0, array1.Length).Select(x => array1[x] - array2[x] + constant);
      

      【讨论】:

        【解决方案4】:

        使用overload of Enumerable.Zip that has a parameter resultSelector

        double[] array1 = ...;
        double[] array2 = ...;
        const double value = 5.0;
        
        var result = array1.Zip(array2, (x, y) => x - y - value);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 2015-08-15
          • 2013-02-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多