我有两个分别实现编码和解码的功能:
void
delta_encode (char *buffer, const unsigned int length)
{
char delta = 0;
char original;
unsigned int i;
for (i = 0; i < length; ++i)
{
original = buffer[i];
buffer[i] -= delta;
delta = original;
}
}
void
delta_decode (char *buffer, const unsigned int length)
{
char delta = 0;
unsigned int i;
for (i = 0; i < length; ++i)
{
buffer[i] += delta;
delta = buffer[i];
}
}
我不喜欢的是它们非常相似,除了+ =对 - =部分。有没有办法将它们合并为一个函数,它会询问用户是否要编码或解码,并分别选择 - =或+ =版本。如果有的话,它的代码是什么样的?如果有几种方法可以做到这一点,哪个最好?
答案 0 :(得分:2)
如果你有相同的代码但是有一个符号,你可以在你的函数调用中添加一个encode/decode
参数,如果你有编码版本,你可以将你添加的东西乘以-1
。因此:
typedef enum {ENCODE = -1; DECODE = 1;} CODE_TYPE;
void delta_code(char *buffer, const unsigned int length, CODE_TYPE e);
void delta_code(char *buffer, const unsigned int length, CODE_TYPE e)
{
char delta = 0;
char original;
unsigned int i;
for (i = 0; i < length; ++i)
{
original = buffer[i];
buffer[i] += delta*e;
delta = (e<0)?original:buffer[i];
}
}
答案 1 :(得分:2)
只要这是一个“智力练习”,我不妨发布这个,它捕获了编码/解码的对称性:
#include <stdbool.h>
void delta_code(char *buffer, const unsigned int length, bool encode)
{
char delta = 0;
unsigned int i;
for (i = 0; i < length; ++i)
{
char next_delta;
if (encode)
{
next_delta = buffer[i];
buffer[i] -= delta;
}
else
{
buffer[i] += delta;
next_delta = buffer[i];
}
delta = next_delta;
}
}
编辑:OP提到了语言功能。如果C有一个广义的后缀减法,说=-
就像postfix --
一样,它在减法之前返回左侧的值,那么你可以这样做:
for (i = 0; i < length; ++i)
delta = encode? (buffer[i] =- delta) : (buffer[i] += delta);
当然,在真正的C中你可以做到
char temp;
for (i = 0; i < length; ++i)
delta = encode? (temp = buffer[i], buffer[i] -= delta, temp) : (buffer[i] += delta);
答案 2 :(得分:1)
我同意所有人说这样做很糟糕。它使您的程序效率降低,代码变得笨拙(从而降低了可读性)。如果您在实施设计时遇到过这样的障碍,您可能需要重新考虑您的设计以及为什么这样的要求甚至存在。
所有这一切,你可以做这样的事情:
typedef enum
{
ENCODE,
DECODE
} CONTEXT;
void
delta_operation (char *buffer, const unsigned int length, CONTEXT context)
{
if(context == ENCODE)
{
char delta = 0;
char original;
unsigned int i;
for (i = 0; i < length; ++i)
{
original = buffer[i];
buffer[i] -= delta;
delta = original;
}
}
else if(context == DECODE)
{
char delta = 0;
unsigned int i;
for (i = 0; i < length; ++i)
{
buffer[i] += delta;
delta = buffer[i];
}
}
}
并称之为:
char buffer[] = "Whatever your buffer is supposed to be";
delta_operation (buffer, strlen(buffer), ENCODE);
答案 3 :(得分:1)
我个人同意@paddy。您不应该为了获得更少的代码行而使代码不可读。
通常,如果要在+ =和 - =之间切换,可以使用(+/- 1)乘数。对于+ =你应该使用乘数= 1然后你会得到:
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] + delta
对于 - =你可以使用乘数= -1然后你会得到:
buffer[i] = buffer[i] + multiplier * delta ==> buffer[i] = buffer[i] - delta
特别是对于你的代码,它可能看起来像那样(你可以使用boolean而不是int并将函数中的值作为对象):
void
delta_encode_decode (char *buffer, const unsigned int length, int shouldDecode)
{
char delta = 0;
char original;
unsigned int i;
for (i = 0; i < length; ++i)
{
original = buffer[i];
buffer[i] = buffer[i] + shouldDecode * delta;
if (shouldDecode == 1)
delta = buffer[i];
else
delta = original;
}
}
或更“优雅”的解决方案(Anish Ram的贡献):
typedef enum
{
ENCODE = -1,
DECODE = 1
} eOperation;
并使用eOperation代替硬编码值-1 / + 1和int参数
答案 4 :(得分:0)
这是其他人似乎没有提出的建议。您可以创建一个内核函数来对单个字符执行操作并将其传入。
typedef void (*delta_op)( char *value, char *delta );
void encode( char *value, char *delta )
{
char prev = *value;
*value += *delta;
*delta = prev;
}
void decode( char *value, char *delta )
{
*value -= *delta;
*delta = *value;
}
然后你只需将你的内核函数传递给主要部分。
void encode_decode( char *buffer, unsigned int length, encode_op operation )
{
char delta = 0;
unsigned int i;
for (i = 0; i < length; ++i)
{
operation( &buffer[i], &delta );
}
}
所以你这样打电话:
encode_decode( buffer, length, encode );
encode_decode( buffer, length, decode );
尽管如此......它会很笨拙而且很慢......就像qsort
一样。因为所有函数调用。