Re: C++ programming challenge
Hi,
here's my code. StopWatch source needs to be added on top of the file. I
cannot post it as comment on the page because it says my "html tag"
<fstream> is not accepted... Oo...
I would prefer to start the timing *after* the file has been read,
because this way it's too I/O limited.
Regards,
Nils
//////////
#include <fstream>
#include <iostream>
#include <time.h>
using namespace std;
static const size_t g_blockSize = 1024 * 1024; // 1MB
static char g_buf[g_blockSize];
int main(int argc, char* argv[])
{
if( argc < 2 )
{
std::cout << "usage: <app> <text file>" << std::endl;
return -1;
}
unsigned int letterFreq[256];
memset( letterFreq, 0, sizeof(letterFreq) );
// start counting time
CStopWatch s;
s.startTimer();
FILE* hFile = fopen( argv[1], "rb" ); // binary mode please
if( 0 == hFile )
{
std::cout << "file << " << argv[1] << "couldn't be opened." << std::endl;
return -1;
}
// count chars
size_t totalReadAmount = 0;
size_t countRead = fread( g_buf, 1, g_blockSize, hFile );
while( countRead > 0 )
{
totalReadAmount += countRead;
// count chars
int remaining = (int)countRead;
{
char* ptr = g_buf;
size_t n = int(countRead+7)/8;
switch(countRead&7)
{
case 0: do{ letterFreq[ *ptr++ ]++;
case 7: letterFreq[ *ptr++ ]++;
case 6: letterFreq[ *ptr++ ]++;
case 5: letterFreq[ *ptr++ ]++;
case 4: letterFreq[ *ptr++ ]++;
case 3: letterFreq[ *ptr++ ]++;
case 2: letterFreq[ *ptr++ ]++;
case 1: letterFreq[ *ptr++ ]++;
}while( --n > 0 );
}
}
countRead = fread( g_buf, 1, g_blockSize, hFile );
}
// compute result in percent
const double hunderedDivFileSize = 100.0 / double(totalReadAmount);
for( char i='a'; i<='z'; i++ )
{
unsigned int totalLetterFreq = letterFreq[i] + letterFreq[ i + 'A' -
'a' ];
const double freq = hunderedDivFileSize * double(totalLetterFreq);
cout << i << ' ' << freq << "%" << std::endl;
}
s.stopTimer();
cout << "Total Time: " << s.getElapsedTime() << std::endl;
fclose( hFile );
return 0;
}