Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C++ (http://www.programmingforums.org/forum15.html)
-   -   duplicate numbers in arrays (http://www.programmingforums.org/showthread.php?t=15484)

mychorhizzae Mar 26th, 2008 12:27 AM

duplicate numbers in arrays
 
Hi, I've been lurking here for a while now and decided to make an account to get help. The program I'm trying to write is supposed to:
Read in 20 numbers,
each of which is between 10 and 100, inclusive. As each number is read in, validate
it and store it in the array only if it is not a duplicate of a number already read.
After reading all the values, display only the unique values that the user has
entered.

I have the program functionally working except I don't know what to do for the duplicate cases. Is there an easy way to skip the value entered if duplicate?

:

#include <iostream>
using namespace std;
#include <iomanip>




int main() {
    int idx = 0;
    int list[20];
    int n;
    int i;
   
    cout << "Enter 20 integers between 10 and 100: " << endl;
   
    for (i=0; i<20; i++){ // user inputs 20 numbers
     
    cin >> n;
   
    if (n < 10 || n > 100){  // input must be between 10 and 100
    cout << "invalid entry" << endl;
}
            list[idx] = n;  //sets each number to the next element in array
              ++idx;

}
    for ( int j = 0; j < 10; j++ )
      cout << list[ j ] << " ";  // print numbers in array
       
    system("pause");
    return 0;
}


lectricpharaoh Mar 26th, 2008 1:14 AM

Re: duplicate numbers in arrays
 
The easiest (but not the most efficient) method is to iterate through the array, checking to see if the number is present. If so, don't add it. You can write a function for this:
:

  1. bool isValueInArray(int value, int *array, int numValues)
  2. {
  3.   for(int x=0; x<numValues; ++x)
  4.     if(array[x] == value)
  5.       return true;
  6.   return false;
  7. }

Now, when you get the number from the user, just call this function first in the body of your 'get input from user' loop, and only add it if it returns false:
:

  1. if(isValueInArray(n, list, idx)
  2. {
  3.   list[idx] = n;
  4.   ++idx;
  5. }

Semantically identical to the above, by using postfix increment:
:

  1. if(isValueInArray(n, list, idx)
  2.   list[idx++] = n;

Of course, you don't need to write a separate function for this; I did it only for clarity. You can merge it into the loop with a flag variable and a nested loop.

You're also not printing out all the valid values the user entered, unless this happens to be 10. Try making your printing loop like so:
:

  1. for(int j=0; j<idx; ++j)
  2.   cout << list[j] << ' ';

On another note, your code would be much clearer with consistent indentation, and (in my opinion, though I'm sure others will disagree) using the 'opening brace at line start' style, rather than the old K&R style. I had to scan your code a bit to tell where blocks began and ended, whereas if it were done the way I suggest, it'd have been much easier.

Sane Mar 26th, 2008 6:12 AM

Re: duplicate numbers in arrays
 
There's a neat trick you can use to do this.

Use an array of zeroes. For each number they enter, set the n'th element to 1. After you're done, print out all elements that are 1.

This automatically stops itself from printing out duplicates, because setting an element to 1 twice still keeps it at 1.

Also, your validation of each number did not stop it from being added to the array. The assignment specifies to include duplicates as one of the 20 numbers, but do not count invalid numbers as one of the 20.

:

int main() {
    int idx = 0;
    int list[101] = {0}; // make an array of 101 zero's
    int n;
    int i;
   
    cout << "Enter 20 integers between 10 and 100: " << endl;
   
    for (i=0; i<20; i++) { // user inputs 20 numbers
     
        do {
            cout << "Enter number " << i+1 << ": ";
            cin >> n;
        } while (n < 10 || n > 100);  // input must be between 10 and 100

        list[n] = 1;  // this tells us the n'th number has been used

    }
   
    for ( int j = 10; j <= 100; j++ )
        if(list[j] == 1)
            cout << j << " ";  // index of all numbers that have a 1
       
    system("pause");
    return 0;
}


Note that this does not mantain the order the numbers were inputted.

If you need to mantain the order, you could keep your original code, and then use this method to output the array. As you're outputting it, set the element to 1. Then make sure you don't output a number if the list is set to 1 for that value.

Ooble Mar 26th, 2008 6:46 AM

Re: duplicate numbers in arrays
 
This sounds like a homework assignment to me, so I'm not sure if you'd be allowed to do this, but it would be really easy with sets. Sets are a type of data structure which are always ordered and can only store unique values, which sounds like what you're looking for. There's a set class in the STL.

To initialise a set:
:

set<int> list;
To put stuff in:
:

list.insert(n);
Don't worry about putting stuff in twice - it'll just ignore the duplicates.
And to get stuff out:
:

for (set<int>::iterator i = list.begin(); i != list.end(); i++) {
    cout << *i << " ";
}


lectricpharaoh Mar 26th, 2008 7:39 PM

Re: duplicate numbers in arrays
 
I made a boo-boo:
Quote:

Originally Posted by lectricpharaoh
:

  1. if(isValueInArray(n, list, idx)
  2. {
  3.   list[idx] = n;
  4.   ++idx;
  5. }


You need to invert that condition, and I missed a parenthesis:
:

if(!isValueInArray(n, list, idx))
{
  list[idx] = n;
  ++idx;
}


lectricpharaoh Mar 26th, 2008 7:40 PM

Re: duplicate numbers in arrays
 
Double post, oops.


All times are GMT -5. The time now is 12:46 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC