【问题标题】:A function to append a character in a string efficiently有效地在字符串中追加字符的函数
【发布时间】:2015-10-01 06:00:44
【问题描述】:

我如何在速度方面改进此功能:

void chrapp (char arr[], char chr, int pos)
{
    memmove(arr + pos + 1, arr + pos, strlen(arr + pos));
    *(arr + pos + 1) = chr;
}

此外,不幸的是,它不适用于将字符附加到 数组 的最开头,这也是一种改进。

【问题讨论】:

  • 抛开性能不谈,它不能可靠工作的部分原因是未能同时移动终结器。
  • 试试memmove(arr + pos + 1, arr + pos, strlen(arr + pos) + 1);,这样你也可以复制空值。
  • 还有*(arr + pos) = chr;,而不是*(arr + pos + 1) = chr;——你需要写到你打开的空间,而不是它后面的字符。
  • 啊,是的。数组不保证填充\0s
  • 总是衡量像这样的低级更改/优化的效果;并尝试不同的编译器优化。使用当前的高级编译器很容易做出错误的假设。

标签: c arrays string append


【解决方案1】:

您的原始代码正在遍历字符串两次。一次用于计算字符串的长度,第二次用于移动它。您可以在一个循环中完成它,但是考虑到标准库函数是以高度优化的方式实现的,它不确定它是否真的会加快速度。试试下面的代码:

void chrapp (char arr[], char chr, int pos) {
  char *s;
  char cc;
  for(s=arr+pos; *s; s++) {
     cc = *s; *s = chr; chr = cc;
  }
  *s++ = chr;
  *s = 0;
}

【讨论】:

  • 有趣的方法。在一个循环中执行它对我来说听起来像是一种优化。
【解决方案2】:

使用@Dmitri 注释在移动中包含空终止符'\0'*(arr + pos) 而不是*(arr + pos + 1)

void chrapp(char arr[], char chr, int pos) {
  memmove(arr + pos + 1, arr + pos, strlen(arr + pos) + 1);
  *(arr + pos) = chr;
}

还有其他问题:

  1. 内存管理:现在,假设空间存在。

  2. 检测pos 何时超出字符串末尾。在这种情况下,只需附加。如果没有这个测试,代码结果将是灾难性的。此时很容易将字符串大小添加到函数签名并检查它(未显示)。

  3. 检测pos 何时位于字符串末尾。由于代码知道字符串长度,因此与#2 相同。以一种特殊的方式处理简单的追加情况以加速函数是合理的,因为它确实很常见。

  4. 使用更好的类型。 size_t,而不是intint 而不是 char - 通常一样快或更快,而且肯定更惯用。

  5. 字符串函数通常返回字符串地址。

  6. char == '\0' 应该有特殊处理。现有代码可以工作,但不需要班次。一个移位,写入一个不需要的额外空字符。

...

char *chrapp2(char arr[], int chr, size_t pos) {
  size_t len = strlen(arr);
  if (pos < len) {
    // shift right
    memmove(arr + pos + 1, arr + pos, len - pos + 1);
    *(arr + pos) = chr;
  } else {
    arr[len] = chr;  // Over-write \0
    arr[len+1] = '\0';
  }
  return arr;
}

【讨论】:

  • 有没有更好的方法(尤其是更快)来追加一个字符?这是 能想到的最快的方法,但您似乎对追加非常了解,因此您可能知道更好的解决方案。
  • 如果代码都准备好了 1) 字符串的长度 2) 新索引没有通过结尾 3) 字符不是\0 4) 空间可用,那么最快的是:@ 987654335@.
猜你喜欢
  • 1970-01-01
  • 2013-10-03
  • 2021-03-29
  • 2015-09-15
  • 2014-08-02
  • 1970-01-01
  • 2011-12-24
  • 2011-08-24
相关资源
最近更新 更多