【问题标题】:Selective shallow copy from one array to another从一个数组到另一个数组的选择性浅拷贝
【发布时间】:2014-07-31 04:29:41
【问题描述】:

假设我有 2 个不同大小的数组,即

int arr[] = {0,1,2,3,4,5,6,7,8,9};
int *arr2 = new int[5];

我想浅拷贝其中一些, 深拷贝等价物是

int j =0;    
if(!(i%2))
    {
        arr2[j]=arr[i];
        j++;
    }

现在打印 arr2 将输出:0, 2, 4, 6 ,8

我想要浅拷贝的原因是因为我希望 arr2 随着对 arr 的任何更改而更新。

如果我循环并平方 arr 中的所有元素

我希望 arr2 输出:0, 4, 16, 36 ,64

这2个数组属于同一个类,一个是我的多边形信息,另一个是数据驱动的。 arr 实际上是 4000+ 个元素的大小,而 arr2 接近 3000。目前我的算法适用于深拷贝。但是因为我需要在每个更新帧中深度复制 3000 个元素,所以我在浪费资源,并且想知道我是否可以通过浅拷贝以某种方式做到这一点,所以我不必每帧都更新 arr2。我的代码需要它工作的方式,arr 实际上有 arr2 的重复值。 arr2 是动画的点列表。然后将数据复制到保存顶点位置数据的 arr。这是因为 arr 包含多个贝塞尔补丁,其中一些与另一个补丁共享一个或多个边缘。但我希望在制作动画时忽略它,否则表面会出现中断。

重要的是副本涉及索引,如

arr2[j]=arr[i];

因为我的代码就是这样设置的。 并且操作是低负载的。

【问题讨论】:

  • 对于 C++ 解决方案,您应该编写一个类似std::array 的类,其中有operator[],它可以正确地引用原始文件。有点像模型视图的东西。
  • 你刚才说arr2[j] = arr[i];是深拷贝,然后你说浅拷贝很重要arr2[j]=arr[i];。那没有意义。做int *arr2 = arr;有问题吗?
  • @hyde 一个类只会在内部进行深层复制仍然会导致性能问题。
  • @MattMcNabb 是的。 arr 是一个比 arr2 更大的数组。所以如果我这样做 *arr2 = arr;我丢失数据。棘手的部分是 arr 按特定顺序包含来自 arr2 的重复数据。
  • @new2code 嗯,我的意思是一个不做任何复制的类,无论是深复制还是浅复制,而只是访问实际的数组。单向(只读)或双向,取决于要求。

标签: c++ arrays shallow-copy


【解决方案1】:

你需要一个整数指针数组。

int *arr2[5];

for (int i = 0, j = 0; i < 10; i++) {
    if (!(i%2)) {
        arr2[j]= &arr[i];
        j++;
    }
}

所以你需要设置arr2的每个元素通过arr2[j]= &amp;arr[i];指向arr中对应的元素

当您需要访问 arr2 中的元素时,您可以调用类似:int a = *arr2[j];

稍后假设您将 arr[0] 更改为 10 arr[0] = 10; 然后 int a = *arr2[0]; 会给您 10。

【讨论】:

  • 应该是sizeof(arr) / sizeof(*arr)...(或者更直观的arr.size(),如果arrstd::array
  • 我明白了,所以我保留了一个指针数组,而不是一个数组。所以我只是在需要值时取消引用它们。这很有意义。然而,只有一个问题,是否有新的 int 指针数组。我不确定语法。
  • 我需要动态分配 arr2。我尝试了 new *int[5] 和 new int*[5],但似乎不对。最坏的情况是我只会让 arr2 比它需要的大得多,并使用另一个变量来跟踪它的可用大小。但我宁愿不要。顺便说一句,谢谢你的回答,你大大提高了我的帧率。
  • 没关系,我想通了,我需要 int **arr2 = new int*[5] 谢谢大家的帮助
  • 很高兴听到您想通了。 C/C++ 学起来很有趣,你会在学习的过程中上瘾。
【解决方案2】:

作为指针数组方法的替代方法,这里有一个粗略的 C++03 示例,说明如何以编程方式实现这一点。哪个更好取决于operator[] 在实际用例中需要有多复杂,以及第二个数组要小多少(即它需要多少额外内存,导致缓存未命中等)。

#include <iostream>

class c_array_view  {
public:
    c_array_view(int *array) : array_(array) {}
    int& operator[](size_t index) { return array_[index*2]; }

    static size_t convert_length(size_t original) { return original / 2; }

private:
    int *array_;
};

int main()
{
    int arr[] = {0,1,2,3,4,5,6,7,8,9};
    size_t arr_len = sizeof arr / sizeof arr[0];

    c_array_view arr2(arr);
    size_t arr2_len = arr2.convert_length(arr_len);

    for(unsigned i = 0; i < arr_len; ++i) {
        std::cout << "arr: " << i << " = " << arr[i] << std::endl;
    }
    std::cout << std::endl;

    for(unsigned j = 0; j < arr2_len; ++j) {
        std::cout << "arr2: " << j << " = " << arr2[j] << std::endl;
    }
    std::cout << std::endl;

    arr2[2] = 42;
    std::cout << "modifeid arr2[2] to 42, now arr[4] = " << arr[4] << std::endl;

    return 0;
}

c_array_view 可以变成一个模板,一个很好的通用类,它将映射函数作为 C++11 的 lambda 等等,这只是说明了原理。

【讨论】:

    【解决方案3】:

    如果你想要正方形,那么你不应该使用arr2[j]=arr[i]。正确答案是

    arr2[j]=arr[i]*arr[i];
    

    【讨论】:

    • OP 希望 arr2 引用 arr。平方只是一个例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多