您可以看到它超出了时间限制。
有人给我的想法是拥有10个左右空格的静态变量并将它们连接起来形成更大的空间,所以我想尝试通过2的幂来做到这一点。代码有效,但它显然很慢。有什么更快的方法呢?
std::string operator*(std::string const &s, size_t n)
{
std::string r;
r.reserve(n * s.size());
for (size_t i=0; i<n; i++)
r += s;
return r;
}
std::string operator^(std::string const &s, size_t n)
{
std::string r = s;
for (size_t i = 1; i < n; i++)
{
r = s * r.size();
}
if (n == 0) return std::string(" ");
return r;
}
int main()
{
string blank = " ";
string blank2 = blank * 2;
string blank4 = blank2 ^ 2;
string blank8 = blank2 ^ 3;
string blank16 = blank2 ^ 4;
for (int i = 0; i < 100; i++)
assert((blank2 ^ i).size() == pow(2, i));
return 0;
}
答案 0 :(得分:1)
您的运营商^进行了大量的字符串分配。运算符*预先分配字符串,这是好的,但是每次调用operator *时,运算符^都会创建一个中间字符串。而是预先计算r的长度和所需的副本数。然后你可以预先分配r并执行连接,而不会创建一堆不需要的字符串。
答案 1 :(得分:1)
正如本comment所述,您可以这样做:
std::string str_double (std::string const & s)
{
return s + s;
}
std::string operator*(std::string const &s, size_t n)
{
return str_double(s * (n / 2)) + ((n % 2) ? s : std::string());
}
如果您的编译器和标准库支持右值引用和移动,我相信它非常有效。
但是,我认为任何事情都不会比直截了当的版本快得多,如下:
std::string operator*(std::string const &s, size_t n)
{
std::string r;
r.resize (n * s.size()); // note resizing, not reserving
for (size_t i = 0, j = 0; i < n; ++i, j += s.size())
memcpy (&(r[j]), &(s[0]), s.size());
return r;
}
答案 2 :(得分:0)
如果您希望用1个字符(示例中的空格)填充它,那么使它们更快的方法就是完全消除for循环:
int main()
{
string blank2(2, ' ');
string blank4(4, ' ');
string blank8(8, ' ');
string blank16(16, ' ');
// etc
return 0;
}
为了使它成为通用的(所以你可以用超过1个字符来做到这一点),你仍然想要限制你的循环:
std::string operator*(std::string const &s, size_t n)
{
std::string r(n * s.size(), ' '); // initialize the string with the needed size
for (size_t i=0; i<n; i++) // O(n)
r += s;
return r;
}
std::string operator^(std::string const &s, size_t n)
{
size_t sn = std::pow(s.size(), n);
std::string r(sn, ' ');
for (size_t i = 1; i < sn; i++) // since this doesn't have an inner loop in the * operator, it is O(n) instead of O(n^2)
{
r += s;
}
return r;
}
int main()
{
string blank = " ";
string blank2 = blank * 2;
string blank4 = blank2 ^ 2;
string blank8 = blank2 ^ 3;
string blank16 = blank2 ^ 4;
for (int i = 0; i < 100; i++)
assert((blank2 ^ i).size() == pow(2, i));
return 0;
}