[英]Why doesn't push_back keep working in a loop?
对 C++ 完全陌生。 对任意长度的一维数组进行编程选择排序。 希望允许用户继续向控制台输入整数以制作所需长度的数组,以便随后进行排序。
似乎只能使用用于添加元素的 while 循环来制作长度为 2 的数组。 输入 6、2、3 和 9 时的错误结果代码和示例如下所示。
脚本:
// Preprocessor directives and namespace declaration
#include <iostream>
#include <vector>
using namespace std;
// Function
void SelectionSort(int *arr, int len)
{
// Loop through index j in arr
for (int j = 0; j < len; j++) {
// Assume element j is minimum, and initialise minIndex
int min = arr[j];
int minIndex = j;
// Loop through comparisons to determine actual minimum
// (of elements after and including j)
for (int i = j; i < len; i++)
{
if (min > arr[i])
{
min = arr[i];
minIndex = i;
}
}
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
}
// Display resulting array
for (int i = 0; i + 1 < len; i++)
{
cout << arr[i] << ", ";
}
cout << arr[len - 1] << endl;
}
// Main
int main()
{
// Explain program to user
cout << "Sort 1D array of user-inputted length/contents" << endl;
cout << "To finish array, enter -999" << endl;
// Initialise dynamic array
vector<int> vDyn (1);
vDyn[0] = 0;
cout << "Enter first element of array: ";
int firstElement = 0;
cin >> firstElement;
vDyn[0] = firstElement;
// Loop to define elements until desired length reached
bool keepGoing = true;
while (keepGoing == true)
{
cout << "Enter another element: ";
int newElement = 0;
cin >> newElement;
if (newElement != -999)
{
vDyn.push_back(newElement);
} else
{
keepGoing = false;
}
}
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
// Get array length
int len = sizeof(v) / sizeof(v[0]);
// Run SelectionSort function
SelectionSort(v, len);
return 0;
}
终端:
Sort 1D array of user-inputted length/contents
To finish array, enter -999
Enter first element of array: 6
Enter another element: 2
Enter another element: 3
Enter another element: 9
Enter another element: -999
2, 6
本声明
int len = sizeof(v) / sizeof(v[0]);
相当于声明
int len = sizeof( int * ) / sizeof( int );
因为变量v
被声明为
int* v = &vDyn[0];
指针的大小通常等于 4 或 8 个字节。 因此,可变length
的值为1
或2
,并且不依赖于存储在向量中的元素数量。
相反,您应该使用例如
size_t len = vDyn.size();
你可以像这样声明函数
void SelectionSort(int *arr, size_t len);
并称它为
SelectionSort( vDyn.data(), vDyn.size() );
此外,在 C++ 中,在标头<utility>
中声明了标准函数std::swap
而不是这个代码片段
// Swap minimum with element j
int temp = arr[j];
arr[j] = min;
arr[minIndex] = temp;
你可以写
if ( j != minIndex ) std::swap( arr[j], arr[minIndex] );
内部 for 循环可能看起来像
for ( size_t i = j + 1; i < len; i++)
^^^^^
事实上,您的函数SelectionSort
是一个 C 函数。 C++ 函数应该更通用并使用迭代器。 在这种情况下,它可以将数组与其他容器一起排序。
这是一个演示程序,它显示了一个更通用的函数,该函数调用基于向量的数组。
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename ForwardIterator>
void SelectionSort( ForwardIterator first, ForwardIterator last )
{
for ( ; first != last; ++first )
{
auto current_min = first;
for ( auto next = std::next( first ); next != last; ++next )
{
if ( *next < *current_min ) current_min = next;
}
if ( current_min != first )
{
std::iter_swap( current_min, first );
}
}
}
int main()
{
std::vector<int> v = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
SelectionSort( v.data(), v.data() + v.size() );
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
程序输出为
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
通常,您还需要编写一个也接受比较函数的重载函数。
// Convert vector to array (dynamic to static)
int* v = &vDyn[0];
此行不会将数组转换为任何内容。 您只需获取向量中第一个元素的地址。
如果你想从std::vector
获取一个底层的 c 数组,你应该使用它的data
属性。
此外,由于数组衰减为指针,它不再包含其大小的数据。 您应该依靠std::vector
属性(即std::vector::size
)向前传递此信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.