字符串相乘的有效方法
Efficient way to multiply string
http://ideone.com/g7rGS7
正如你所看到的,它超过了时间限制。
有人给了我一个想法,让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;
}
如本评论中所述,您可以执行以下操作:
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;
}
您的运算符^执行大量字符串分配。运算符*预先分配字符串,这很好,但您的运算符^每次调用运算符*时都会创建一个中间字符串。相反,预先计算r的长度和所需的副本数。然后,您可以预分配r并执行连接,而无需创建一堆不需要的字符串。
如果您想用1个字符(示例中的空格)填充它,那么让它们更快的方法是完全消除for循环:
int main()
{
string blank2(2, ' ');
string blank4(4, ' ');
string blank8(8, ' ');
string blank16(16, ' ');
// etc
return 0;
}
为了使它通用(这样你就可以用不止一个字符来完成),你仍然需要限制你的循环:
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;
}
相关文章:
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法