There was a question, it is necessary to replace the same characters in the entered text with the "signature". Using #include <vector> everything is solved quite simply, but you cannot use it (the size is updated by itself). How to implement this task using a char array or string ?

We have the string aaaa345rr, the user enters the number 2, all characters in a row going 2 or more times are changed to the signature {number, character}. The available line at the output {4, a} 345 {2, o}

  • At the expense of the algorithm, I thought of doing this: Cycle going along the line, each character after the first is compared with the current one for comparison, if it is equal, we increase the character counter and remember the position of the current one, otherwise, if the repeat counter is greater than 1, then cut all characters from the current one, which is compared to the current one, which is in a loop and put the repetition counter on the cut out space, but how to "dynamically" then change the size of the array, if I for example replace 3 'a' characters with {3, a}? - LokenGarvel '
  • @jfs, when replacing part of a string with a signature, the size of the array changes, problems with updating the size of the array. - LokenGarvel '
  • @jfs, while (str[i+1]!='\0') { if (str[i] == str[i + 1]) for (int x=0;(x<"размер строки" && str[x]!='\0');x++) then I make a replacement where the size of the string changes accordingly, the size needs to be updated, the problem is here. - LokenGarvel '

2 answers 2

In order to obtain {4,а}345{2,о} from аааа345рр , that is, to implement Run Length Coding (RLE) :

 template<class InputIt, class OutputIt> OutputIt rle_encode(InputIt first, InputIt last, OutputIt d_first) { if (first == last) // empty return d_first; auto prev = *first++; // previous char uintmax_t count = 1; for ( ; first != last; ++first, ++count) { if (prev != *first) { // ended run of the same consecutive elements d_first = write_rle_run(d_first, prev, count); // write the run prev = *first; // start new run count = 0; } } return write_rle_run(d_first, prev, count); } 

This is a translation from Python's rle_encode () function .

write_rle_run() writes the found series of characters in a row to the result:

 template<class OutputIt, class C> OutputIt write_rle_run(OutputIt d_first, C character, uintmax_t count) { if (count > 1) { *d_first++ = '{'; for (char digit : std::to_string(count)) *d_first++ = digit; *d_first++ = ','; *d_first++ = character; *d_first++ = '}'; } else { assert(count == 1); *d_first++ = character; } return d_first; } 

This also works for an array:

 const char a[] = "aaaa345pp"; char output[5*(sizeof a)/2]; rle_encode(std::begin(a), std::end(a), output); 

and for string:

 std::string text = "aaaa345pp"; std::string s; rle_encode(std::begin(text), std::end(text), std::back_inserter(s)); 

and for input / output streams:

 std::istream_iterator<char> chars{std::cin}, eof; rle_encode(chars, eof, std::ostream_iterator<char>(std::cout)); 

Full code example .

In the write_rle_run() you can transfer the desired number of repetitions from the user and adapt the if (count > 1) condition.

To perform the conversion in the opposite direction, you can use rle_decode() .

  • and how to use this algorithm to return the text to its original state, that is, to decode the text? - LokenGarvel '
  • one
    @LokenGarvel 'is a separate [simple] question. Here is an example for a similar format on Python . It does not matter what algorithm the data generates. How to draw depends primarily on the format of the data and in what form you get them. You can use regular expressions or you can use the hands of the {count,char} series to search and unpack. An example of how one digit on C numbers are recognized . Try to implement a solution, and if specific difficulties arise, ask a separate Stack Overflow question. - jfs

Using string everything is solved by a small function. The question is closed

  while (first != str.end()) { string::const_iterator second = first + 1; while (second != str.end() && *first == *second) ++second; size_t n = second - first; if (n > 1) { stringstream ss; ss << n; ret += string("{")+ss.str() + string(",") + *first + string("}"); first = second; } else { ret += *first++; } }