我需要编写一个函数,它是系统的一部分,用于对字符串使用huffman编码。此特定函数扫描字符串,然后根据字符串中的字符生成单个霍夫曼树的列表。但是,当我运行它时,此功能不起作用。任何人都可以帮我弄清楚这个功能有什么问题吗?
hufflist* build_hufflist(char* s)
{
char* letters = malloc(strlen(s));
int x;
int letterspos = 0;
hufflist* output = malloc(sizeof(hufflist));
output = NULL;
char* scopy = strdup(s);
make_capital(scopy);
for(x = 0 ; x < strlen(s) ; x++) {
if(('a' <= scopy[x]) && (scopy[x] <= 'z')) {
scopy[x] -= 32;
}
if(char_in_array(letters, s[x] == 0)) {
letters[letterspos] = scopy[x];
letterspos++;
hl_insert(output, huff_singleton(scopy[x], char_count(scopy, scopy[x])));
}
}
return output;
}
char_in_array是一个函数,它返回一个字符是否在数组中,而char_count返回一个字符在数组中的次数。我已经对它们进行了测试,但它们都有效。
此外,这里还有相关的数据定义
typedef struct leaf leaf;
typedef struct node node;
typedef struct huff huff;
typedef struct hufflist hufflist;
enum huff_tag { LEAF, NODE };
struct leaf {
char c;
int n;
};
struct node {
int n;
huff *lsub;
huff *rsub;
};
union huff_union {
leaf leaf;
node node;
};
struct huff {
enum huff_tag tag;
union huff_union h;
};
struct hufflist {
huff* val;
hufflist* next;
};
答案 0 :(得分:2)
以下是我发现的一些问题。
1)你malloc letters
,然后开始使用它而不初始化它指向任何基本情况的数据(例如 - 所有0,或s
的副本,等等。)。相反,如果letterspos = 0
表示letters
为空,那么char_in_array()
也可能需要该信息。
2)你是malloc output
,但是立即将它设置为NULL并最终返回。
3)您在make_capital()
上调用scopy
,然后在循环中执行类似的逻辑。
4)为第二个参数传递一个布尔值(0或1)到char_in_array()
。您可能打算在== 0
之外拨打char_in_array()
。
4a)函数char_in_array()
只接受指向letters
的指针和要检查的字符。例如,它不会以letterspos
为例。所以,&#34;结束&#34; letters
必须嵌入数组本身(例如,使用nul-terminator参见1))或者你也需要传递letterspos
。
hufflist* build_hufflist(char* s)
{
char* letters = malloc(strlen(s)); // 1) maybe calloc(strlen(s), 1) or calloc(256, 1) instead?
int x;
int letterspos = 0;
hufflist* output = malloc(sizeof(hufflist));
output = NULL; // 2) probably not what you intended
char* scopy = strdup(s);
make_capital(scopy);
for(x = 0 ; x < strlen(s) ; x++) {
if(('a' <= scopy[x]) && (scopy[x] <= 'z')) { // 3) didn't make_capital() already do this?
scopy[x] -= 32;
}
if(char_in_array(letters, s[x] == 0)) { // 4) should the == 0 be outside the call to char_in_arrays? 4a) doesn't char_in_array need letterspos too?
letters[letterspos] = scopy[x];
letterspos++;
hl_insert(output, huff_singleton(scopy[x], char_count(scopy, scopy[x])));
}
}
return output;
}
编辑看起来您的代码会重复扫描整个字符串(即 - 您为找到的每个新字符调用char_count()
),这不是最佳选择。您可以在一次传递中获得字符串中所有字符的计数,如下所示:
unsigned int char_counts[256] = { 0 };
unsigned char *ptr = (unsigned char*) scopy;
for (; *ptr; ++ptr)
++char_counts[*ptr];
char_counts
现在包含copy
中包含的每个字符的计数,由(无符号)字符值本身索引。字符串中未包含的字符的计数为零。那么你可以这样做:
for (x = 0; x < 256; ++x)
if (char_counts[x])
hl_insert(output, huff_singleton(x, char_counts[x]));
我假设插入的顺序并不重要,这可能是也可能不是。