Arrays homework question

I have this homework question:

Write and test a program that read in n integers (max value for n is 20), each integer has

a value between 0 and 100 inclusive. You program should then print out the unique values

among the input numbers and the count of these values.

Sample input:

1
2
Enter a the number of integers = 8
Enter 8 integers: 5 6 7 6  6 17 17 35


Sample output:

1
2
3
4
5
Number 5: 1
Number 6: 3  
Number 7: 1 
Number 17: 2
Number 35: 1


This is what I did:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;

int main(){
  int a[20], n;

  cout<< "Please enter the number of integers= ";
  cin>> n;
  cout<<"Please enter"<< n<<" integers: ";

  for (int i=0; i<n; i++)
    cin >> a[i];

  for (int k=0; k< n; k++){
    int sum=0;
    for (int i=0; i< n; i++){
      if (a[i]==a[k])
        sum= sum+1;
    }

    cout<< "Number "<< a[k]<<" : "<< sum<< endl;
  }
}
Hello laurencurtis,

Welcome to the forum.

Your program is lacking a few things. There are no include files to make the program work. Although not necessary there should be a "return 0;" at the end of main.

You should initialize your variables.

You are printing out to many numbers at the end of the outer for loop, i.e., each number entered not a total.

If you break up the program like this:
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
#include <iostream>

//using namespace std;  // <--- Best not to use.

int main()
{
	int a[20], n;

	std::cout << "Please enter the number of integers= ";
	std::cin >> n;
	std::cout << "Please enter" << n << " integers: ";

	for (int i = 0; i < n; i++)
		std::cin >> a[i];


	for (int k = 0; k < n; k++)
	{
		int sum = 0;
		
		for (int i = 0; i < n; i++)
		{
			if (a[i] == a[k])
				sum = sum + 1;
		}

		std::cout << "Number " << a[k] << " : " << sum << std::endl;
	}

	// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}

It makes it much easier to read and understand.

I will see what I can come up with.

hope that helps,

Andy
Last edited on
I found it easier to sort the numbers first.

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
#include<iostream>
using namespace std;

int main() {
	int a[20], n;
	int temp;

	cout << "Please enter the number of integers= ";
	cin >> n;
	cout << "Please enter " << n << " integers: ";

	for (int i = 0; i<n; i++)
		cin >> a[i];

	//sort the numbers
	for (int i = 0; i < n-1; i++) {
		for (int j = i+1; j < n; j++) {
			if (a[i] > a[j]) {
				temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}


	//count duplicates
	int jump = 0;
	for (int i = 0; i < n; i++) {
		int sum = 1;
		for (int j = i+1; j < n; j++) {
			if (a[i] == a[j]) {
				sum++;
				jump++;
			}
		}
		cout << "Number: " << a[i] << " Count: " << sum << endl;
		i = i + jump;
                jump = 0;
	}


	return 0;
}
Last edited on
Hello laurencurtis,

This is an idea I had and then reworked to give you an idea.

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
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <iomanip>

//using namespace std;  // <--- Best not to use.

int main()
{
	constexpr std::size_t MAXNUMS{ 20 };
	constexpr std::size_t MAXNUMS2{ 101 };  // <--- One more than needed to avoid RTEs.

	int a[MAXNUMS]{ 100, 5, 6, 7, 6, 6, 17, 17, 35, 100, 75, 5 };  // <--- Setup for testing.
	int n{ 12 };  // <--- Setup for testing.

	int numCount[MAXNUMS2]{};  // <--- Added. Keeps track of the "sum" of each number.

	//std::cout << "Please enter the number of integers= ";  // <--- These commented lines are done for testing.
	//std::cin >> n;
	//std::cout << "Please enter" << n << " integers: ";

	//for (int i = 0; i < n; i++)
	//	std::cin >> a[i];

	// A different approach for entry.
	//for (int i = 0; i < n; i++)
	//{
	//	std::cout << "Please enter number " << i + 1 << ": ";
	//	std::cin >> a[i];
	//}

	for (int k = 0; k < n; k++)
	{
		int sum = 0;
		
		for (int i = 0; i < n; i++)
		{
			if (a[i] == a[k])
			{
				sum = sum + 1;
				numCount[a[i]] = sum;  // <--- Added;
			}
		}

		//std::cout << "Number " << a[k] << " : " << sum << std::endl;  // <--- Moved to for loop.
	}

        std::cout << "\n\n" << std::endl;

	for (size_t lc = 0; lc < MAXNUMS2; lc++)
	{
		if(numCount[lc])
			std::cout << "Number " << std::setw(3) << lc << " : " << numCount[lc] << std::endl;
	}


	// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
	// The next line is needed for normal input. Not needed for testing.
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}


Lines 8 and 9 are the better way to define an array. This way if you need to change the size you only have to make the change in one place. More often the name "MAXSIZE" is used for this, but a good descriptive name works. The capital letters will let you know that it is defined as a constant. If "constexpr" does not work "const" will work fine.

Lines 11 and 12 are set up to avoid having to enter numbers every time you test the program. When working properly remove the contents and leave the empty {}s.

Line 14 I added. Using the numbers in "a" as a subscript to "numCounr" you can store the sum of how many time it appears in "a".

In the two nested for loop I added one line to the if statement. You should see what is happening there.

The last for loop just prints out the total or (sum) for each number in the arrays. The if statement executes only if the value of "numCount[lc]" is greater than 0. Looking back at line 14 you will see the array was initialized to zero and that means every element of the array.

The last lines just before the "return" will keep the console window open if needed and there are many who need this. Once the program is finished they can either be commented out or removed.

As a benefit the output looks sorted from lowest to highest.

Hope that helps,

Andy
There are a few different ways to approach this, and it seems your output is correct; just that it's repeating a few times more than it should.

Just to summarize input rules: up to 20 integers from 0 to 100, inclusive.
Example input: 5 6 7 6 6 17 17 35

Your strategy
1. Store all input in a size-20 array, exactly as it was entered { 5, 6, 7, 6 ... }
2. Analyze the array for repetitions. One minor optimization here is that your count could start at 1, and inner loop could begin its index at (outer_index + 1)
3. A problem of showing the results appeared -- it seems at first glance that you'd either need more space to separately pair the token with its count, or suffer multiple output repetitions

A workaround to fix #3 would be to alter the array after examining that index -- for example, setting values of duplicates (inner loop) to -1. We know the user could not have entered a -1 because of specification in range [0,100]:
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
#include <iostream>

using namespace std;

int main()
{
    int total;
    cout << "Please input the total number of integers (up to 20): ";
    cin >> total;
    if (total <= 0)
    {
        cout << "Error: total '"<< total <<"' should be greater than 0" << endl;
        return -1;
    }

    cout << "Please input " << total << " space-separated integers: ";
    int a[20];
    for (int i=0; i<total; ++i)
        cin >> a[i];

    // Analysis by setting duplicates to a "skip me" value during counting    
    int count;
    cout << endl << "Frequencies:" << endl;
    for (int i=0; i<total; ++i)
    {
        if (a[i] == -1)  // Skip on -1
            continue;

        count = 1;
        cout << "  " << a[i] << ": ";
        for (int j=i+1; j<total; ++j)
        {
            if (a[j] == a[i])
            {
                count += 1;
                a[j] = -1;
            }
        }
        cout << count << endl;
    }

    return 0;
}

Please input the total number of integers (up to 20):  8
Please input 8 space-separated integers:  5 6 7 6  6 17 17 35

Frequencies:
  5: 1
  6: 3
  7: 1
  17: 2
  35: 1

Just saw Andy's second response -- yep, this is the second strat I was going to mention, though the it should be done with just one O(n) loop without nesting:

1. Grab 101 indices of space to track frequencies of all numbers in range 0 to 100, inclusive
2. Initialize all these to 0
3. At the moment of input, increment values in the indices as each input number is read

Also shown here is another way to do a loop X times, by decrementing the total:
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
#include <iostream>

using namespace std;

int main()
{
    const int MAX = 100;
    int total;
    cout << "Please input the total number of integers (1 to 20): ";
    cin >> total;
    if (total <= 0)
    {
        cout << "Error: total '"<< total <<"' should be greater than 0" << endl;
        return -1;
    }

    cout << "Please input " << total << " space-separated integers (0 to "
         << MAX << "): ";

    // Using index to store frequency for all possible values in range    
    int a[MAX+1]{};
    int n;
    while (total--)
    {
        cin >> n;
        a[n] += 1;
    }

    // Analysis is now just a matter of outputting non-zero values    
    cout << endl << "Frequencies:" << endl;
    for (int i=0; i<=MAX; ++i)
    {
        if (a[i])
            cout << "  " << i << ": " << a[i] << endl;
    }

    return 0;
}


A careful observer might wonder, "Hmm... is there a way to avoid using more space than I need, and avoid iterating through 80+ indices of zeroes before spotting my input?". Since this latest strat's loop actually iterates 101 times, it could ironically be slower than the previous strat's nested (total*total), if total is 10 or less.

And so, we come to one of my great loves: maps. This is not an array solution, but is pretty much the go-to strat for calculating frequencies. The key is the token (an integer in this case), and the value is an integer that increases with each sighting of that token. (Aside: std::map is ordered by default, but if you need that extra performance boost, you could use std::unordered_map). In C++, the key-value pairs are stored in "first" and "second" variables, respectively.

A bonus over strat #2 is that the user is no longer limited to range [0, 100] because we don't explicitly need to spend time acquiring this space.
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
#include <iostream>
#include <map>

using namespace std;

int main()
{
    int total;
    cout << "Please input the total number of integers (1 to 20): ";
    cin >> total;
    if (total <= 0)
    {
        cout << "Error: total '"<< total <<"' should be greater than 0" << endl;
        return -1;
    }

    cout << "Please input " << total << " space-separated integers: ";
    map<int,int> freq;
    int n;
    while (total--)
    {
        cin >> n;
        freq[n] += 1;
    }
    cout << endl << "Frequencies:" << endl;
    for (auto& kv : freq)
        cout << "  " << kv.first << ": " << kv.second << '\n';

    return 0;
}

Last edited on
Topic archived. No new replies allowed.