【问题标题】:How to split array into n chunks given their sizes in C++?给定 C++ 中的大小,如何将数组拆分为 n 个块?
【发布时间】:2020-11-26 11:24:17
【问题描述】:

假设我有一个包含 10000 个整数的数组,它将被拆分为 3 个子数组(在本例中为“num_jobs”)。在我的代码中,我找到了每个子数组的长度,长度存储在函数“split()”中的数组“parts”中。

我的代码:

// Function that prints  
// the required sequence 
int * split(int x, int n) //x=10000,n=3
{ 
  
    // If we cannot split the  
    // number into exactly 'N' parts 
    int *parts;
    parts = new int[n];
    if(x < n) 
    {
        return parts; 
    }
          
  
    // If x % n == 0 then the minimum  
    // difference is 0 and all  
    // numbers are x / n 
    else if (x % n == 0) 
    { 
        for(int i=0;i<n;i++)
        { 
        parts[i] = (x/n); 
        }
    } 
    else
    { 
  
        // upto n-(x % n) the values  
        // will be x / n  
        // after that the values  
        // will be x / n + 1 
        int zp = n - (x % n); 
        int pp = x/n; 
        for(int i=0;i<n;i++)  
        { 
  
            if(i>= zp) 
            parts[i] = (pp + 1); 
            else
            parts[i] = pp; 
        } 
    }
    // cout<<parts[0]<<parts[1]<<parts[2];
    return parts;
} 
      

main()
{
    int num_jobs;
    cout << "Enter Number of Jobs: "; // Type a number and press enter
    cin >> num_jobs; // Get user input from the keyboard  
    int sizeOfInputArray = 10000;
    int* partsArray = split(sizeOfInputArray, num_jobs);
    
    for(int index=0;index<num_jobs;index++)
    {
        cout<<partsArray[index];
        }
}

我要做的是创建 num_jobs 个数组,每个长度都存在于“partsArray”中。对于 10000 长度,给定 3 个 num_jobs,它返回一个包含 3333、3333、3334 的数组,它表示每个子数组的大小。如何处理 10000 长度的大数组的拆分?

【问题讨论】:

  • (1) 你需要使用c-arrays吗?在 C++ 中,您应该使用 std::vector。 (2)如果n没有精确划分初始大小,你想如何分配“剩余”元素?
  • 1.创建n 容器。 2. 遍历您的数组并将元素i 放入容器i*n/10000

标签: c++ arrays split dynamic-arrays


【解决方案1】:

正如在 cmets 中所说,使用 std::vector 会更简单,但我还是给你一个 C 数组的例子:

int ** splitArray(int *inputArray, int *parts, int num_jobs) {
    int ** subarrays = new int*[3];
    int * ptr = inputArray;
    for (int i=0; i< num_jobs; i++) {
        subarrays[i] = new int[parts[i]];
        memcpy(subarrays[i], ptr, parts[i]);
        ptr += parts[i];
    }
    return subarrays;
}

int main()
{
    int sizeOfInputArray = 10000;
    int * inputArray = new int[sizeOfInputArray];
    memset(inputArray, 0xff, sizeOfInputArray * sizeof(int)); //This sets all index to -1
    int num_jobs = 3;
    int* partsArray = split(sizeOfInputArray, num_jobs);
    
    int ** subarrays = splitArray(inputArray, partsArray, num_jobs);
    std::cout << "\n" << subarrays[0][0] << " "; //==> -1
    std::cout << "\n" << subarrays[1][0] << " "; //==> -1
    std::cout << "\n" << subarrays[2][0] << " "; //==> -1
    
    //Releases allocated memory
    for(int i=0;i<num_jobs;i++) delete subarrays[i];
    delete subarrays;
    delete inputArray;
    delete partsArray;
    return 0;
}

【讨论】:

    【解决方案2】:

    首先,尽量避免使用原始数组。 std::vector 在性能和内部实现方面几乎相同,但同时提供了强大的接口并为您处理内存。

    对于 C 样式的数组,您不能将单个数组拆分为多个部分。假设你有

    int* arr = new int[n];
    

    你不能重新解释那个数组并开始把它当作 2 个单独的数组来对待,因为一旦你决定释放它的内存,你将释放整个 arr,你不能改变这种行为。但是,您可以只使用阵列的一部分。假设调用一个函数,它将一个数组作为参数以及起始和结束索引,类似于

    void doMagic(int* arr, int begin, int end) {
        for (int i = begin; i < end; ++i) {
            //do something with arr[i]
        }
    }
    

    请注意,您可以对 std::vector 执行相同的操作。如果要从数组中提取数据并准备包含原始数组部分的单个较小数组,则必须手动完成。再次使用 beginend 索引的技巧,并将循环中的值从原始数组复制到新数组。您可以使用std::vector 实现相同的目的,因为它的一个构造函数可以采用两个iterators 并复制一系列元素。

    最后,为避免计算子数组大小时出现问题,当总大小不容易被块数整除时(​​例如 10,000 除以 3),您可以改为计算让我们称它们为分割点或范围。如果您的数组有 n 个元素并且您想将其拆分为 x 部分,您可以计算 currentbeginend 索引块如下。

    int begin = (n * current) / x;
    int end = ((n * (current + 1)) / x) - 1;
    

    【讨论】:

      猜你喜欢
      • 2020-09-16
      • 2020-01-14
      • 2017-04-02
      • 1970-01-01
      • 2012-06-27
      • 2018-06-13
      • 1970-01-01
      • 2020-10-28
      • 2021-09-19
      相关资源
      最近更新 更多