Collecting Like Numbers in an Array

I have a bool function with an array where I am trying to find a pair of matching values. These values can be any where in the array, so as long as there are two elements with the same value then I need to return true. I wrote my code out on paper first and felt good about my approach; however, I am not sure if I am returning the bool function correctly 1st time doing one), because if I put in my return true statement it always returns true. Then, when I put in my else return false statement it always returns false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  bool pair(const int array[])
{
	int value = 0, count = 0;

	for (int i = 0; i < VALUES; i++) {

		value = hand[i];
		for (int j = 1; j <= VALUES; j++) {

			if (value == array[j]) {
				count++;

				if (count == 2)
					return true;

				else
					return false;

			}
		}
	}
}
Last edited on
You need to reset the value of count for each iteration of the outer loop because the count variable keeps track of the duplicates for each element in the hand array.
1
2
3
4
    for (int i = 0; i < NUM_CARDS; i++) {
        value = hand[i];
        count = 0;
        for(...)


I don't understand why you have j start from 1 and then use less-than-equal to NUM_CARDS on line 8. You will end up going out-of-bound. My assumption is that your NUM_CARDS is the total number of elements in the hand array, so what do you believe will happen if you use hand[NUM_CARDS]?

In your inner loop, j needs to start from 0. If one of the matching element happens to be at index 0, you will miss it.
 
for (int j = 0; j < NUM_CARDS; j++) 


You cannot use if ... else .. to return true or false on line 13 and 16. The way it is currently set up, your program will end up processing only the first element in the array. Your goal is to check every element in the array for duplicates. Am I correct?

You need to check to see if count == 2 outside your inner loop at the very end of your outer loop and return true if the count is 2. At the end of the function outside your outer loop, you can return false because you can be confident that if your execution reached past your outer loop, it means there was no duplicates in the array.
1
2
3
4
5
6
7
8
        for (int j = 0; j < NUM_CARDS; j++) {
            if (value == hand[j]) {
                count++;
                if (count == 2) return true;
            }
        } // End of Inner Loop
    } // End of Outer Loop
    return false;


Hope this helps. Let me know if I misunderstood your requirements.

EDIT: You can check if count == 2 in the inner loop.
Last edited on
Hello stoneJax,

Your question along with the bit of code is a little abstruse and poses more questions than answers.

Where and how is "VALUES" defined?

in line where did "hand" come from?

I would most likely loose the "else" statement and put the "return false;" before the closing } of the function.

I am thinking that you might want this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool pair(const int array[], const int hand[])  // <--- May need the second parameter.
{
	int value = 0, count = 0;

	for (int i = 0; i < VALUES; i++)
	{
		value = hand[i];

		for (int j = 1; j <= VALUES; j++)
		{
			if (value == array[j])
			{
				count++;

				if (count == 2)
					return true;
			}
		}
	}

	return false;
}

As I stared at your code I realized that you could loose the variable "value" and write the first if statement as if (hand[i] == array[j]) because the value of "i" only changes when the inner for loop is finished.

Hope that helps,

Andy
Thanks guys!

I reset the counter and got rid of the else statement in favor of the return statement at the end of the outer loop and now it works.

I also played around with changing (int j = 1; j <= VALUES; j++) to
(int j = 0; j < VALUES; j++) and that works too. I didn't do that before because I thought that I would be comparing the first value to itself. Also, your assumption is right about NUM_CARDS is the total number of elements in the hand array.

I also like (hand[i] == array[j]) as it is a little more efficient.
I need to further modify the function so it returns true if there are two sets of pairs with different values, and returns true if there are three of a kind. There are 5 int values in the array taken as user input and can range any where from 2-9. I am not allowed to use any clever algorithms that skip array processing. Any suggestions on how to best go about this?

For example:
2 2 3 4 5 is true, 2 3 2 3 4 is true, 2 2 2 3 3 is true, 2 2 2 3 4 is false, and 2 2 2 2 3 is false.
and returns true if there are three of a kind.
...
2 2 2 3 4 is false

Shouldn't 2 2 2 3 4 be true since there are 3 of a kind?

Since the values are limited to 2-9, create an array of 10 items and store the count of each card type. Note that using range based for loops below would be more reliable.
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
#include <iostream>

using std::cout;

bool checkHand(int hand[5])
{
    int counts[10]{};

    // Get the count of each number in the hand
    for (unsigned i=0; i<5; ++i) {
	++counts[hand[i]];
    }

    // Get the maximum frequency of a number in the hand
    unsigned maxIdx=2;
    for (unsigned i=2; i<=9; ++i) {
	if (counts[i] > counts[maxIdx]) {
	    maxIdx = i;
	}
    }
    cout << "There are " << counts[maxIdx] << " cards with value " << maxIdx
	 << '\n';
    return (counts[maxIdx] == 2 || counts[maxIdx] == 3);
}

int
main()
{
    int hands[5][5] = { {2,2,3,4,5},
		       {2,3,2,3,4},
		       {2,2,2,3,3},
		       {2,2,2,3,4},
		       {2,2,2,2,3}
    };

    for (unsigned i=0; i<5; ++i) {
	cout << checkHand(hands[i]) << '\n';
    }
    return 0;
}
Thank you for the feed back. I appreciate it!
Topic archived. No new replies allowed.