Re: C++ programming challenge
For what it's worth I also coded up a version
that read longs instead of chars, and
accumulated 16 bits at a time in the "count"
array (fixing the calculation at the end).
Since the strategy has changed for the testing,
here's the code I previously referred to. Runs
faster than any of the others I've tried (on
my computer, of course).
Uses some ugly casting which I'm sure some will
disagree with. Also, it assumes longs are no
more than 64 bits. And it assumes chars are 8
bits. Whatever. It's more to demonstrate the
idea than anything else.
// -----------------------------------------------
#include <iostream>
#include <fstream>
using namespace std;
#define BUFFSIZE 4096
char const* digit = "0123456789";
char const* alpha = "abcdefghijklmnopqrstuvwxyz";
char const* ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWZYZ";
int main(int argc, char* argv[]) {
if( argc <= 1 )
return (cout << "Please provide a file name" << endl, 1);
char buff[BUFFSIZE];
long count[65536] = {0};
long total_alpha[26] = {0};
long count2[256] = {0};
CStopWatch s;
s.startTimer();
ifstream f(argv[1]);
if (f.good()) {
do {
f.read(buff, BUFFSIZE);
streamsize bytesread = f.gcount();
streamsize i = 0;
for (; i < bytesread; i += sizeof(unsigned
long)) {
unsigned long c = *(reinterpret_cast<unsigned long*>(buff + i));
unsigned long d = c >> 32;
++count[c & 0xFFFF];
++count[d & 0xFFFF];
c >>= 16;
d >>= 16;
++count[c & 0xFFFF];
++count[d & 0xFFFF];
}
for (; i < bytesread; ++i)
++count[buff[i]];
} while (!f.eof());
for (int i = 0; i < 65536; ++i) {
count2[i & 0xFF] += count[i];
count2[(i >> 8) & 0xFF] += count[i];
}
unsigned long total = 0;
for (int i = 0; i < 26; ++i) {
unsigned long x = count2[alpha[i]] + count2
[ALPHA[i]];
total_alpha[i] = x;
total += x;
}
float p2 = 100.0f / total;
for (int i = 0; i < 26; ++i) {
float p = p2 * total_alpha[i];
cout << alpha[i] << ' ' << p << '%' << '\n';
}
cout << endl;
}
s.stopTimer();
cout << "Time elapsed: " << s.getElapsedTime() << endl <<
endl;
return 0;
}