[英]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 }
@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 }
筆記:
rbegin()
和rend()
來從頭到尾合並向量,就像 OP 那樣。 這對於始終在必須讀取仍未處理的元素之后寫入合並元素是必要的。nums1
的輸入迭代器乍一看可能有點令人驚訝。 必須使用nums1.rbegin() + n
來跳過已分配用於存儲nums2
附加元素的空間。 (那正是n
。)std::merge()
必須與自定義謂詞(例如std::greater )一起使用,因為我使用升序排序的樣本數據,但從后到前合並,將其反轉為降序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.