This program reads strings of numbers from a txt file, converts them to integers, stores them in a vector, and then tries to output them in an organized fashion like so....
If txt file says:
7 5 5 7 3 117 5
The program outputs:
3
5 3
7 2
117
so if the number occurs more than once it outputs how many times that happens. Here is the code so far.
#include "std_lib_facilities.h"
int str_to_int(string& s)
{
stringstream ss(s);
int num;
ss >> num;
return num;
}
int main()
{
cout << "Enter file name.\n";
string file;
cin >> file;
ifstream f(file.c_str(), ios::in);
string num;
vector<int> numbers;
while(f>>num)
{
int number = str_to_int(num);
numbers.push_back(number);
}
sort(numbers.begin(), numbers.end());
for(int i = 0; i < numbers.size(); ++i)
{
if(i = 0 && numbers[i]!= numbers[i+1]) cout << numbers[i] << endl;
if(i!=0 && numbers[i]!= numbers[i-1])
{
cout << numbers[i] << '\t' << counter << endl;
counter = 0;
}
else ++counter;
}
}
Edit: Program is getting stuck. Looking for an infinite loop right now.
You could use a map of numbers to counters:
typedef map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
... then iterate over the map to print results.
EDIT: As suggested by lazypython: if you have the TR1 extensions [wikipedia.org] available, unordered_map should have better performance...
typedef std::tr1::unordered_map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
How about using a map, where the key is the number you're tracking and the value is the number of occurrences?
If you must use a vector, you've already got it sorted. So just keep track of the number you previously saw. If it is the same as the current number, increment the counter. Every time the number changes: print out the current number and the count, reset the count, set the last_seen number to the new number.
Using a map is the practical solution. What you should do is to solve this problem :)
This is called frequency counter. So, you have a sorted vector and all what you have to do is to count successive equal numbers. In other words, you have to check each number with its successor.
for(size_t i = 0; i < numbers.size(); i++)
{
size_t count = 1;
size_t limit = numbers.size() - 1;
while(i < limit && numbers[i] == numbers[i+1])
{
count++;
i++;
}
std::cout << numbers[i] << "\t" << count << std::endl;
}
This program reads strings of numbers from a txt file, converts them to integers, stores them in a vector, and then tries to output them in an organized fashion like so....(emphasis added)
What is the point of this storage step? If you are reading the numbers from a file, then you already have them in order, ready to be processed (counted) one at time, as you encounter them.
However, I would need a way for it to know when it sees a new number.
I advise you to have a look at std::set
or std::map
. I expect either of these containers would do what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With