【发布时间】:2021-03-13 18:53:27
【问题描述】:
请看下面的代码,它通过循环遍历所有要替换的utf8字符来执行连续的字符/字符串替换;你会提出另一个更高效的构造吗?
static char *utf8[66] = { "◊", "⎕", "⍞", "⌹", "⊤", "⊥",
"⌶", "⌈", "∪", "⍕", "⍎", "│",
"⍟", "∆", "∇", "→", "←", "⌊",
"┐", "└", "─", "↑", "↓", "≡",
"⍸", "⋸", "∵", "⌷", "⍂", "⌻",
"⊣", "⊢", "⋄", "┘", "┌", "⍺",
"⊂", "⊃", "⍝", "⍲", "⍴", "⍱",
"⌽", "⊖", "○", "∨", "⍳", "⍬",
"∈", "∩", "⌿", "⍀", "≥", "≤",
"≠", "×", "÷", "⍙", "∘", "⍵",
"⍫", "⍋", "⍒", "¯", "¨", NULL };
static char *ebcdic[66] = { "\x8d", "\x90", "\x91", "\x92", "\x98", "\x9d",
"\x9f", "\xa9", "\xac", "\xae", "\xaf", "\xb3",
"\xb5", "\xb6", "\xb7", "\xb8", "\xbd", "\xbe",
"\xbf", "\xc0", "\xc4", "\xc6", "\xc7", "\xcf",
"\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5",
"\xd6", "\xd7", "\xd8", "\xd9", "\xda", "\xe0",
"\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7",
"\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed",
"\xee", "\xef", "\xf0", "\xf1", "\xf2", "\xf3",
"\xf4", "\xf5", "\xf6", "\xf7", "\xf8", "\xf9",
"\xfa", "\xfb", "\xfc", "\xfd", "\xfe", NULL };
char* convert(char *line) {
char *buffer1;
char *buffer2;
char *tmp;
int i=0;
buffer1 = malloc(strlen(line));
strcpy(buffer1, line);
while(ebcdic[i]) {
buffer2 = replace(buffer1, utf8[i], ebcdic[i]);
free(buffer1);
buffer1 = malloc(strlen(buffer2));
strcpy(buffer1, buffer2);
}
tmp = malloc(strlen(buffer1 + 1));
sprintf(tmp, "%s\n", buffer1);
free(buffer1);
free(buffer2);
return tmp;
}
char* replace(const char* s, const char* oldW, const char* newW) {
char* result;
int i, cnt = 0;
int newWlen = strlen(newW);
int oldWlen = strlen(oldW);
for (i = 0; s[i] != '\0'; i++) {
if (strstr(&s[i], oldW) == &s[i]) {
cnt++;
i += oldWlen - 1;
}
}
result = (char*)malloc(i + cnt * (newWlen - oldWlen) + 1);
i = 0;
while (*s) {
if (strstr(s, oldW) == s) {
strcpy(&result[i], newW);
i += newWlen;
s += oldWlen;
} else {
result[i++] = *s++;
}
}
result[i] = '\0';
return result;
}
- update-001:为 replace() 添加了代码。
- update-002:将 for/loop 更改为 while。
感谢您的关注,在这种特殊情况下,我更关心可读性和内存使用情况而不是性能。
【问题讨论】:
-
(a) 将分配空间的长度增加一以允许空终止符。 (b) 显示
replace的定义。 (c) 不要释放缓冲区并分配新空间,只需重用同一个缓冲区。 (d) 根本不分配缓冲区来复制line;只为新行分配空间。输入可以直接从用户传递的缓冲区中读取,而无需复制。 (e)sprintf(tmp, "%s\n", buffer1);是荒谬的。只需将所需的数据放入buffer1(如果需要,为换行符分配更多空间)并返回。 (f) 缓冲区未被释放并被回收。 -
添加了 replace() 的代码
-
我建议先写正确的代码,然后再担心效率。
while(ebcdic[i])显然是不正确的,它永远不会终止。malloc(strlen(line))显然是不正确的。每次迭代的mallocs 多于frees 显然是不正确的。
标签: c loops optimization