Я реализовал простой рекурсивный алгоритм для RLE (кодирование длины цикла).
Код:
#include <iostream>
using namespace std;
template <size_t N>
struct RLE {
static size_t cnt;
static void Compress(char const p[]) {
// Check current char with next char. If they are not same then print the current character and its count. Then reset the counter to 0 for next itetation.
if (!(*p == *(p + 1))) {
cout << cnt << *p;
cnt = 0;
}
// Call the function again with new character
RLE<N - 1>::Compress(p + 1);
}
};
template <size_t N>
size_t RLE<N>::cnt = 1 + RLE<N - 1>::cnt;
template <>
struct RLE<0> {
static size_t cnt;
static void Compress(char const[]) {
}
};;
//template<> // On uncomenting this like why do I get a error "extraneous template<>, in declaration of variable cnt."
size_t RLE<0>::cnt = 0;
int main(void) {
char const str[]{"mmatsss"};
// -1 since sizeof includes terminating null char.
RLE<sizeof(str) - 1>::Compress(str);
}
Для ввода типа «mmatsss» ожидаемый результат — «2m1a1t3s», но я получаю «1m1a1t1s», т. е. код печатает только первый символ группы. Я не могу понять ошибку в коде. Может кто-нибудь, пожалуйста, взгляните на это и помогите мне понять, что я делаю неправильно здесь.
@Yakk - Adam Nevrsumont Я скомпилировал код на мобильном компиляторе Cxxdroid и получил результат, о котором я упоминал в посте, но когда я попробовал с онлайн-компиляторами, я получил результат, о котором вы упомянули, возможно, мне нужно изменить свой компилятор. дополнительный вопрос, является ли отрицательный результат неполным, не поддающимся проверке и / или вопрос не соответствует стандартам StackOverflow
Я использовал c4droid. И прочитайте код, и он должен делать то, что говорит c4dtoid.
@Yakk-AdamNevraumont У меня на телефоне нет приложения C4Droid. Cxxdroid был бесплатным, поэтому я его использовал.





I am unable to figure out the bug in the code, can someone please take a look at it, and help me to understand what am i doing wrong here.
Проблема в том, что вы инициализируете статический член cnt следующим образом
template <size_t N>
size_t RLE<N>::cnt = 1 + RLE<N - 1>::cnt;
size_t RLE<0>::cnt = 0;
поэтому вы получаете cnt == N, когда компилятор использует инициализированное значение RLE<N - 1>::cnt (случай g++), cnt == 1, когда N > 0, когда компилятор использует ноль для RLE<N - 1>::cnt (случай clang++).
Я не знаю, кто прав, но дело в том, что когда ты пишешь
cout << cnt << *p;
cnt = 0;
вы печатаете cnt в RLE<N> -- так что N или 1, в зависимости от случая -- и обнуляете cnt в RLE<N>.
Но когда вы обнуляете cnt в RLE<N>, cnt в RLE<N-1> остаются неизменными (так что N-1 или 1, в зависимости от случая).
Я не вижу много метапрограммирования в вашем коде, но мне кажется, что возможная коррекция установлена все cnt на 1
template <size_t N>
size_t RLE<N>::cnt = 1;
size_t RLE<0>::cnt = 1;
и установите RNE<N-1>::cnt как cnt + 1 в Compress()
static void Compress(char const p[])
{
if (!(*p == *(p + 1)))
{
cout << cnt << *p;
cnt = 0u;
}
RLE<N - 1>::cnt = cnt+1u; <--- add this line
RLE<N - 1>::Compress(p + 1);
}
Но, честно говоря, я предпочитаю ваш оригинальный (не метапрограммный) код.
@ ma66, спасибо за просмотр кода. Я хотел знать, как это можно сделать с помощью метапрограммы. Я согласен, что простая рекурсивная версия намного чище и понятнее. С уважением
Этот код создает 6m5a4t1 с использованием gcc. Пожалуйста, убедитесь, что у вас есть точный код, точный вывод, и сообщите нам свой компилятор. Требуется минимальный воспроизводимый пример.