说起字符串的左旋和右旋问题,想必大家都不陌生,这是一个在初学C语言过程中经常遇到的一个问题,解题的思路可以说很多,每一个人的看待问题的角度都不同,所以就可以得到不同的解题思路。下面我就列举几种方法:

先从最容易想到的说起:

以字符串abcdef为例,若是左旋问题,首先我们可以拿出首个字符a,将其与后面的每一个字符交换一次,得到新的字符串bcdefa,然后进行交换得到cdefab,循环执行,一直到次数等于你给定的次数。(右旋与此类似)

代码如下所示:

void LRevolve_Words(char *Pword, int  k, int len)            //左旋,k为指定的左旋字符的个数
{int i = len;                                         char temp;while (k--){for ( i = 0; i < len - 1 ; i++)              //依次交换{temp = *(Pword + i);*(Pword + i) = *(Pword + i + 1);*(Pword + i + 1) = temp;}}
}
void RRevolve_Words(char *Pword, int  k, int len)               //右旋
{int i = len;char temp;while (k--){for ( i = len ; i > 1 ; i--){temp = *(Pword + i - 1);*(Pword + i - 1) = *(Pword +  i - 2);*(Pword + i - 2) = temp;}}
}

上面的方法是最简单的,也容易想到,实现起来简单,代码容易理解,但是最主要的缺点就是效率不高,如果不考虑时间和空间的限制,假设移动的位为k,则要循环k次,每次循环移动1位,这样的空间复杂度是0(1),时间复杂度是0(n*k),如果k大于n,则0(n^2)。因此,如果K>N,右移K - N之后的数组序列跟右移K位的结果是一样的。

下面介绍一种比较巧妙地方法:(个人认为也是最好的方法)

采用先部分再整体的方法(或者先整体再部分,效果差不多):具体实现是先反转前k个字符,然后再反转后n - k个字符,最后再反转整个字符串。这种方法比上面一种方法高效。时间复杂度是0(n),空间复杂度为0(1)。

这种方法也叫三步反转法。(以左旋为例,右旋与之类似)

#include<stdio.h>
#include <string.h>
#include<assert.h>
#define Max_Words 20
void Reverse_String(char * Pword, char * qword)
{char *pa = Pword;char *pb = qword;char temp;assert(Pword);assert(qword);while (pa<pb){temp = *pa;*pa = *pb;*pb = temp;pa++;pb--;}
}
int main()
{char arr[Max_Words];int len = 0;int k = 0;char *pStart = NULL;char *pEnd = NULL;printf("请输入您要旋转的字符串内容\n");scanf("%s", arr);len = strlen(arr) - 1;printf("请输入您要旋转的字符个数\n");scanf("%d", &k);pStart = &arr[0];pEnd = arr + len;Reverse_String(pStart, pStart + k - 1);             //把要左旋的k个字符先逆序翻转Reverse_String(pStart + k, pEnd);                    //把k+1后的字符逆序翻转Reverse_String(pStart, pEnd);                          //整个字符串逆序翻转        printf("旋转之后的字符串为:%s\n", arr);return 0;
}

接着再介绍一种不是一下子可以想到的方法。就是用递归,当然不是说这方法很难,只是我们不经常用这方法,或者说如果不提醒你,你是无法一下子想到的。(一般会提示你请用递归方法解决)

当然递归也有不同的递归方式:

方式一:

每次向右移动K位,最后递归,把一个规模为N的问题化解为规模为M(M<N)的问题。

举例来说,设字符串总长度为L,左侧要旋转的部分长度为s1,那么当从左向右循环交换长度为s1的小段,直到最后,由于剩余的部分长度为s2(s2==L%s1)而不能直接交换。

该问题可以递归转化成规模为s1+s2的,方向相反(从右向左)的同一个问题。随着递归的进行,左右反复回荡,直到某一次满足条件L%s1==0而交换结束。可以说是第一种方法更好地展示。

方式二:

先说左旋,每次都把一个元素拿出来,然后将把一个元素先拿出来,放在一个临时变量temp之中,并把这个元素改成‘\0’,然后进行递归,直到达到指定的次数,递归结束,之后进行递归的返回,返回后依次拿出之前保存的temp赋值给最后面元素之后的一个空间,(当然这里需要额外的空间,定义的数组要比字符串内容大)。

void LRevolve_Words(char *Pword , int  k , int len)             //len为数组内容的大小
{char temp;assert(Pword);if (k){temp = *Pword;*Pword = '\0';                                 //将首字符改成‘\0’LRevolve_Words(Pword + 1, k - 1 , len);*(Pword + len  ) = temp;}*(Pword + len + k) = '\0';
}

再说右旋,与左旋稍有不同,在递归的过程中首先要将每一个字符向后面移动一位,然后取出最后面的一个元素,并放入temp之中,然后再改成'\0',然后进行递归,递归返回的时候,将前面元素赋值成后面要旋转的元素。

void RRevolve_Words(char *Pword , int  k , int len)
{char temp;int i;assert(Pword);if (k){temp = Pword[len - 1];for ( i = 0; i < len ; i++){Pword[len - i  ] = Pword[len - i - 1];}Pword[len] = '\0';RRevolve_Words(Pword + 1, k - 1 , len - 1);*Pword  = temp;                                          }
}

其实还有许多其他的方法,总之没有最好只有更好,大家也可以多多去探索!

实现字符串左旋和右旋的常见方法相关推荐

  1. 字符串左旋和右旋的常见方法

    1.问题 比如数组,假设以数组的某个索引,或者索引之间,作为旋转中心,对数组进行逆时针(左旋)或顺时针(右旋)的旋转. 类似这样: int[] a={1,2,3,4,5} 左旋3个之后 {4,5,1, ...

  2. matlab视频旋转振动,基于MATLAB的振动合成及左旋与右旋的动态模拟演示

    振动和波动是横跨物理学不同领域的一种非常普遍而重要的运动形式.振动的合成是研究实际问题常见的方法.其中同频率同方向简谐振动合成原理,是讨论光波.声波以及电磁辐射的干涉和衍射的理论基础;同方向,频率之和 ...

  3. 右手螺旋判断磁感应强度方向_弹簧左旋or右旋在功能和应用上有什么区别,如何判断左旋还是右旋...

    点击上方"机械设计一点通"关注我们,每天学习一个机械设计相关知识点 弹簧左旋/右旋在功能上有什么区别 弹簧左旋.右旋就和左左旋.右旋螺纹一样,如果是压缩或拉伸弹簧,左旋.右旋都一样 ...

  4. Java 平衡二叉树之单旋(左旋,右旋)与双旋

    1.平衡二叉树 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高. 具有以下特点:它是一 棵空树或它的左右两个 ...

  5. 通过左旋和右旋来实现搜索二叉树的自平衡

    首先左旋和右旋的概念都是在平衡二叉树的基础上提出的.并对AVL树 SB树 红黑树在原理层面进行了简单的介绍,无coding. 什么是左旋? 假设存在下述平衡二叉树(某个结点的左子节点都小于该结点,右子 ...

  6. AVL树添加节点后的平衡操作(一)逻辑分析:左旋、右旋、双旋(超详细图解)

    AVL树 AVL树是最早发明的自平衡二叉搜索树之一,其名字来源于两位发明它的科学家G. M. Adelson-Velsky 和 E. M. Landis(来自苏联的科学家). AVL树的特点 AVL树 ...

  7. 【算法】红黑树插入数据(变色,左旋、右旋)(二)

    本人菜鸡一只,正在更新红黑树系列的文章. 该系列已经全部更完,有5篇文章: [算法]红黑树(二叉树)概念与查询(一):https://blog.csdn.net/lsr40/article/detai ...

  8. 平衡二叉树(AVL)的左旋和右旋

    平衡二叉树(AVL)的左旋和右旋 最近算法和数据结构受虐,于是开始从二叉树学习,诸君共勉,同时也作为笔记.其实要理解思想不难,关键是要有耐心,不要觉得它难! 构建左平衡: bf :平衡度,可取值LH( ...

  9. HashMap的工作原理和底层实现(二)红黑树的左旋、右旋

    HashMap中的红黑树左旋.右旋 摘要: HashMap是java最常用的容器之一,本文会通过阅读源码的方式来理解HashMap中是如何进行红黑树的左旋和右旋 一.什么是左旋和右旋 红黑树的性质 每 ...

最新文章

  1. JetBrains 2018 中国开发者生态报告:Java 最流行
  2. Spring Boot + thymeleaf 实现文件上传下载
  3. HTTP状态码和编程
  4. OpenCASCADE绘制测试线束:简单的向量代数和测量之矢量代数命令
  5. 阿里云视频云编码优化的思考与发现
  6. 在自定义HttpHandler中如何使用Session
  7. python操作时间加减与格式输出
  8. Hyperledger Fabric服务器配置及修改Docker容器卷宗存储根目录/位置
  9. 二十年后我发明了保姆机器人作文_【赏学堂】苹果五级作文班优秀作品赏析——温睿哲二十年后回故乡...
  10. UI Framework-1: Ash Color Chooser
  11. 如何给CSDN上的每篇原创文章添加版权声明
  12. Acoustica Premium Edition Mac(音频编辑软件)
  13. adb pull 报错处理:adb: error: cannot create file/directory 'E:\': No such file or directory
  14. 参观移动公司机房感想
  15. Python进行模糊匹配
  16. c语言中中不同类型数据间的混合运算
  17. ipa包上传itunes store失败
  18. python调用pyd失效
  19. [渝粤教育] 天津师范大学 中学地理教学设计 参考 资料
  20. 【报告分享】2020中国民营企业500强调研分析报告-全国工商联(附下载)

热门文章

  1. BIM与超级计算机,BIM到底是什么?解读真正的BIM
  2. php twig if,twig基本语法
  3. mysql数据存储过程添加数据_Mysql 存储过程 自动插入数据
  4. GAN ZOO - 第1节: 分析GAN的缺陷与改进方向,介绍典型的改进模型:CGAN、InfoGAN
  5. 财务知识入门——《富爸爸,穷爸爸》
  6. 浪潮服务器NF5280m5 raid硬盘驱动 配置,raid和系统
  7. linux网络编程--网络编程的基本函数介绍与使用【转】
  8. 【亲测有效】树莓派4B安装realsense(Intel深度摄像头)
  9. 微信小程序的消息推送的token的配置
  10. 一部手机就能完成人像三维扫描建模