Kyle
Kyle

Reputation: 21

Removing duplicates from a vector, recursion c++

I'm working on a program that is supposed to sort a vector of ints and then get passed to a recursive function to remove any duplicates by having an element check it's neighbor, and remove it if they're the same. Here is my code:

#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;
}

My issue here is that when it runs, I get the following error after entering values:

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

It also prints multiple times when it works but I'm not terribly concerned about that. Where's the bug? Can anybody help me out?

UPDATE:

Here is the code that I am CURRENTLY running with:

#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;
}

I ran with a debugger, everything was fine, was removing duplicates like it was no big deal, until the size of n/i reached the size of the list. Then I get that error message listed above. How do I fix that?

Upvotes: 0

Views: 1867

Answers (2)

Etherealone
Etherealone

Reputation: 3558

You have commented out returns completely except the recursive call. The functions go on although it should not.

You should use return checkNum(v, n); on those lines.

Edit:

Your code is completely flawed and won't do what you want. Here is a quick ugly code of how you should be doing it while you stick to limitation of probably homework:

#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;
}

Upvotes: 2

Bruce Dean
Bruce Dean

Reputation: 2828

Ok got it to work. You need to add a return after the line, cout << "No duplicates found" like:

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

The reason is that by the time the recursive call reaches this point in the program, you are done checking for duplicates. Your recursive function should wrap things up at this point.

Without the return you keep increasing n (below at the line with n++):

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

but then n is larger than the size of your vector v, causing the error.

Upvotes: 1

Related Questions