【发布时间】:2017-02-22 20:19:15
【问题描述】:
我正在编写一个 CLI 输入解析器,我想知道将字符串拆分为标记的最快算法是什么。
规则:
- 空格表示令牌的结尾。
- 任何字符都可以用反斜杠转义,这意味着我按原样接受它,没有任何特殊含义。 (目前只用于转义空格)
这是我目前使用的代码:
#define POINTER_ARRAY_STEP 10
#define STRING_STEP 255
char **parse_line(char *line)
{
char **array;
size_t array_len;
size_t array_index;
size_t token_len;
size_t token_index;
array_len = POINTER_ARRAY_STEP;
array = malloc((array_len + 1) * sizeof(char*)); /* +1 to leave space for NULL */
array_index = 0;
token_len = STRING_STEP;
array[array_index] = malloc(token_len + 1);
token_index = 0;
for (; *line; ++line) {
if (array_index == array_len) {
array_len += POINTER_ARRAY_STEP;
array = realloc(array, (array_len + 1) * sizeof(char*));
}
if (token_index == token_len) {
token_len += STRING_STEP;
array[array_index] = realloc(array[array_index], token_len + 1);
}
if (*line == '\\') {
array[array_index][token_index++] = *++line;
continue;
}
if (*line == ' ') {
array[array_index][token_index] = 0;
array[++array_index] = malloc(token_len + 1);
token_index = 0;
continue;
}
array[array_index][token_index++] = *line;
}
/* Null terminate the last array element */
array[array_index][token_index] = 0;
/* Null terminate the array */
array[array_index + 1] = NULL;
return array;
}
【问题讨论】:
-
foo = realloc(foo, some_size)总是一个坏主意:如果调用失败,您必须释放您刚刚覆盖的原始指针foo。 -
@DanielJour 是的,为了性能,一个一个地重新分配也不是最优的。这就是大小和容量的区别。
-
哪些算法中最快的?这取决于您是否准备像
strtok那样牺牲输入字符串。我的选择是使用strchr遍历字符串,并将 nul 终止符写入(副本)字符串的空格中。 -
您不需要重新分配。你可以只记住单词的开头,找到结尾,然后分配你需要的内存。
-
最后:当询问“最快的算法”时,总是有一个问题:您是否分析了您的(工作?)实现?真的是瓶颈吗?
标签: c string algorithm command-line-interface tokenize