[英]Right shift a binary string efficiently in C++
If I have a string that represents an integer in binary form such as 如果我有一个以二进制形式表示整数的字符串,例如
1101101
and I want to circularly right shift it to obtain 我想循环右移以获得
1110110
One way I could think of would be converting the string into an int
and use (taken from wikipedia ) 我想到的一种方法是将字符串转换为
int
并使用(摘自Wikipedia )
// https://stackoverflow.com/a/776550/3770260
template <typename INT>
#if __cplusplus > 201100L // Apply constexpr to C++ 11 to ease optimization
constexpr
#endif // See also https://stackoverflow.com/a/7269693/3770260
INT rol(INT val, size_t len) {
#if __cplusplus > 201100L && _wp_force_unsigned_rotate // Apply unsigned check C++ 11 to make sense
static_assert(std::is_unsigned<INT>::value,
"Rotate Left only makes sense for unsigned types");
#endif
return (val << len) | ((unsigned) val >> (-len & (sizeof(INT) * CHAR_BIT - 1)));
}
However, if the string consists of, say, 10^6 char
then this does not work as the integer representation exceeds even the range of __int64
. 但是,如果字符串由10 ^ 6
char
组成,则此操作不起作用,因为整数表示甚至超过了__int64
的范围。
In that case I could think of a solution by looping over the string 在那种情况下,我可以通过遍历字符串来考虑解决方案
//let str be a char string of length n
char temp = str[n - 1];
for(int i = n - 1; i > 0; i--)
{
str[i] = str[i - 1];
}
str[0] = temp;
This solution runs in O(n)
due the loop over the length of the string, n. 由于在字符串n的长度上存在循环,因此该解决方案在
O(n)
运行。 My question is, is there much more efficient way to implement circular shifting for large binary strings? 我的问题是,对于大型二进制字符串,有没有更有效的方法来实现循环移位?
Both input and output are std::string
s 输入和输出都是
std::string
s
You have to move memory one way or another, so your proposed solution is as fast as it gets. 您必须以一种或另一种方式移动内存,因此您提出的解决方案要尽可能快。
You might also use standard std::string
functions: 您可能还使用标准的
std::string
函数:
str.insert(str.begin(), str[n - 1]);
str.erase(str.end() - 1);
or memmove
, or memcpy
(I don't actually recommend this, it's for an argument) 或
memmove
或memcpy
(我实际上不建议这样做,这是为了争论)
char temp = str[n - 1];
memmove(str.data() + 1, str.data(), n - 1);
str[0] = temp;
Note that memmove
may look faster, but it's essentially the same thing as your loop. 请注意,
memmove
外观可能更快,但这与循环本质上是一样的。 It is moving bytes one by one, it's just encapsulated in a different function. 它正在逐字节移动字节,只是封装在其他函数中。 This method might be faster for much larger data blocks, of size 1000 bytes or more, since the CPU is optimized to move large chunks of memory.
这种方法对于更大的数据块(大小为1000字节或更大)可能更快,因为CPU已优化为移动大块内存。 But you won't be able to measure any difference for 10 or 20 bytes.
但是您将无法测量10或20个字节的差异。
Moreover, the compiler will most likely run additional optimizations when it sees your for
loop, it realizes that you are moving memory and chooses the best option. 此外,当编译器看到您的
for
循环时,很可能会运行其他优化,它意识到您正在移动内存并选择最佳选项。
The compiler is also good at dealing with std::string
methods. 编译器还擅长处理
std::string
方法。 These are common operations and the compiler knows the best way to handle it. 这些是常见的操作,编译器知道处理它的最佳方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.