Удаление дубликатов из вектора, рекурсия с ++

0

Я работаю над программой, которая должна сортировать вектор ints, а затем передавать в рекурсивную функцию для удаления любых дубликатов, если элемент проверяет ее соседом и удаляет ее, если они одинаковы. Вот мой код:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void checkNum(vector<int> &v, int n)
{
    int i = n;
    if (v[i] == '\0')
    {
        cout << "No duplicates found." << endl;
    }
    if (v[i]==v[i+1])
    {
        v.erase(v.begin()+i);
        /*return 1 + */checkNum(v, n);
    }
    else
    {
        n++;
        /*return 0 + */checkNum(v, n);
    }
    int k;
    cout << "Sorted values, no duplicates: " << endl;
    for (k=0; k< v.size(); k++)
        cout << v[k] << " ";
    //return 0;
}

int main()
{
    vector<int> numbers;
    cout << "Please enter numbers, 0 to quit: " << endl;
    bool more = true;
    while (more)
    {
        int num;
        cin >> num;
        if (num == 0)
            more = false;
        else
            numbers.push_back(num);
    }
    sort(numbers.begin(),numbers.end());
    cout << "The sorted values are: " << endl;
    int i;
    for (i = 0; i < numbers.size(); i++)
        cout << numbers[i] << " ";
    checkNum(numbers, 0);
    system("pause");
    return 0;
}

Моя проблема здесь в том, что когда она запускается, я получаю следующую ошибку после ввода значений:

Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll File: d:\program files (x86)\microsoft visual studio 11.0\vc\include\vector Line: 1140
Expression: vector subscript out of range

Он также печатает несколько раз, когда он работает, но я не очень обеспокоен этим. Где ошибка? Кто-нибудь может мне помочь?

ОБНОВИТЬ:

Вот код, с которым я ТЕПЕРЬ работает:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int checkNum(vector<int> &v, int n)
{
int i = n;
if (i == v.size())
{
    cout << "No duplicates found." << endl;
    return 0;
}
if (v[i]==v[i+1])
{
    v.erase(v.begin()+i);
    return checkNum(v, n);
}
else
{
    n++;
    return checkNum(v, n);
}

int k;
cout << "Sorted values, no duplicates: " << endl;
for (k=0; k< v.size(); k++)
    cout << v[k] << " " << endl;
return 0;
}

int main()
{
vector<int> numbers;
cout << "Please enter numbers, 0 to quit: " << endl;
bool more = true;
while (more)
{
    int num;
    cin >> num;
    if (num == 0)
        more = false;
    else
        numbers.push_back(num);
}
sort(numbers.begin(),numbers.end());
cout << "The sorted values are: " << endl;
int i;
for (i = 0; i < numbers.size(); i++)
    cout << numbers[i] << " ";
checkNum(numbers, 0);
system("pause");
return 0;
}

Я работал с отладчиком, все было в порядке, удаляли дубликаты, как будто это было неважно, до тех пор, пока размер n/i не достиг размера списка. Затем я получаю это сообщение об ошибке, указанное выше. Как это исправить?

  • 0
    Что случилось, когда вы встретили точку останова в строке 1140? Каково было значение индекса, когда он не прошел? Я предполагаю, что вы используете отладчик.
  • 0
    Вы не обеспокоены индексированием после конца вашего массива?
Показать ещё 3 комментария
Теги:
recursion
vector

2 ответа

2

Вы прокомментировали return полностью, за исключением рекурсивного вызова. Функции продолжаются, хотя это не должно.

Вы должны использовать return checkNum(v, n); на этих линиях.

Редактировать:

Ваш код полностью испорчен и не будет делать то, что вы хотите. Вот быстрый уродливый код того, как вы должны это делать, в то время как вы придерживаетесь ограничения, вероятно, домашней работы:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void checkNum(vector<int> &v, vector<int>::iterator& it)
{
    if (it == v.end() - 1) //last element
    {
        cout << "After duplicate removal pass:" << endl;
        for (int k=0; k< v.size(); k++)
             cout << v[k] << " ";
    }
    else if (*it == *(it + 1)) //next element is equal to current one, erase current one
    {
        v.erase(it); //using 'it' after this line is normally not a good practice,
        // but we know the vector is stored sequentially and 'it' will point to another element because above we checked if this is the last element or not.
        return checkNum(v, it);
    }
    else //next element is not the same as this one
    {
        ++it;
        return checkNum(v, it);
    }
}

int main()
{
    vector<int> numbers;
    cout << "Please enter numbers, 0 to quit: " << endl;
    bool more = true;
    while (more)
    {
        int num;
        cin >> num;
        if (num == 0)
            more = false;
        else
            numbers.push_back(num);
    }
    sort(numbers.begin(),numbers.end());
    cout << "The sorted values are: " << endl;
    int i;
    for (i = 0; i < numbers.size(); i++)
        cout << numbers[i] << " ";
    vector<int>::iterator elementToStart = numbers.begin();
    checkNum(numbers, elementToStart);
    system("pause");
    return 0;
}
  • 0
    Сделано это изменение, та же проблема.
  • 0
    @ Кайл Код полностью ошибочен. Теперь, когда я прочитал его полностью, он скажет: «Дубликаты не найдены». он уже нашел дубликаты и удалил их, потому что n в конечном итоге будет равно размеру вектора.
Показать ещё 4 комментария
1

Хорошо, это сработало. Вам нужно добавить возврат после строки, cout << "Не найдено дубликатов":

if (i == v.size())
{
   cout << "No duplicates found." << endl;
   return; // add this return
}

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

Без возврата вы продолжаете увеличивать n (ниже на линии с n++):

else
{
    n++;
    /*return 0 + */checkNum(v, n);
}

но затем n больше размера вашего вектора v, вызывая ошибку.

  • 0
    У него уже есть возврат 0.
  • 0
    @ Кайл, не уверен, о чем ты говоришь; посмотрите на ту часть кода, на которую я ссылался выше, я что-то упустил? Я добавил ответ выше, чтобы проиллюстрировать, что нужно изменить. После этого изменения ваш код заработал идеально для меня.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню