Created
January 28, 2016 20:01
-
-
Save matthewaveryusa/8d7de93401de96021bfe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <string> | |
#include <vector> | |
#include <cstring> | |
#include <string> | |
#include <fstream> | |
#include <streambuf> | |
#include <iostream> | |
#include <ctime> | |
// 5 statements | |
template <class InputIt, class ForwardIt, class BinOp> | |
void for_each_token(InputIt first, InputIt last, | |
ForwardIt s_first, ForwardIt s_last, | |
BinOp binary_op) | |
{ | |
while (first != last) { | |
const auto pos = find_first_of(first, last, s_first, s_last); | |
binary_op(first, pos); | |
if (pos == last) break; | |
first = next(pos); | |
} | |
} | |
// 2 statements | |
std::pair<size_t, size_t> DoTristansWay(std::string str) | |
{ | |
size_t count = 0; | |
size_t max_len = 0; | |
constexpr char delims[] = " \n\t\r\f"; | |
for_each_token(str.cbegin(), str.cend(), | |
delims, delims + sizeof(delims), | |
[&count,&max_len] (std::string::const_iterator first, std::string::const_iterator second) { | |
if (first != second) | |
max_len = std::max(max_len, (size_t) std::distance(first, second)); | |
++count; | |
}); | |
return {count,max_len}; | |
} | |
// 5 statements | |
template <class InputIt, class ForwardIt, class BinOp> | |
void for_each_token2(InputIt first, InputIt last, | |
ForwardIt s_first, ForwardIt s_last, | |
BinOp binary_op) | |
{ | |
auto max_char = std::max_element(s_first, s_last); | |
auto min_char = std::min_element(s_first, s_last); | |
while (first != last) { | |
auto pos = first; | |
while(*pos < *min_char || *pos > *max_char) ++pos; | |
pos = find_first_of(pos, last, s_first, s_last); | |
binary_op(first, pos); | |
if (pos == last) break; | |
first = next(pos); | |
} | |
} | |
// 2 statements | |
std::pair<size_t, size_t> DoMattsWay(std::string str) | |
{ | |
size_t count = 0; | |
size_t max_len = 0; | |
constexpr char delims[] = " \n\t\r\f"; | |
for_each_token2(str.cbegin(), str.cend(), | |
delims, delims + sizeof(delims), | |
[&count,&max_len] (std::string::const_iterator first, std::string::const_iterator second) { | |
if (first != second) | |
max_len = std::max(max_len, (size_t) std::distance(first, second)); | |
++count; | |
}); | |
return {count,max_len}; | |
} | |
static bool IsDelim( char tst ) | |
{ | |
const char* DELIMS = " \n\t\r\f"; | |
do // Delimiter string cannot be empty, so don't check for it. Real code should assert on it. | |
{ | |
if( tst == *DELIMS ) | |
return true; | |
++DELIMS; | |
} while( *DELIMS ); | |
return false; | |
} | |
std::pair<size_t,size_t> DoJoshsWay(std::string& str) | |
{ | |
size_t count = 0; | |
size_t max_len = 0; | |
char* pMutableString = (char*) malloc( str.size()+1 ); | |
strcpy( pMutableString, str.c_str() ); | |
char* p = pMutableString; | |
// skip leading delimiters | |
while( *p && IsDelim(*p) ) | |
++p; | |
while( *p ) | |
{ | |
// note start of token | |
char* pTok = p; | |
do// skip non-delimiters | |
{ | |
++p; | |
} while( !IsDelim(*p) && *p ); | |
// clobber trailing delimiter with null | |
*p = 0; | |
max_len = std::max(max_len, (size_t) std::distance(pTok, p)); | |
++count; | |
do // skip null, and any subsequent trailing delimiters | |
{ | |
++p; | |
} while( *p && IsDelim(*p) ); | |
} | |
free(pMutableString); | |
return {count,max_len}; | |
} | |
int main() { | |
std::ifstream t("sponza.obj"); | |
std::string str((std::istreambuf_iterator<char>(t)), | |
std::istreambuf_iterator<char>()); | |
{ | |
clock_t begin = clock(); | |
for(int i = 0; i < 10; ++i) { | |
DoTristansWay(str); | |
} | |
clock_t end = clock(); | |
std::cout << end - begin << std::endl; | |
} | |
{ | |
clock_t begin = clock(); | |
for(int i = 0; i < 10; ++i) { | |
DoMattsWay(str); | |
} | |
clock_t end = clock(); | |
std::cout << end - begin << std::endl; | |
} | |
{ | |
clock_t begin = clock(); | |
for(int i = 0; i < 10; ++i) { | |
DoJoshsWay(str); | |
} | |
clock_t end = clock(); | |
std::cout << end - begin << std::endl; | |
} | |
} | |
//mavery@bos-lp86w:~$ g++ -std=c++1y ~/main.cpp -O3 && ./a.out | |
//1003632 | |
//741816 | |
//4199091 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment