有没有办法对阵列中的一个成员进行操作?

Nei*_*yer 2 c#

我一直在解决日常编码问题并且来到了这个问题.

给定一个整数数组,返回一个新数组,使得新数组的索引i处的每个元素都是原始数组中除i处的数字之外的所有数字的乘积.

例如,如果我们的输入是[1,2,3,4,5],则预期输出将是[120,60,40,30,24].如果我们的输入为[3,2,1],则预期输出为[2,3,6].后续行动:如果你不能使用师?

因此,简单的方法是将数组中的所有元素相乘,然后除以[i],但这会产生问题,即如果I = 0要获得异常错误.

我知道对数组的所有成员执行操作的聚合函数,但是有没有办法修改聚合,以便它对所有成员进行操作,但是有一个,或者是否有其他函数/方法提供此功能?

Dmi*_*nko 5

如果source很小,你可以借助Where例如跳过索引

  int[] source = new int[] { 1, 2, 3, 4, 5 };

  int[] result = Enumerable
    .Range(0, source.Length)
    .Select(i => source
       .Where((value, index) => index != i) // all items except i-th
       .Aggregate((s, a) => s * a))         // should be multiplied 
    .ToArray();

  Console.Write(string.Join(", ", result));
Run Code Online (Sandbox Code Playgroud)

结果:

  120, 60, 40, 30, 24
Run Code Online (Sandbox Code Playgroud)

编辑:但是,解决方案有O(N**2)时间复杂性; 如果初始source数组很大,我们可以实现更高效的O(N)代码(是的,我们应该介意):

  int[] source = ...

  int[] result;

  int zeroCount = source.Count(item => item == 0);

  if (zeroCount >= 2)      // All zeroes case
    result = new int[source.Length];   
  else if (zeroCount == 1) // All zeroes save one value case
    result = source
      .Select(v => v == 0
         ? source.Where(item => item != 0).Aggregate((s, a) => s * a)
         : 0)
      .ToArray(); 
  else {                   // No zeroes case
    // long, 1L: to prevent integer overflow, e.g. for {1000000, 1000000} input
    long total = source.Aggregate(1L, (s, a) => s * a);

    result = source
      .Select(v => (int)(total / v)) // yes, it's a division...
      .ToArray(); 
  }
Run Code Online (Sandbox Code Playgroud)