Advertisement
Guest User

Untitled

a guest
Dec 20th, 2012
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.15 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2.  
  3. // trim_timers.cpp : Defines the entry point for the console application.
  4. //
  5.  
  6. #include <iostream>
  7. #include <string>
  8. #include <sstream>
  9. #include <vector>
  10. #include <utility>
  11.  
  12. #include "Timer.h"
  13.  
  14. using namespace std;
  15.  
  16. struct TrimTest;
  17.  
  18. struct TestSpec
  19. {
  20.     string name;
  21.     string url;
  22.     TrimTest * test;
  23.  
  24.     TestSpec(string n, string u, TrimTest * t)
  25.         : name(n), url(u), test(t)
  26.     {}
  27. };
  28.  
  29. vector<TestSpec> all_tests;
  30.  
  31. void register_test(string name, string url, TrimTest * test)
  32. {
  33.     all_tests.push_back(TestSpec(name, url, test));
  34. }
  35.  
  36. struct TrimTest
  37. {
  38.     TrimTest(string test_name, string url)
  39.     {
  40.         register_test(test_name, url, this);
  41.     }
  42.  
  43.     virtual char* trim_right(char * str) =  0;
  44. };
  45.  
  46. #define CONCAT(a, b) CONCAT2(a, b)
  47. #define CONCAT2(a, b) a##b
  48. #define TRIM_RIGHT(name, url)    TRIM_RIGHT_IMPL(name, url, CONCAT(test, __LINE__))
  49.  
  50. #define TRIM_RIGHT_IMPL(name, url, classname) \
  51. struct classname : TrimTest { \
  52.     classname() : TrimTest(name, url) {} \
  53.     char * trim_right(char * str); \
  54. }; \
  55.     classname CONCAT(classname, _obj); \
  56.     char * classname::trim_right(char * str)
  57.  
  58.  
  59. TRIM_RIGHT("article", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx")
  60. {
  61.     int len = strlen(str) - 1;
  62.     if(len == 0 || str[len] != ' ') return str;
  63.     str[strlen(str)-1] = '\0';
  64.     return trim_right(str);
  65. }
  66.  
  67.  
  68. TRIM_RIGHT("gallier2", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx#397535")
  69. {
  70.     size_t l = strlen(str);
  71.     while(l && str[--l] == ' ')
  72.         str[l] = 0;
  73.     return str;
  74. }
  75.  
  76.  
  77. char *trim_right_r_impl_Aufgehaben(char *str,int len)
  78. {
  79.     if(len == 0 || str[len] != ' ') return str;
  80.     str[len] = '\0';
  81.     return trim_right_r_impl_Aufgehaben(str,len-1);
  82. }
  83.  
  84. TRIM_RIGHT("Aufgehaben", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx#397539")
  85. {
  86.     int len = strlen(str);
  87.     return trim_right_r_impl_Aufgehaben(str,len-1);
  88. }
  89.  
  90.  
  91. TRIM_RIGHT("Xarthaneon the Unclear", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx#397558")
  92. {
  93.     for(int i = strlen(str) - 1; i >= 0; i--)
  94.         if(str[i] == ' ')
  95.             str[i] = '\0';
  96.     return str;
  97. }
  98.  
  99.  
  100. TRIM_RIGHT("PleegWat", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?pg=2#397572")
  101. {
  102.     char * p = NULL;
  103.     while( *str )
  104.     {
  105.         if( p && !isspace(*str) )
  106.             p = NULL;
  107.         if( !p && isspace(*str) )
  108.             p = str;
  109.         str++; // added
  110.     }
  111.  
  112.     if( p ) *p = '\0';
  113.     return str;
  114. }
  115.  
  116.  
  117. TRIM_RIGHT("I DUNNO LOL", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?pg=2#397623")
  118. {
  119.     char * start = str; // added
  120.     char *end = str;
  121.     while (*str) {
  122.         if (*str++ != ' ') {
  123.             end = str;
  124.         }
  125.     }
  126.     *end = 0;
  127.     return start; // added
  128. }
  129.  
  130.  
  131. TRIM_RIGHT("LK 1", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?pg=3#397636")
  132. {
  133.     char *stop = NULL ;
  134.     char *cursor = str ;
  135.     char current = *cursor ;
  136.     while (current != '\0') {
  137.         int printable = (current > ' ') ;
  138.         if (printable) { if (stop) stop=NULL ; }
  139.         else if (!stop) { stop=cursor ; }
  140.         cursor++ ;
  141.         current = *cursor ;
  142.     }
  143.     if (stop) *stop = '\0' ;
  144.     return str;
  145. }
  146.  
  147.  
  148. #define PRINTABLE(x) (x > ' ')
  149. TRIM_RIGHT("LK 2", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?pg=3#397636")
  150. {
  151.     char *stop = NULL ;
  152.     char *cursor = str ;
  153.     char current ;
  154.     goto First;
  155. NextUnstopped:
  156.     cursor++ ;
  157. First:
  158.     current = *cursor ;
  159.     if (current == '\0') goto End;
  160.     if PRINTABLE(current) goto NextUnstopped;
  161.     stop = cursor ;
  162. FoundMoreWhitespace:
  163.     cursor++ ;
  164.     current = *cursor ;
  165.     if (current == '\0') goto End;
  166.     if (!PRINTABLE(current)) goto FoundMoreWhitespace ;
  167.     stop = NULL ;
  168.     goto NextUnstopped ;
  169. End:
  170.     if (stop) *stop = '\0' ;
  171.     return str;
  172. }
  173. #undef PRINTABLE
  174.  
  175.  
  176. TRIM_RIGHT("Scott", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?pg=3#397641")
  177. {
  178.     int i = 0, j = 0;
  179.     while ( str[i] != '\0' )
  180.     {
  181.         if ( str[i] != ' ' )
  182.         {
  183.             j = i;
  184.         }
  185.         ++i;
  186.     }
  187.     str[j + 1] = '\0';
  188.     return str;
  189. }
  190.  
  191.  
  192. TRIM_RIGHT("Brendan", "http://thedailywtf.com/Comments/Recursive-Whitespace-Removal.aspx?rnd=344357517&pg=L#397673")
  193. {
  194.     char * start = str; // added
  195.     char *stop;
  196. next:
  197.     while(!isspace(*str)) {
  198.         if(*str == '\0') return start; // modified
  199.         str++;
  200.     }
  201.     stop = str;
  202.     do {
  203.         str++;
  204.         if(*str == '\0') {
  205.             *stop = '\0';
  206.             return start; // modified
  207.         }
  208.     } while(isspace(*str));
  209.     goto next;
  210. }
  211.  
  212.  
  213. // I'll use this type for two things: for correctness tests, it will hold pairs of <input, expected answer>.
  214. // For performance tests, it will hold pairs of <input, short description>.
  215. typedef pair<string, string> StringPair;
  216.  
  217. StringPair correctness_tests[] = {
  218.     StringPair("", ""),
  219.     StringPair(" ", ""),
  220.     StringPair("   ", ""),
  221.     StringPair("  a", "  a"),
  222.     StringPair("a ", "a"),
  223.     StringPair("a   ", "a"),
  224.     StringPair("a b c", "a b c"),
  225.     StringPair("a b ", "a b")
  226. };
  227.  
  228. const int thousand = 1000;
  229. int lengths[] = { 1 * thousand, 10 * thousand, 100 * thousand, 500 * thousand };
  230.  
  231. string repeat(string base, int num)
  232. {
  233.     stringstream ss;
  234.     for (int i=0; i<num; ++i) {
  235.         ss << base;
  236.     }
  237.     return ss.str();
  238. }
  239.  
  240. string exp_description(string base, int exp)
  241. {
  242.     stringstream ss;
  243.     ss << base << "<sup>" << exp << "</sup>";
  244.     return ss.str();
  245. }
  246.  
  247. StringPair repeated_test(string base, int exp)
  248. {
  249.     return StringPair(repeat(base, exp), exp_description(base, exp));
  250. }
  251.  
  252. StringPair make_englishy_test(int length)
  253. {
  254.     return repeated_test("aaaa ", length / 5);
  255. }
  256.  
  257. StringPair make_all_spaces_test(int length)
  258. {
  259.     return repeated_test(" ", length);
  260. }
  261.  
  262. StringPair make_alternating_test(int length)
  263. {
  264.     return repeated_test("a ", length / 2);
  265. }
  266.  
  267. StringPair make_no_spaces_test(int length)
  268. {
  269.     return repeated_test("a", length);
  270. }
  271.  
  272. StringPair make_spaces_then_non_space(int length)
  273. {
  274.     StringPair spaces = make_all_spaces_test(length - 1);
  275.     return StringPair(spaces.first + "a", spaces.second + "a");
  276. }
  277.  
  278. StringPair make_one_final_space(int length)
  279. {
  280.     StringPair spaces = make_no_spaces_test(length - 1);
  281.     return StringPair(spaces.first + " ", spaces.second + " ");
  282. }
  283.  
  284. StringPair make_five_final_space(int length)
  285. {
  286.     StringPair spaces = make_no_spaces_test(length - 5);
  287.     return StringPair(spaces.first + "     ", spaces.second + " <sup>5</sup>");
  288. }
  289.  
  290. typedef StringPair (*PerformanceTestMaker)(int);
  291. PerformanceTestMaker performance_test_makers[] = {
  292.     make_englishy_test,
  293.     make_all_spaces_test,
  294.     make_alternating_test,
  295.     make_no_spaces_test,
  296.     make_spaces_then_non_space,
  297.     make_one_final_space,
  298.     make_five_final_space
  299. };
  300.  
  301. void do_correctness_test(TestSpec const & spec)
  302. {
  303.     std::cout << "    { \"name\": \"" << spec.name << "\", \"url\": \"" << spec.url << "\", \"results\": {";
  304.     for (auto test: correctness_tests) {
  305.         char * copy = new char[test.first.size() + 9];
  306.         copy += 8;
  307.         copy[-1] = ' ';
  308.         strcpy(copy, test.first.c_str());
  309.         string actual = spec.test->trim_right(copy);
  310.         if (copy[-1] != ' ') {
  311.             std::cout << "\"" << test.first << "\": \"<underflow>\", ";
  312.         }
  313.         else if (actual == test.second) {
  314.             std::cout << "\"" << test.first << "\": \"<OK>\", ";
  315.         }
  316.         else {
  317.             std::cout << "\"" << test.first << "\": \"" << actual << "\", ";
  318.         }
  319.     }
  320.     std::cout << "\"dummy\":\"dummy\"}},\n";
  321. }
  322.  
  323. void do_correctness_tests()
  324. {
  325.     std::cout << "{\"correctness\": [\n";
  326.     for (auto implementation: all_tests) {
  327.         do_correctness_test(implementation);
  328.     }
  329.     std::cout << "    {}],\n";
  330. }
  331.  
  332.  
  333. void do_timing_test(TestSpec const & spec)
  334. {
  335.     Timer timer;
  336.     std::cout << "    { \"name\": \"" << spec.name << "\", \"url\": \"" << spec.url << "\", \"results\": {";
  337.     for (auto test_maker : performance_test_makers) {
  338.         for (int length : lengths) {
  339.             StringPair this_test = test_maker(length);
  340.             char * input = strdup(this_test.first.c_str());
  341.             timer.start();
  342.             spec.test->trim_right(input);
  343.             timer.stop();
  344.             std::cout << "\"" << this_test.second << "\": " << timer.getElapsedTimeInSec() << ", ";
  345.         }
  346.     }
  347.     std::cout << "\"dummy\":\"dummy\"}},\n";
  348. }
  349.  
  350.  
  351. void do_timing_tests()
  352. {
  353.     std::cout << "\"timing\": [\n";
  354.     for (auto implementation: all_tests) {
  355.         do_timing_test(implementation);
  356.     }
  357.     std::cout << "{}]}\n";
  358. }
  359.  
  360. int main()
  361. {
  362.     do_correctness_tests();
  363.     do_timing_tests();
  364.     return 0;
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement