繁体   English   中英

为什么 push_back 不继续循环工作?

[英]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的值为12 ,并且不依赖于存储在向量中的元素数量。

相反,您应该使用例如

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM