合并数组(覆盖与偏移量)

时间:2018-09-28 18:14:18

标签: c# arrays

给出一个浮点数在-1和1之间的源数组,我想操纵该数组以给定的偏移量与其自身组合。我认为,更详细地描述这一点的最简单方法是通过示例:

sourceArray: [0.1, 0.2, 0.3, -0.5, -1.0]
offsets: [0,1,2]

这将导致3个数组组合在一起。偏移量实际上是在移动数组,并保持长度。

o0: [0.1, 0.2, 0.3, -0.5, -1.0]
o1: [-1.0, 0.1, 0.2, 0.3, -0.5]
o2: [-0.5, -1.0, 0.1, 0.2, 0.3]

合并数组(每个位置的总和)后,结果将是:

[-1.4, -0.7, 0.6, 0.0, -1,2]

我已经实现了一个生成正确结果的循环,但是它太慢了,因为我的源数组更大,并且我必须用不同的偏移量多次进行计算。

是否有使用C#实现此目的的更快方法?

2 个答案:

答案 0 :(得分:1)

在此问题的标准实现中,mod似乎是最慢的操作。幸运的是,如果对偏移量进行了排序,则可以通过将mod中的迭代分解为多个阶段来消除对arr的需求,在每个阶段中,我们可以确保偏移量数组索引保持在范围之内。

希望您不介意我用Java进行说明吗?我相信它将用C#转换几乎1-1:

static double[] sumOffsetsNoMod(double[] arr, int[] off)
{
  double[] sum = new double[arr.length];
  for(int i=0, p=off.length-1 ; i<arr.length; p--)
  {
    int top = arr.length-off[p];
    for(; i<top; i++)
      for(int j=0; j<off.length; j++)
        sum[i+off[j]] += arr[i];
    off[p] -= arr.length;
  }

  // restore off
  for(int i=0; i<off.length; i++) off[i] += arr.length;

  return sum;
}

请注意,我们必须修改偏移量的值,以在逐步移动各相时将它们从右移变为左移。为了正确起见,我们最后将偏移量恢复为其原始值。

但是,我听到您说的所有这些额外的努力值得吗?好吧,在针对使用mod的参考实现的完全非科学的定时测试中,非mod版本要快很多:

Mod   : 1485ms
NoMod : 863ms

供参考:

static double[] sumOffsetsMod(double[] arr, int[] off)
{
  double[] sum = new double[arr.length];
  for(int i=0; i<arr.length; i++)
    for(int j=0; j<off.length; j++)
      sum[(i+off[j])%arr.length] += arr[i];
  return sum;
}

public static void main(String[] args)
{
  double[] arr = {0.1, 0.2, 0.3, -0.5, -1.0};
  int[] off = {0,1,4};

  int n=10000000;
  long t = System.currentTimeMillis();
  for(int i=0; i<n; i++)
  {
    double[] sum = sumOffsetsMod(arr, off);
  }
  System.out.printf("Mod   : %dms\n", (System.currentTimeMillis()-t));
  t = System.currentTimeMillis();
  for(int i=0; i<n; i++)
  {
    double[] sum = sumOffsetsNoMod(arr, off);
  }
  System.out.printf("NoMod : %dms\n", (System.currentTimeMillis()-t));
}

答案 1 :(得分:-1)

这是伪代码:

snprintf( m_Text, sizeof(m_Text) - 1, "%s", logMessage.c_str() )

这是<activity android:name=".SingleTaskActivity" android:label="singleTask launchMode" android:launchMode="singleTask"> ,其中for i from 0 to length(sourceArray)-1 total = 0 for j from 0 to length(offsets)-1 total = total + sourceArray[(i + offsets[j]) % length(sourceArray)] result[i] = total O(n*m),而nlength(sourceArray)

如果您有足够的内存,则可以通过实现所有偏移量数组来避免执行所有模运算:

m

然后您可以遍历数组:

length(offsets)