getting rid of repeated numbers

Hello. I have some numbers given and i need to get rid of them if they repeat in an array. I am given an amount of numbers 'n' and the actual numbers that I am saving into M[100]. I should use only one array and get rid of those numbers by using nested loops. If the input is : 3, 5, 5,4 , the output should be: 5, 4;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  #include <fstream>

using namespace std;

void clear(int M[], int & n, int k); // the function that gets rid of the number
void reading(int M[], int & n); //input
void output(int M[], int n);   // output

int main()
{   ofstream fr("results.txt");
    int n, k;
    int M[100];
    reading(M, n);
    for(int i = 0; i < n; i++){             // checking if the numbr repeats
        for (int j = 0; j < n; j++){
            if(M[j] == M[i]){
            clear(M, n, i);  // if yes, cleaning it
            i--;
            }
        }
    }


    output(M, n);
	return 0;
}

void reading(int M[], int & n)
{
    ifstream fd("given.txt");
    fd >> n;
    for (int i = 0; i < n; i++)
        fd >> M[i];
    fd.close();
}

void output(int M[], int n)
{
    ofstream fr("results.txt");
    for (int i = 0; i < n; i++)
        fr << M[i] << endl;
    fr.close();
}

void clear(int M[], int & n, int k)
{
   for (int i = k; i < n-1; i++)
       M[i] = M[i+1];
   n--;
}
Last edited on
Do you have a question?


1. After line 31 you should do a sanity check. I could type -7 or 999. Neither is good for your array.

2. Lines 14--21. Which element do you keep, which remove, logically?

3. Why the example claims that the unique 3 must be removed?
3. Because its not the number that we are checking, it's the amout of numbers given, so 3 = 'n'.
2. I want to remove M[i] but I get no results, that is my main question
Last edited on
Just the part to get the unique (non-repeating) elements in an array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>

// return true if value is present in any of the positions [0 ... n-1]
bool is_present( const int array[], std::size_t n, int value  )
{
    for( std::size_t i = 0 ; i < n ; ++i ) if( array[i] == value ) return true ;
    return false ;
}

// return true if the value of array[pos] is present in any of the positions [0 ... pos-1]
bool seen_earlier( const int array[], std::size_t pos )
{
    if( pos == 0 ) return false ; // there is nothing before the first element
    else return is_present( array, pos, array[pos] ) ;
}

// bring unique elements to the front of the array; return number of unique elements
std::size_t unique( int array[], std::size_t sz )
{
    if( sz == 0 ) return 0 ; // sanity check

    std::size_t next_pos = 1 ; // position to place the next unique element
                               // (array[0] is always unique)

    // note that logically, there is a nested loop here:
    // seen_earlier() calls is_present() which implements a loop
    // however, the code is easier to read and reason about when
    // we do not have directly nested control structures within the same function
    // (caveat: a "career teacher" may see red because he/she/it can't
    // immediately see any directly nested loops in the program)
    for( std::size_t i = 1 ; i < sz ; ++i )
        if( !seen_earlier( array, i ) ) array[ next_pos++ ] = array[i] ;

    return next_pos ; // number of unique elements
}

// print the first n elements of the array
void print( const int array[], std::size_t n, std::ostream& stm = std::cout )
{
    for( std::size_t i = 0 ; i < n ; ++i ) stm << array[i] << ' ' ;
    stm << '\n' ;
}

int main()
{
    int test[] { 2, 2, 1, 1, 2, 5, 4, 4, 3, 4, 3, 3, 5, 5, 4, 4, 1, 6, 3, 2, 1, 1 } ;
    const std::size_t n = sizeof(test) / sizeof(*test) ;
    print( test, n ) ;

    const std::size_t n_unique = unique( test, n ) ;
    print( test, n_unique ) ;
}

http://coliru.stacked-crooked.com/a/ec5955ee71d1fe02
2. I want to remove M[i] but I get no results, that is my main question
1
2
3
4
5
6
7
8
    for(int i = 0; i < n; i++){             // checking if the numbr repeats
        for (int j = 0; j < n; j++){
            if(M[j] == M[i]){
            clear(M, n, i);  // if yes, cleaning it
            i--;
            }
        }
    }

Who is M[i], logically? Is it the first of repeating values, the last, or what?

Lets look at your nested loop. The outer loop is clear; it looks at each element in turn. That is actually one too many. JLBorges does point out (implicitly) that there is nothing before the first nor after the last and thus one of them is unique by design.

The inner loop looks at the whole array. Why?
* For one, you have already processed the beginning of the array, so elements up to M[i] must be unique. Why should we care about them any more?
* More serious is the fact that you inner loop will consider case i==j. Element is always equal to itself and would thus be removed, whether it is a repeating value or not.


If you want to keep the first occurence of each value, then you only look at the part of the array that is after the M[i] and remove repeats from that part of the array. That leaves M[i] intact.

If you want to keep the last occurrence of each value, then you again look at the part of the array that is after M[i]. If any copy is found, then you remove the M[i], and nothing else.

The JLBorges solution keeps the first occurence of each value, but it uses a different logic than what I described. I leave it to you as an exercise to figure out.
Topic archived. No new replies allowed.