【发布时间】:2021-08-22 01:12:56
【问题描述】:
我编写了两个函数来从字符串中提取“有效”子字符串,这意味着子字符串可能只包含字母和数字。但是,如果要检查的字符串很长,即使性能差距不是太明显,它们也会开始失去性能,这让我不太高兴。有没有更快的方法来“验证”字符串?这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <wchar.h>
wchar_t* validstr(wchar_t* src, wchar_t* cc, unsigned int* index) {
wchar_t* valid = calloc(1, sizeof(wchar_t));
while (isalpha(*cc) || isdigit(*cc)) {
valid = realloc(valid, (wcslen(valid) + 2) * sizeof(wchar_t));
wcscat(valid, (wchar_t[]) { *cc, 0 });
++* index;
*cc = src[*index];
}
return valid;
}
wchar_t* validstr2(wchar_t* src) {
wchar_t* valid = calloc(1, sizeof(wchar_t));
while (isalpha(*src) || isdigit(*src)) {
valid = realloc(valid, (wcslen(valid) + 2) * sizeof(wchar_t));
wcscat(valid, (wchar_t[]) { *src, 0 });
src++;
}
return valid;
}
int main() {
wchar_t* str = L"valid10+(notvalidanymore";
// usage for validstr()
wchar_t current = str[0];
unsigned int index = 0;
printf("%ls\n", validstr(str, ¤t, &index));
// usage for validstr2()
printf("%ls\n", validstr2(str));
}
【问题讨论】:
-
循环内的 realloc 会很慢。为什么不直接通过循环查找有效字符的数量,然后在循环后分配空间并复制数据?是否有理由需要在循环内重新分配?
-
我只需
strdup字符串,然后将所有应保留的字符移到前面,跳过不相关的字符。如果您绝对希望尽量减少分配的内存,请先计算剩余的字符数。 -
@Aconcagua 他的代码不会保留所有有效字符 - 它只是保留初始子字符串,但不包括第一个无效字符。所以他可以对字符串进行strdup,然后用字符串终止符替换第一个无效字符。这似乎是一个很好的方法 - 如果有 strdup 的宽字符版本。
-
这就是我的想法:onlinegdb.com/qg24aTzxo 它仍然需要循环,但它只会在循环内递增,因此性能并不是真正的问题,因为时间完全被 calloc 所掩盖。实际上, calloc 似乎是一种浪费——如果你马上要重写它,你不需要初始化内存。 onlinegdb.com/gCvppGSBO 呢?
-
@JerryJeremiah 我的错,一直疏忽。在 POSIX 上,有
wcsdup并且似乎 windows 也支持它。承认,不能保证一般可移植......
标签: arrays c string memory c-strings