I was wondering if anyone can help me out. I am trying to either use a list or a struct as a container to count the frequency of letters in a text file and am having some trouble figuring out the solution.
I have some code below and was first trying to use a struct but can't figure out how to easily navigate this object with a pointer. Does anyone have examples of how to add to and walk through entries in a struct? Isn't a struct like an expandable container?
If I can use the std::list I would rather do that but couldn't really find any examples on this site or on the web that were useful enough after reading the std::list documentation. I need a char variable and an integer the char contains the letter found and the integer is the counter of how many times I found each letter.
Can anyone here help?
Thanks.
Code so far:
#include <iostream>
#include <fstream>
#include <list>
using namespace std;
struct LetterBox {
char letter;
size_t frequency;
LetterBox* Next;
LetterBox(char ch, size_t count, LetterBox* ptr)
{
letter = ch;
frequency = count;
Next = ptr;
}
};
int main() {
new LetterBox(' ',0,nullptr);
// new LetterBox(' ',0,nullptr);
int count = 0;
char ch;
string line;
string FileName;
cout << "Enter the name of the textfile: ";
cin >> FileName;
ifstream file (FileName);
if (file.is_open())
while (file.good())
{
while(getline(file, line)) {
for (int i = 0; i < sizeof(line); i++) {
ch = toupper(line[i]);
count++;
cout << ch;
}
}
file.close();
}
else
{
cout << "Unable to open file:" << FileName << endl;
return 1;
}
return 0;
}
You can experiment a bit, using std::map like you use dict in some other languages, it is Quicker, easier, more seductive and already solve problems if you want to support UTF encoding later.
But if you already know it will only be used for ASCII text there is another way.
Your universe for ASCII is 0-255 (actual 0-128 but lets ignore that in case someone use the extended ASCII). This mean that we can actually in reasonable space cover all outcomes with a
std::array<std::size_t, 256> letters= {0};
You can then replace your inner loop with
for (int i = 0; i < sizeof(line); i++) {
ch = toupper(line[i]);
letter[ch]++;
}
And later write out the result
for (char ch = 'A'; ch <= 'Z'; ch++) {
std::cout << "Letter: '" << ch << "' occured " << letter[ch] << " times\n";
}
This should be roughly the same space usage as a std::map but better locality and far better lookup time. You could get by with using only 27 letters but that adds more conditions.
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