[英]Flaws in algorithm and algorithm performance
char *stringmult(int n)
{
char *x = "hello ";
for (int i=0; i<n; ++i)
{
char *y = new char[strlen(x) * 2];
strcpy(y,x);
strcat(y,x);
delete[] x;
x=y;
}
return x;
}
I'm trying to figure out what the flaws of this segment is. 我试图弄清楚此细分市场的缺陷。 For one, it deletes x and then tries to copy it's values over to y.
例如,它删除x,然后尝试将其值复制到y。 Another is that y is twice the size of x and that y never gets deleted.
另一个是y的大小是x的两倍,并且y永远不会被删除。 Is there anything that I'm missing?
有什么我想念的吗? And also, I need to figure out how to get algorithm performance.
而且,我需要弄清楚如何获得算法性能。 If you've got a quick link where you learned how, I'd appreciate it.
如果您有一个快速的链接来学习如何做,我将不胜感激。
y
needs one more byte than strlen(x) * 2
to make space for the terminating nul character -- just for starters. y
需要比strlen(x) * 2
多一个字节来为终止的nul字符留出空间-仅适用于初学者。
Anyway, as you're returning a new
ed memory area, it's up to the caller to delete it (eek). 无论如何,当您返回一个
new
ed内存区域时,由调用方删除它(eek)。
What you're missing, it seems to me, is std::string
...!-) 在我看来,您缺少的是
std::string
...!-)
As for performance, copying N characters with strcpy is O(N); 至于性能,用strcpy复制N个字符是O(N); concatenating N1 characters to a char array with a previous strlen of N2 is O(N1+N2) (std::string is faster as it keeps the length of the string in an O(1)-accessible attribute!-).
将N1个字符连接到前一个字符为N2的char数组是O(N1 + N2)(std :: string更快,因为它将字符串的长度保留在O(1)可访问的属性中!-)。 So just sum N+N**2 for N up to whatever your limit of interest is (you can ignore the
N+
part if all you want is a big-O estimate since it's clearly going to drop away for larger and larger values of N!-). 因此,只要将N的N + N ** 2加到您感兴趣的极限范围内即可(如果您想要的只是大O估计,则可以忽略
N+
部分,因为随着N的值越来越大,它显然会消失!-)。
For starters delete[] x; 对于初学者,delete [] x; operates for the first time round the loop on some static memory.
第一次在某些静态存储器上循环运行。 Not good.
不好。
It looks like an attempt to return a buffer containing 2^n copies of the string "hello ". 看起来像是尝试返回一个缓冲区,该缓冲区包含字符串“ hello”的2 ^ n个副本。 So the fastest way to do that would be to figure out the number of copies, then allocate a big enough buffer for the whole result, then fill it with the content and return it.
因此,最快的方法是找出份数,然后为整个结果分配足够大的缓冲区,然后用内容填充并返回。
void repeat_string(const std::string &str, int count, std::vector<char> &result)
{
result.resize(str.size() * count);
for (int n = 0; n < count; n++)
str.copy(&result[n * s.size()], s.size());
}
void foo(int power, std::vector<char> &result)
{
repeat_string("hello ", 1 << (power + 1), result);
}
You should instead compute the result length at once and allocate memory at once and pass the char* as an in-parameter: 相反,您应该立即计算结果长度并立即分配内存,然后将char *作为参数传入:
char* stringMult(const char* what, int n)
{
const size_t sourceLen = strlen( what );
int i;
size_t resultLen = sourceLen;
// this computation can be done more cleverly and faster
for( i = 0; i < n; i++ ) {
resultLen *= 2;
}
const int numberOfCopies = resultLen / sourceLen;
char* result = new char[resultLen + 1];
char* whereToWrite = result;
for( i = 0; i < numberOfCopies; i++ ) {
strcpy( whereToWrite, what );
whereToWrite += sourceLen;
}
return result;
}
Certain parts of my implementation can be optimized but still it is much better and (I hope) contains no undefined-behaviour class errors. 我的实现的某些部分可以优化,但仍然会更好,并且(希望)不包含未定义行为的类错误。
您必须为NULL终止字符串的Y分配空间时添加一个。请检查以下位置的代码http://codepad.org/tkGhuUDn
char * stringmult (int n)
{
int i;
size_t m;
for (i = 0, m = 1; i < n; ++i; m *= 2);
char * source = "hello ";
int source_len = strlen(source);
char * target = malloc(source_len*m+1) * sizeof(char));
char * tmp = target;
for (i = 0; i < m; ++i) {
strcpy(tmp, source);
tmp += source_len;
}
*tmp = '\0';
return target;
}
Here a better version in plain C. Most of the drawbacks of your code have been eliminated, ie deleting a non-allocated pointer, too many uses of strlen and new . 这是普通C语言中的一个更好的版本。已消除了代码的大多数缺点,即删除了未分配的指针,过多使用strlen和new 。 Nonetheless, my version may imply the same memory leak as your version, as the caller is responsible to free the string afterwards.
但是,我的版本可能暗含与您的版本相同的内存泄漏,因为调用者负责随后释放字符串。
Edit: corrected my code, thanks to sharptooth. 编辑:更正了我的代码,这归功于Sharpothoth。
char* string_mult(int n) 字符* string_mult(int n)
{ {
const char* x = "hello ";
char* y;
int i;
for (i = 0; i < n; i++)
{
if ( i == 0)
{
y = (char*) malloc(strlen(x)*sizeof(char));
strcpy(y, x);
}
else
{
y = (char*)realloc(y, strlen(x)*(i+1));
strcat(y, x);
}
}
return y;
} }
Nobody is going to point out that " y
" is in fact being deleted? 没有人会指出“
y
”实际上被删除了吗?
Not even one reference to Schlmeiel the Painter ? 甚至没有提到画家Schlmeiel吗?
But the first thing I'd do with this algorithm is: 但是我要用此算法做的第一件事是:
int l = strlen(x);
int log2l = 0;
int log2n = 0;
int ncopy = n;
while (log2l++, l >>= 1);
while (log2n++, n >>= 1);
if (log2l+log2n >= 8*(sizeof(void*)-1)) {
cout << "don't even bother trying, you'll run out of virtual memory first";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.