簡體   English   中英

運行時錯誤:在 C++ 中合並兩個排序的 arrays

[英]Runtime Error: merge two sorted arrays in C++

我編寫了這段代碼用於合並兩個排序的 arrays:-

   class Solution {
   public:
     void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
         int p1=m-1, p2=n-1, i=m+n-1;      
         while(p2>=0){
     
        if(p1>=0 && nums1[p1]<nums2[p2]){
            
            nums1[i]=nums2[p2];
            p2--;
            
        }//if
        else{
             nums1[i]=nums1[p1];
            p1--;
        }
        i--;
    }
    
}//fn
};

這引發了運行時錯誤。 有人可以幫我解決這個問題嗎?

我將 OP 樣本放入coliru上的MCVE中,並能夠重現 OP 的問題。 就我而言,執行只是由於越界訪問而中止。

我高度懷疑 OP 將nums1, nums1.size(), nums2, nums2.size()到了Solution::merge()中。 由於合並是破壞性的(將結果寫入輸入容器之一),因此必須考慮這一點。

恕我直言,OP似乎基本上意識到了這一點,因為合並是從后到前完成的。

但是,由於nums1用於 output,因此必須在合並之前為其提供足夠的大小。

例如nums1.resize(m + n); 在合並開始時將完成這項工作。

我的 MCVE 修復:

#include <iostream>
#include <vector>

class Solution {
    
  public:
  
    void merge(std::vector<int>& nums1, int m, std::vector<int>& nums2, int n)
    {
      nums1.resize(m + n); // <= ENSURE SUFFICIENT STORAGE IN nums1
      int p1 = m - 1, p2 = n - 1, i = m + n - 1;      
      while (p2 >= 0) {
        if (p1 >= 0 && nums1[p1] < nums2[p2]) {
          nums1[i] = nums2[p2];
          p2--;
        } else {
          nums1[i] = nums1[p1];
          p1--;
        }
        i--;
      }
    }
};

int main()
{
  // sample data
  std::vector<int> nums1{ 1, 3, 5, 7, 9 };
  std::vector<int> nums2{ 2, 4, 6, 8 };
  // run merge
  Solution().merge(nums1, (int)nums1.size(), nums2, (int)nums2.size());
  // output result
  std::cout << "nums1: {";
  const char* sep = " ";
  for (const int num : nums1) {
    std::cout << sep << num;
    sep = ", ";
  }
  std::cout << " }" << std::endl;
}

Output:

nums1: { 1, 2, 3, 4, 5, 6, 7, 8, 9 }

coliru 現場演示


@Armin Montigny建議使用std::merge()而不是手工編織的實現。

首先,我懷疑它是否也能夠管理破壞性合並,但經過深思熟慮后,我意識到如果使用得當,它會完美地做到這一點。 我修改了我的 MCVE 以查看它的外觀。

我使用std::merge()的替代 MCVE :

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

class Solution {
    
  public:
  
    void merge(std::vector<int>& nums1, int m, std::vector<int>& nums2, int n)
    {
      nums1.resize(m + n); // <= ENSURE SUFFICIENT STORAGE IN nums1
      std::merge(
        nums1.rbegin() + n, nums1.rend(), // consider that nums1 is already resized
        nums2.rbegin(), nums2.rend(),
        nums1.rbegin(),
        std::greater<int>());
    }
};

int main()
{
  // sample data
  std::vector<int> nums1{ 1, 3, 5, 7, 9 };
  std::vector<int> nums2{ 2, 4, 6, 8 };
  // run merge
  Solution().merge(nums1, (int)nums1.size(), nums2, (int)nums2.size());
  // output result
  std::cout << "nums1: {";
  const char* sep = " ";
  for (const int num : nums1) {
    std::cout << sep << num;
    sep = ", ";
  }
  std::cout << " }" << std::endl;
}

Output:

nums1: { 1, 2, 3, 4, 5, 6, 7, 8, 9 }

coliru 現場演示

筆記:

  1. 我使用rbegin()rend()來從頭到尾合並向量,就像 OP 那樣。 這對於始終在必須讀取仍未處理的元素之后寫入合並元素是必要的。
  2. nums1的輸入迭代器乍一看可能有點令人驚訝。 必須使用nums1.rbegin() + n來跳過已分配用於存儲nums2附加元素的空間。 (那正是n 。)
  3. std::merge()必須與自定義謂詞(例如std::greater )一起使用,因為我使用升序排序的樣本數據,但從后到前合並,將其反轉為降序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM