fork(1) download
  1. #include <cassert>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <iterator>
  5. #include <string>
  6.  
  7. namespace
  8. {
  9. template<class It, class C>
  10. It write_rle_run(It d_first, C prev, uintmax_t count) {
  11. if (count > 1) {
  12. *d_first++ = '{';
  13. for (char d : std::to_string(count))
  14. *d_first++ = d;
  15. *d_first++ = ',';
  16. *d_first++ = prev;
  17. *d_first++ = '}';
  18. }
  19. else {
  20. assert(count == 1);
  21. *d_first++ = prev;
  22. }
  23. return d_first;
  24. }
  25.  
  26. /// aaaab4cpp -> {4,a}b4c{2,p}
  27. template<class InputIt, class OutputIt>
  28. OutputIt rle_encode(InputIt first, InputIt last, OutputIt d_first)
  29. {
  30. if (first == last) // empty
  31. return d_first;
  32.  
  33. auto prev = *first++; // previous char
  34. uintmax_t count = 1;
  35. for ( ; first != last; ++first, ++count) {
  36. if (prev != *first) { // ended run of the same consecutive elements
  37. d_first = write_rle_run(d_first, prev, count); // write the run
  38. prev = *first; // start new run
  39. count = 0;
  40. }
  41. }
  42. return write_rle_run(d_first, prev, count);
  43. }
  44. }
  45.  
  46. int main()
  47. {
  48. const char a[] = "aaaa345pp";
  49. char output[sizeof a];
  50. rle_encode(std::begin(a), std::end(a), output);
  51. std::cout << output << '\n';
  52.  
  53.  
  54. std::string text = "aaaa345pp";
  55. rle_encode(std::begin(text), std::end(text), std::ostream_iterator<char>(std::cout));
  56. std::cout << '\n';
  57.  
  58. std::string s;
  59. rle_encode(std::begin(text), std::end(text), std::back_inserter(s));
  60. std::cout << s << std::endl;
  61.  
  62. std::istream_iterator<char> chars{std::cin}, eof;
  63. rle_encode(chars, eof, std::ostream_iterator<char>(std::cout));
  64. std::cout << '\n';
  65. }
  66.  
Success #stdin #stdout 0s 15232KB
stdin
aaaa345pp
stdout
{4,a}345{2,p}
{4,a}345{2,p}
{4,a}345{2,p}
{4,a}345{2,p}