3

除了循环整个数组之外,是否有更快/更有效的方法将 char 数组拆分为块(比如 21 个字符/数组)?

这是我现在的尝试

const char* arr = line.c_str();
char smallArr[(int)ceil((double)strlen(arr)/(double)21)][21];
int arrSisze[(int)ceil((double)strlen(arr)/(double)21)][1];
int m=0;int n=0;
for (int i=0; i<strlen(arr); i++) {
    smallArr[m][i]=arr[i];
    arrSisze[m][0]=(i+1)-n;
    if ((i-n)==19) {
        m++;
        n+=20;
    }
}
4

3 回答 3

3

1) 使用 memcpy

char myname[] = "hello";
char dest[20] = {0};    
/* using memcpy to copy string: */
 memcpy ( dest, myname, 5);

2) 使用 strncpy

char str1[]= "To be or not to be";
char str2[40];

strncpy ( str2, str1, sizeof(str2) );
于 2013-06-16T06:53:54.980 回答
3

是的,指针算术和memcpy. 但是,当您使用 C++ 时,让我们坚持使用std::strings 并假设它们memcpy为我们做了 a。

std::vector<std::string> output;
output.reserve(line.length() / 21 + (line.length() % 21) ? 1 : 0);

auto i = line.begin(), j = i + 21;
for(; line.end() - j > 21; i = j, j+= 21)
{
    output.emplace(i, j)
}

if(j != line.end())
{
    output.emplace(j, line.end());
}

那么,这里发生了什么?std::string出于我们的目的,将 a视为一个char数组和一个length变量就足够了。

首先,我们为输出预留了足够的空间。你也这样做了。

接下来,我们定义 2 个变量ij. i表示当前子字符串的开头和j最后一个迭代器。这里的迭代器可以被认为是指向string'schar数组内部结构的指针——它们甚至可能是char*s!

然后我们一次一行地遍历原始字符串。只是在正确的位置emplace构造 a 的新元素。vector该调用等效于output.push_back(std::string(i, j))并且仅在 C++11 中可用。

line.end() - j > 21最后,我们使用;检查是否还有另一个完整的块。line.end()是数组的最后一个迭代器char- 它指向NUL字符(如果有的话)。如果没有完整的块,我们使用j != line.end().

于 2013-06-16T06:48:45.263 回答
0

不要重新优化标准库。

  • 如果你有一个 std::string,就使用它。
  • 不要使用浮点数进行整数计算:只使用整数算术
  • 问题复杂度为 O(1)。没有其他解决方案可以用更少的一个字符串步行跨度和相关副本来覆盖它
  • 正确使用 C++,忘记 C

=

std::vector<std::string> chunks;
chunks.resize(21);
size_t chunksize = line.size()/21+1;
for(size_t i=0,j=0; i<line.size(); i+=chunksize, ++j)
{  chunks[j] = line.substr(i,chunksize); }

请注意,sting::size需要 N^0,而strlen需要 N^1 复杂度(它内部有一个循环)。

在这段代码中,我的循环在块上是 21^1,substr 是 (N/21)^1 每个块内容,在整个长度上给出 N^1。

无需跟踪字符串长度和 null 终止字符串。一切都由 std::string 类处理。

于 2013-06-16T07:15:38.273 回答