字符串循环移位
来源:互联网 发布:2015最新网络神曲 编辑:程序博客网 时间:2024/04/29 23:20
把字符串移动n位。可以一个一个移动,这样的话,要移动n次,每次移动len个。算法时间复杂度为O(n*len)。
也可以开辟一个新的内存,把移动的最终位置计算出来,直接放到那里即可,这样时间负责度为O(1),空间复杂度为O(len)。
除此之外,还有时间负责度为O(1),空间负责度也为O(1)的算法。
第二种方法是,先把前n个字符串反转,再把后面的反转。最后再把整个字符串反转
上面的移位都需要多次移位,有没有一种方法,一次性让移动的字符串到位。
看一下abcdefgh,左移3。我们可以一次计算出所有字符串最终的位置,移位即可。
把a保存起来,d移到a,g移到d,b移到g,e移到b,h移到e,c移到h,f移到c,a移到f,结束。
如果左移4呢,会出现死循环。这个与字符串长度和移位位数有关,要移动两者的最大公约数次数。
测试:
也可以开辟一个新的内存,把移动的最终位置计算出来,直接放到那里即可,这样时间负责度为O(1),空间复杂度为O(len)。
除此之外,还有时间负责度为O(1),空间负责度也为O(1)的算法。
第一种方法为把右边的向左移,每次移动n位。一直到末尾,再把末尾的反转好
//字符串左移n位void shift(std::string &str, int n){int len = str.length();if (len <= 0) return;n = n%len;int start = 0;//交换起始位置int end = n;//后面交换的起始位置int mark = end;//记录这个位置while (true){while (start != mark&&end < len){char temp = str[start];str[start] = str[end];str[end] = temp;++start;++end;//std::cout << str << std::endl;}if (start == mark){if (end >= len)return;elsemark = end;//更新mark}else if (end >= len)end = mark;}}
第二种方法是,先把前n个字符串反转,再把后面的反转。最后再把整个字符串反转
//反转[start end]之间字符串void inversion(std::string& str, int start, int end){char temp;while (start<end){temp = str[start];str[start] = str[end];str[end] = temp;++start;--end;}}void shift1(std::string& str, int n){int len = str.length();if (len <= 0) return;n = n%len;inversion(str, 0, n - 1);//反转前n半部分inversion(str, n, len - 1);//反转后半部分inversion(str, 0, len - 1);//整体反转}
上面的移位都需要多次移位,有没有一种方法,一次性让移动的字符串到位。
看一下abcdefgh,左移3。我们可以一次计算出所有字符串最终的位置,移位即可。
把a保存起来,d移到a,g移到d,b移到g,e移到b,h移到e,c移到h,f移到c,a移到f,结束。
如果左移4呢,会出现死循环。这个与字符串长度和移位位数有关,要移动两者的最大公约数次数。
//计算公约数int gcd(int max, int min){if (min == 0)return max;return gcd(min, max%min);}void shift2(std::string& str, int n){int len = str.length();if (len <= 0) return;n = n%len;int GCD = gcd(len, n);int loop = len / GCD;for (int i = 0; i < GCD; ++i)//循环最大公约数次{char temp = str[i];int j;for (j = 0; j < loop - 1; ++j)//每次循环换loop个。{str[(i + j*n) % len] = str[(i + j*n + n) %len ];}str[(i + j*n) % len] = temp;}}
测试:
int main(){std::string str = "abcde";shift(str, 3);std::cout << str << std::endl;shift1(str, 3);std::cout << str << std::endl;shift2(str, 3);std::cout << str << std::endl;return 0;}
0 0
- 字符串循环移位包含
- 读书笔记--字符串循环移位
- 字符串循环移位
- 字符串循环移位
- 字符串循环移位
- 字符串循环移位算法
- 字符串循环移位
- 字符串循环移位
- 字符串 --- 循环移位问题
- 字符串循环移位
- 字符串循环移位
- 字符串循环移位
- 字符串循环移位
- 字符串右循环移位
- 字符串右循环移位
- 字符串循环移位
- 字符串循环移位
- 字符串循环移位
- 2014-10-25Android学习--------Android应用工程文件组成
- Linux 增加sys节点技巧
- PAT (Advanced Level) Practise 1020. Tree Traversals (25)
- 判断数字是多少位数,正向反向输出
- 浅谈CSRF攻击方式
- 字符串循环移位
- 吴桐的新博客
- 这Hadoop分布式文件系统
- GET vs. POST
- libzplay简单的播放音频例子
- 2014——我的求职之路(四)
- C# 发送消息SendKeys、SendMessage、keybd_event的用法
- 工厂模式浅谈
- Openstack中RabbitMQ RPC代码分析