我已经为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",即代码只打印组的第一个字符。我无法找出代码中的错误。有人可以看看它,并帮助我了解我在这里做错了什么。
我无法找出代码中的错误,有人可以看看它,并帮助我了解我在这里做错了什么。
问题是您初始化静态成员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
(CLak++大小写)。
我不知道谁是对的,但关键是当你写的时候
cout << cnt << *p;
cnt = 0;
你用RLE<N>
打印cnt
- 所以N
或1
,根据情况 - 你RLE<N>
cnt
设置为零。
但是当你在RLE<N>
中将cnt
设置为零时,RLE<N-1>
中的cnt
保持不变(所以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
设置为Compress()
中的cnt + 1
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);
}
但是,坦率地说,我更喜欢您的原始(不是元编程)代码。