代码之家  ›  专栏  ›  技术社区  ›  0xDEAD BEEF

C数组问题(拆分)

  •  2
  • 0xDEAD BEEF  · 技术社区  · 15 年前

    问题很简单——比如,我得到了函数,它接收数组作为参数。

    void calc(double[] data)
    

    如何将此数据“拆分”为两个子数组并传递给类似这样的子函数

    calc_sub(data(0, length/2));
    cals_sub(data(length /2, length /2));
    

    我希望,你有这个想法——在C++中我会写这个

    void calc(double * data, int len)
    {
       calc_sub(data, len / 2); //this one modifies data!!
       calc_sub(data + len / 2, len / 2); //this one modifies data too!!
    }
    

    在没有不必要的记忆复制的情况下,如何在C中做同样的事情? 我需要两份记忆副本。 1)从数据到分割数据 2)钙亚 3)从分割的数据返回到数据!这是对时间和记忆的巨大浪费!

    5 回复  |  直到 15 年前
        1
  •  2
  •   Sjoerd    15 年前

    根据Calc_Sub所做的操作,可以创建一个IEnumerable类,该类接受数组并在数组的某些部分上迭代。类似的东西 ArraySegment 但是 better .

        2
  •  8
  •   Darin Dimitrov    15 年前

    最简单的可能是使用LINQ Take Skip 扩展方法:

    int half = data.Length / 2;
    double[] sub1 = data.Take(half).ToArray();
    double[] sub2 = data.Skip(half).ToArray();
    
        3
  •  5
  •   Warty    15 年前

    简单的答案是,要获得子数组,必须创建一个新的数组并复制元素…或者,如果你使用C++,你将会是MCPCP。

    现在,为什么不采用偏移/计数方法呢? 打电话时 calc_sub(blargh[] array) 取而代之的是使用 calc_sub(blargh[] array, int offset, int count) ?

    这基本上是将指针传递到start/half pos元素并告诉函数只处理数组元素的一半的方法。


    我要注意的是,除非您使用大型双数组,否则您真的不应该担心这个问题。64位=8字节。即使你有一个1000个元素的数组,也就是8000字节,大约8kb的内存,在不到一秒钟的时间内,你会有很大的空闲空间…

    现在,在可能的情况下保存内存总是一个好主意,但我认为这是过早的优化。

    我还应该注意数组是通过引用传递的,因为它们实际上是对象,而不是整数或字符串,所以这个方法是最好的内存方面的方法[它不复制数组;它提供类似于指向数组对象的指针],但它的局限性在于,在函数中修改数组会修改传递到函数外部的数组呼叫。

        4
  •  1
  •   Rune FS    15 年前

    继续这样写你自己的子阵函数:

    public static class ArrayExtensions
    {
      T[] SubArray<T>(this T[] arr, int startIndex,int count)
      {
        var sub = new T[count];
        Array.Copy(arr,startIndex,sub,o,count);
        return sub;
      }
    }
    

    然后你可以像这样使用它:

    void calc(double[] data)
    {
      var half = data.Length /2;
      data.SubArray(0, half ));
      data.SubArray(half , half ));
    }
    
        5
  •  1
  •   Guffa    15 年前

    如果你能 calc_sub 方法采取 IEnumerable<double> 而不是 double[] ,可以使用扩展方法创建返回部分数组的表达式:

    void calc(double[] data) {
      int half = data.Length / 2;
      calc_sub(data.Take((half));
      calc_sub(data.Skip(half));
    }
    

    这样就不必将数据复制到新数组中,表达式将从原始数组返回项。