Найти n-е наибольшее число бесконечного цикла Переполнение стека

У меня есть вектор из N чисел, и я хочу найти n-е число в массиве. Я использую вариант быстрой сортировки, но время от времени у меня возникает проблема с бесконечными циклами, и я думаю, что, если наибольшее число является единственным вариантом в двух массивах. Число может появляться в массиве много раз, так что, если, например, я выберу 10 для N и я хочу найти 1-е наибольшее число, я могу получить {9,9} в левом массиве, что приведет к бесконечному циклу. Что я могу сделать, чтобы исправить это? Вот мой код

#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <vector>

using namespace std;
int partition(int n, int arrsize, vector<int> intarr); //pass vector by val

int main() {

int n, N;

cout << "Please enter n: " << endl;
cin >> n;
cout << "Please enter N: " << endl;
cin >> N;

vector<int> array;
srand(time(NULL));

for(i=0; i < N; i++) {
array.push_back(1 + rand() % N);
cout << array.at(i) << ", ";
}

//Get the nth largest value of array[N]
int arraylen = array.size();
cout << "\nArraylen is " <<  arraylen << endl;
int result = partition(n, arraylen, array);

cout << "The " << n << "th largest number is: " << result <<endl;

return 0;
}

int partition(int n, int arrsize, vector<int> intarr) {
//1. Get a random value from the array:
int random = rand() % arrsize;
int pivot = intarr.at(random);

//2. Partition the array into 2 halves left < pivot > right
vector<int> left;
vector<int> right;

for(int j=0; j < arrsize; j++) {
if (intarr[j] >= pivot)
left.push_back(intarr[j]);
else if (intarr.at(j) < pivot)
right.push_back(intarr[j]);
else continue;
}

cout << "\n \n" << "Left = ";

for(int k = 0; k < left.size(); k++) {
cout << left.at(k) << ", ";
}

cout << endl << "Right = ";

for(int k = 0; k < right.size(); k++) {
cout << right.at(k) << ", ";
}

int leftlen = left.size();
int rightlen = right.size();

if (n < leftlen)
return partition(n, leftlen, left);

else if (n > (arrsize - rightlen)) {
n = n - (leftlen);
return partition(n, rightlen, right);
}

else return pivot;

}

2

Решение

Так как вы все равно создаете новые векторы (я полагаю, потому что вы не хотите изменять входной вектор), вы также можете просто избегать помещения элемента pivot влево или вправо. В этом случае, если стержень окажется элементом, который вы ищете, он будет пойман else return pivotи если вы столкнетесь с вырожденным случаем, когда раздел — это все равные элементы, то ничто не будет помещено ни в левую, ни в правую часть, и единственное значение раздела будет возвращено правильно.

Способ быстрой сортировки позволяет избежать этой проблемы — никогда не помещать элемент pivot в сортируемые субвекторы; следовательно, даже если один из векторов окажется одним и тем же элементом, он все равно окажется короче, чем был. Это тонкость с быстрой сортировкой, которая редко объясняется хорошо, хотя Седжвик обсуждает способы улучшения производительности быстрой сортировки на векторах со многими повторяющимися элементами.

2

Другие решения

Проверка того, что любой из подмассивов пуст, поможет обнаружить бесконечный цикл, а также сбой в некоторых других случаях.

int leftlen = left.size();
int rightlen = right.size();
if (leftlen == 0 || rightlen == 0) /* break processing */

редактировать Бесконечный цикл возможен, только если один из массивов равен 0, а другой заполнен тем же значением.

1

По вопросам рекламы [email protected]