我試圖撰寫插入排序的遞回代碼,但我遇到了分段錯誤。請幫我解決一下這個。
#include <bits/stdc .h>
using namespace std;
void insert(vector<int> &v,int temp){
if(v.size()==0||v[v.size()-1]<=temp){
v.push_back(temp);
return;
}
int val = v[v.size()-1];
v.pop_back();
insert(v, temp);
v.push_back(val);
return;
}
void sort(vector<int> &v){
if(v.size()==1) return;
int temp = v[v.size()-1];
v.pop_back();
sort(v);
insert(v,temp);
}
int main() {
int n;
vector<int> v;
cin>>n;
for(int i=0;i<n;i )
cin>>v[i];
sort(v);
for(int i=0;i<n;i )
cout<<v[i];
return 0;
}
uj5u.com熱心網友回復:
問題是向量v是空的(意味著它有 size 0)并且你試圖訪問它的元素,這會導致未定義的行為。
vector<int> v; //this creates an empty vector named v
cin>>n;
for(int i=0;i<n;i )
cin>>v[i]; //this leads to undefined behavior
在上面的代碼片段中,向量v是一個空向量,意味著它沒有元素。因此,運算式cin >> v[i], 會導致未定義的行為,因為您正在訪問向量的i第 th 索引處的元素,但向量內沒有要訪問的元素。
未定義的行為意味著任何事情1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。
所以你看到的輸出(也許看到)是未定義行為的結果。正如我所說,不要依賴具有 UB 的程式的輸出。該程式可能會崩潰(這就是您的情況)。
因此,使程式正確的第一步是洗掉 UB。只有這樣,您才能開始推理程式的輸出。
解決方案
要解決這個問題,您可以在創建矢量時指定矢量的大小,如下所示:
int n;
cin>>n;
vector<int> v(n);//create vector of size n
1有關未定義行為的更技術上準確的定義,請參見此處提到:對程式的行為沒有限制。
uj5u.com熱心網友回復:
這會創建一個空的vector<int>:
vector<int> v;
訪問其中的任何元素將使您的程式具有未定義的行為。您可以通過提供給建構式或在創建空后呼叫來創建vector<int>具有所需元素數量的。另一種選擇是將其創建為空,然后將元素添加到其中,在這種情況下它將動態增長。nresize(n)vector<int>push_back()emplace_back
使用正確數量的元素創建它的示例:
int main() {
int n;
// verify that extraction of `n` succeeded and that `n > 0`:
if(!(std::cin >> n && n > 0)) {
std::cerr << "error\n";
return 1;
}
// create the vector with the correct number of elements
std::vector<int> v(static_cast<size_t>(n));
// use a range-based for loop to get a reference to each element:
for(int& val : v)
std::cin >> val; // extract into the referenced `int`
sort(v);
// here you can use a range-based for loop to get a copy of each element
// (which is cheap in this case, since they are `int`s):
for(int val : v)
std::cout << val << ' ';
std::cout << '\n';
}
演示
筆記:
#include <bits/stdc .h>- 切勿包含此非標準標題。包括標準標題,例如iostream和vectorusing namespace std;- 不要這樣做。尤其是當你為這樣的函式提供多載時,如果你 include和 dosort將可用。bits/stdc .husing namespace std;
uj5u.com熱心網友回復:
你宣告了一個空向量
int n;
vector<int> v;
所以在這個 for 回圈中使用下標運算子
for(int i=0;i<n;i )
cin>>v[i];
呼叫未定義的行為。
相反,您可以在輸入n值之后使用元素最初宣告向量n,例如
int n;
cin>>n;
vector<int> v( n );
for(int i=0;i<n;i )
cin>>v[i];
n或者您可以在已知值之后調整向量的大小,例如
int n;
vector<int> v;
cin>>n;
v.resize( n );
for(int i=0;i<n;i )
cin>>v[i];
最好將變數 n 宣告為具有無符號整數型別,例如
size_t n;
代替 for 回圈,您可以使用基于范圍的 for 回圈
size_t n = 0;
cin>>n;
std::vector<int> v( n );
for ( auto &item : v ) std;:cin >> item;
在函式sort中,您需要至少通過以下方式更改 if 陳述句中的條件
void sort( std::vector<int> &v ){
if ( v.size() < 2 ) return;
//...
because in general the user can pass an empty vector.
Instead of using expressions like this v[v.size()-1] you could use the member function back. For example
int temp = v.back();
that makes the code more readable.
I would define the functions the following way without redundant return statements
void insert( std::vector<int> &v, int value )
{
if (v.empty() || not( value < v.back() ) )
{
v.push_back( value );
}
else
{
int tmp = v.back();
v.pop_back();
insert( v, value );
v.push_back( tmp );
}
}
void sort( std::vector<int> &v )
{
if (not ( v.size() < 2 ))
{
int last = v.back();
v.pop_back();
sort( v );
insert( v, last );
}
}
Here is a demonstration program.
#include <iostream>
#include <vector>
void insert( std::vector<int> &v, int value )
{
if (v.empty() || not( value < v.back() ) )
{
v.push_back( value );
}
else
{
int tmp = v.back();
v.pop_back();
insert( v, value );
v.push_back( tmp );
}
}
void sort( std::vector<int> &v )
{
if (not ( v.size() < 2 ))
{
int last = v.back();
v.pop_back();
sort( v );
insert( v, last );
}
}
int main()
{
std::vector<int> v = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
sort( v );
for (const auto &item : v)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
The program output is
0 1 2 3 4 5 6 7 8 9
And advice: try to avoid the using directive
using namespace std;
it can be a reason of name collisions and sometimes makes the code unclear that is whether there is used a standard C function or a user defined function.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/444266.html
下一篇:將臨時系結到r值參考會產生錯誤
