#include <iostream>
#include <vector>
usingnamespace std;
struct number{int value; int count;};
void fill_array(vector<number> &numbers);
void out(vector<number> &numbers);
int main()
{
vector<number> numbers;
fill_array(numbers);
out(numbers);
system("pause");
return 0;
}
void fill_array(vector<number> &numbers)
{
int next;
cout << "Please enter a sequence of non-zero integers (up to 50)\n"
<< "and this program will tell you the count of each different integer used\n";
cout << "Enter a negative number to end sequence.\n";
cin >> next;
while((next > 0))
{
// Insert first element into vector if empty
if(numbers.empty())
{
number newNumber;
newNumber.count = 1;
newNumber.value = next;
numbers.push_back(newNumber);
}
else
{
// Search vector for duplicates
vector<number>::iterator iter = numbers.begin();
while(iter != numbers.end())
{
if(iter->value == next)
{
iter->count++;
break;
}
iter++;
}
// If finished searching and didn't find the number then create new element in vector
if(iter == numbers.end())
{
number newNumber;
newNumber.count = 1;
newNumber.value = next;
numbers.push_back(newNumber);
}
}
// Prompt for next number
cin >> next;
}
}
void out(vector<number> &numbers)
{
cout << "Number \t Count\n";
vector<number>::iterator iter = numbers.begin();
while(iter != numbers.end())
{
cout << iter->value << "\t" << iter->count << endl;
iter++;
}
}
Just for fun, here's a version of your program using an stl map that will automagically not duplicate print and count for you - using the right data structure and algorithms will save you a lot of time and debugging.
#include <iostream>
#include <map>
usingnamespace std;
void fill_map( map<unsigned,unsigned>& m );
void out( const map<unsigned,unsigned>& m );
int main()
{
map<unsigned,unsigned> m;
fill_map( m );
out( m );
return 0;
}
void fill_map( map<unsigned,unsigned>& m )
{
int next;
cout << "Please enter a sequence of non-zero integers (up to 50)\n"
<< "and this program will tell you the count of each different integer used\n";
cout << "Enter a negative number to end sequence.\n";
cin >> next;
map<unsigned,unsigned>::iterator it;
while( next > 0 )
{
if ( (it=m.find( next ))==m.end() )
{
m[ next ] = 1;
} else {
m[ next ] = it->second + 1;
}
cin >> next;
}
}
void out( const map<unsigned,unsigned>& m )
{
int count;
cout << "Number \t Count\n";
map<unsigned,unsigned>::const_iterator it;
for ( it=m.begin(); it!=m.end(); ++it )
{
cout << it->first << "\t" << it->second << endl;
}
}
No, an stl map initially contains nothing. Actually, let me be more specific - when you insert some value into a map and that value is POD (plain-old-data), it's just copied. If it is a class, it is copy-constructed. If it's a pointer, the pointer is copied.
On Line 29, you will see that I initialize the value at next to 1.
stl data structures are all value-based and know nothing about memory.
That means if you called new before inserting something into an stl map, you will have to call delete before that stl map falls out of scope (otherwise, you have a memory leak). This is true if your stl map "owns" those pointers. In certain instances, you can have two stl maps, one that owns the pointers and a second that doesn't. In that case, you don't want to call delete on the latter, but you need to call it on the former. It is up to you to maintain consistency. This is true of as many stl data structures you use. One of them can "own" its items while the others don't. It's not very hard to maintain if your code is clear and consistent, but you do have to be vigilant.
In this case, since our key and values are all POD (plain-old-data), we don't need to worry about memory at all. Stuff will go away when the map goes away.