迭代大小为100000的C字符数组需要花费大量时间

仅尝试迭代大小为100000的字符数组,但这需要8-9秒。 但是对于int来说,它需要几毫秒的时间。

    int i;
    char str[100005];
    str[0] = '\0';
    for(i=1;i<10000;i++){
        strcat(str,"HelloWorld");
    }
    for(i=1;i<strlen(str);i++){
        str[i]=str[i-1];
    }
sayalin 回答:迭代大小为100000的C字符数组需要花费大量时间

让我们看一下这段代码:

for(i = 1; i < 10000; i++){
    strcat(str,"HelloWorld");
}

考虑对strcat的调用如何工作。 strcat函数的工作原理是向前扫描字符串,直到找到空终止符,然后在其中写入第二个参数。如果您的字符串很短,那将非常快-例如,它的长度约为10-20个字符-但如果要附加的字符串很长(例如10,000个字符),那么strcat将花费很多时间只需扫描到字符串的末尾即可找到要附加字符串的位置。这意味着此函数中对strcat的每次调用将比上一个调用花费更长的时间,并且最终最后一个调用相当慢。

那么如何加快速度?一种选择是将指向空终止符的指针存储在str数组中,以便您可以告诉strcat从哪里开始寻找。这可能是这样的:

size_t length = strlen("HelloWorld");
char* nextSpot = str;
for(i = 1; i < 10000; i++){
    strcat(nextSpot,"HelloWorld");
    nextSpot += length;
}

这意味着strcat呼叫将始终在最后一个呼叫中断的地方接听,从而加快了速度。

希望这会有所帮助!

,

您的代码存在一些问题。首先是您要在尚未初始化的目标数组上调用onCompleted。您需要先设置strcat

其他问题是算法问题。要知道目标字符串的插入位置,每次调用str[0] = '\0';时都必须执行strcat或等效操作。这意味着它每次都经过strlen个字符。这就是您的算法O(n)。然后,您将对每个字符再次拨打~O(n^2),并收取相同的罚款。并且请记住,第二个循环只是将整个数组设置为strlen

如果您要复制一个字符串'H'次,最好先计算其长度,然后单步执行缓冲区操作:

10000

我在这里使用char str[100005]; const char *template = "HelloWorld"; int n = strlen(template); char *p = str; for(int i = 0; i < 10000; i++) { strncpy(p,template,n); p += n; } *p = '\0'; 是因为它避免了为您制作的每个副本都复制strncpy的终止'\0'

另一种方法是使用模除(可能会更慢)来放置字符:

template

这两种方法在我的机器上所花的时间都比原始循环少几个数量级,因为它们只对数组执行一次。

最终循环将先前的字符一遍又一遍地复制到缓冲区的其余部分。由于您的缓冲区充满了char str[100005]; const char *template = "HelloWorld"; int n = strlen(template); int end = n * 10000; for(int i = i; i < end; i++) { str[i] = template[i % n]; } ,因此循环将HelloWorld复制到每个位置。您可以使用'H'为您做同样的事情:

memset

故事的寓意是避免重新计算您可以使用简单的计数器或指针跟踪的内容。如果您希望一切进展顺利,请尽量减少工作量。

本文链接:https://www.f2er.com/2467562.html

大家都在问