题目:实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA

方法一:三步旋转法

左旋程序思路:首先根据画图得知左旋后的结果,然后在分析实现的简约步骤;
第一步:字符串全逆序;
第二步:左边的字符串逆序;
第三步:右边的字符串逆序;

举例:左旋K=1个字符:

首先是头文件和主函数部分:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>int main()
{char arr[] = "aabcd";/*未定义的数组内容不能用{}括起来,只能采用“”的形式。*/printf("%s\n", my_left_move(arr, 1));/*表示左旋一个字符*/system("pause");return 0;
}

接下来是左旋函数实现部分:

char* my_left_move(  char *src, int count)/* 函数的实现,此处的src是指针变量,不能加coonst常属性,是不可修改的左值*/
{int i = 0;int len = strlen(src);char tmp = 0;assert(src);//断言指针的有效性for (i = 0; i < len/2; i++)//第一步:整体逆序{采用了数组的方式:并且循环条件除以2是为了优化算法;/*tmp = src[i];src[i] = src[i + len-1];src[i + len-1] = tmp;*/采用指针的形式符合函数定义tmp=*(src+i);*(src + i) = *(src  + len - 1-i);//此处的下标要自己去分析的src变成了src+len-1,+i变成了-i;*(src + len - 1 - i) = tmp;}for (i = 0; i <(len-count)/2 ; i++)//第二步:左边的字符串逆序{tmp = *(src + i);*(src + i) = *(src + len -count- 1 - i);*(src + len - count-1 - i) = tmp;}for (i=0; i <count/2; i++)//第三步:右边的字符串逆序{tmp =*(src + len -count+i) ;*(src + len -count  + i) = *(src+len-1-i);*(src + len - 1 - i) = tmp;}return src;
}

然后是整个程序:(左旋一个字符)

左旋一个字符:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>char* my_left_move(  char *src, int count)/* 函数的实现,此处的src是指针变量,不能加coonst常属性,是不可修改的左值*/
{int i = 0;int len = strlen(src);char tmp = 0;assert(src);//断言指针的有效性for (i = 0; i < len/2; i++)//第一步:整体逆序{采用了数组的方式:并且循环条件除以2是为了优化算法;/*tmp = src[i];src[i] = src[i + len-1];src[i + len-1] = tmp;*/采用指针的形式符合函数定义tmp=*(src+i);*(src + i) = *(src  + len - 1-i);//此处的下标要自己去分析的src变成了src+len-1,+i变成了-i;*(src + len - 1 - i) = tmp;}for (i = 0; i <(len-count)/2 ; i++)//第二步:左边的字符串逆序{tmp = *(src + i);*(src + i) = *(src + len -count- 1 - i);*(src + len - count-1 - i) = tmp;}for (i=0; i <count/2; i++)//第三步:右边的字符串逆序{tmp =*(src + len -count+i) ;*(src + len -count  + i) = *(src+len-1-i);*(src + len - 1 - i) = tmp;}return src;
}
int main()
{char arr[] = "aabcd";/*未定义的数组内容不能用{}括起来,只能采用“”的形式。*/printf("%s\n", my_left_move(arr, 1));/*表示左旋一个字符*/system("pause");return 0;
}

举例:左旋K=2个字符:

无论左旋多少个字符,方法一样,只是在区分左串和右串的时候把要移动的字符串看做一个整体,其内部顺序不变;

同样的先是头文件和主函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>int main()
{char arr[] = "aabcd";/*未定义的数组内容不能用{}括起来,只能采用“”的形式。*/printf("%s\n", my_left_move(arr, 2));/*表示左旋两个字符*/system("pause");return 0;
}

接下来是左旋函数实现部分:

char* my_left_move(char *src, int count)/* 函数的实现,此处的src是指针变量,不能加coonst常属性,是不可修改的左值*/
{int i = 0;int len = strlen(src);char tmp = 0;assert(src);//断言指针的有效性for (i = 0; i < len / 2; i++)//第一步:整体逆序{采用了数组的方式:并且循环条件除以2是为了优化算法;/*tmp = src[i];src[i] = src[i + len-1];src[i + len-1] = tmp;*/采用指针的形式符合函数定义tmp = *(src + i);*(src + i) = *(src + len - 1 - i);//此处的下标要自己去分析的src变成了src+len-1,+i变成了-i;*(src + len - 1 - i) = tmp;}for (i = 0; i <(len - count) / 2; i++)//第二步:左边的字符串逆序{tmp = *(src + i);*(src + i) = *(src + len - count - 1 - i);*(src + len - count - 1- i) = tmp;}for (i = 0; i <count / 2; i++)//第三步:右边的字符串逆序{tmp = *(src + len - count + i);*(src + len - count + i) = *(src + len - 2 - i);*(src + len - 2- i) = tmp;}return src;
}

然后是整个程序:(左旋两个字符)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<string.h>
char* my_left_move(char *src, int count)/* 函数的实现,此处的src是指针变量,不能加coonst常属性,是不可修改的左值*/
{int i = 0;int len = strlen(src);char tmp = 0;assert(src);//断言指针的有效性for (i = 0; i < len / 2; i++)//第一步:整体逆序{采用了数组的方式:并且循环条件除以2是为了优化算法;/*tmp = src[i];src[i] = src[i + len-1];src[i + len-1] = tmp;*/采用指针的形式符合函数定义tmp = *(src + i);*(src + i) = *(src + len - 1 - i);//此处的下标要自己去分析的src变成了src+len-1,+i变成了-i;*(src + len - 1 - i) = tmp;}for (i = 0; i <(len - count) / 2; i++)//第二步:左边的字符串逆序{tmp = *(src + i);*(src + i) = *(src + len - count - 1 - i);*(src + len - count - 1- i) = tmp;}for (i = 0; i <count / 2; i++)//第三步:右边的字符串逆序{tmp = *(src + len - count + i);*(src + len - count + i) = *(src + len - 2 - i);*(src + len - 2- i) = tmp;}return src;
}
int main()
{char arr[] = "aabcd";/*未定义的数组内容不能用{}括起来,只能采用“”的形式。*/printf("%s\n", my_left_move(arr, 2));/*表示左旋两个字符*/system("pause");return 0;
}

方法二:移相法

我们可以通过画图的方式来实现移相左旋:

我们直接来做左旋K=2个字符的:

01.<span style="font-size:18px;color:#ff0000;"><strong>
02.</strong></span>#define _CRT_SECURE_NO_WARNINGS 1
03. #include<assert.h>
04. #include<windows.h>
05. #include<stdio.h>
06. #include<string.h>
07. void  my_left_move(char* str, int count)
08. {
09.  assert(str);
10.  int i = 0;
11.  int len = strlen(str);
12.  if (len <= 1)
13.  {
14.   return ;
15.  }
16.  for (i = 0; i <count; i++)
17.  {
18.   int j = 0;
19.   char  tmp = str[0];  <span style="font-size:18px;color:#ff0000;"><strong>//把第一个字符保存起来</strong></span>
20.  for (j = 0; j < len - 1; j++)
21.   {
22.
23.    *(str + j) = *(str + j + 1);  <span style="font-size:18px;"><span style="color:#ff0000;"><strong>//然后依次进行平移</strong>
24.</span></span>  }
25.   *(str + len - 1) = tmp;  <span style="color:#ff0000;"><strong><span style="font-size:18px;">//再把tmp保存的内容赋给最后一个空位</span></strong>
26.</span> }
27. }
28.int main()
29. {
30.  char arr[] = "AABCD";
31.  int k= 2;
32.  my_left_move(arr, k);
33.  printf("%s\n", arr);
34.  system("pause");
35.  return 0;
36. }

总结:左旋一个字符或者多个字符的唯一差别就是在最后一步右边字符串的逆序个数上,循环条件K即count变了呢!

那么做完左旋的你是不是也想做一做右旋呢?其实你只要画画图就知道,右旋和左旋其实是一样的只不过你在区分左串和右串的起始位置有所不同而已!

那么这里给出一个右旋K=count个字符的右旋实现程序:(采用三步旋转法)

(传参合适的K)

这里也可以采用移相法!!!

<strong>char* my_right_move(char *src, int count)/* 函数的实现,此处的src是指针变量,不能加coonst常属性,是不可修改的左值*/
{int i = 0;int len = strlen(src);char tmp = 0;assert(src);//断言指针的有效性for (i = 0; i < len / 2; i++)//第一步:整体逆序{采用了数组的方式:并且循环条件除以2是为了优化算法;/*tmp = src[i];src[i] = src[i + len-1];src[i + len-1] = tmp;*/采用指针的形式符合函数定义tmp = *(src + i);*(src + i) = *(src + len - 1 - i);//此处的下标要自己去分析的src变成了src+len-1,+i变成了-i;*(src + len - 1 - i) = tmp;}for (i = 0; i <(len - count) / 2; i++)//第二步:左边的字符串逆序{tmp = *(src + i);*(src + i) = *(src + len - count - 1 - i);*(src + len - count - 1 - i) = tmp;}for (i = 0; i <count / 2; i++)//第三步:右边的字符串逆序{tmp = *(src + len - count + i);*(src + len - count + i) = *(src + len - 1 - i);*(src + len - 1 - i) = tmp;}return src;
}</strong>

题目:判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1 = abcd和s2 = ACBD,返回0.

AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC
AABCD右旋两个字符得到CDAAB

同样先把头文件和主函数编好:

16.#define _CRT_SECURE_NO_WARNINGS 1
17.#include<assert.h>
18.#include<windows.h>
19.#include<stdio.h>
20.#include<string.h>
21.
22.int main()
23.{
24.    char arr[] = "AABCD";
25.    int ret = my_move(arr, "ABCDA");
26.    if (ret == 1)
27.    {
28.        printf("yes\n");
29.    }
30.    else
31.    {
32.        printf("no\n");
33.    }
34.    system("pause");
35.    return 0;
36.}
37.

然后是函数实现部分:

char my_move(char* str1, char* str2)
42.{
43.    assert(str1);
44.    assert(str2);
45.    int len = strlen(str1);
46.    strncat(str1, str1, len);
47.    if (strstr(str1, str2))
48.    {
49.        return 1;
50.    }
51.    else
52.    {
53.        return 0;
54.    }
55.}

最后是整个程序:

01.#define _CRT_SECURE_NO_WARNINGS 1
02.#include<assert.h>
03.#include<windows.h>
04.#include<stdio.h>
05.#include<string.h>
06.char my_move(char* str1, char* str2)
07.{
08.    assert(str1);
09.    assert(str2);
10.    int len = strlen(str1);
11.    strncat(str1, str1, len);
12.    if (strstr(str1, str2))
13.    {
14.        return 1;
15.    }
16.    else
17.    {
18.        return 0;
19.    }
20.}
21.int main()
22.{
23.    char arr[] = "AABCD";
24.    int ret = my_move(arr, "ABCDA");
25.    if (ret == 1)
26.    {
27.        printf("yes\n");
28.    }
29.    else
30.    {
31.        printf("no\n");
32.    }
33.    system("pause");
34.    return 0;
35.}  .
<span style="color:#cc0000;">  </span>

哈哈,到这里,整个左旋右旋相信已经一目了然了,继续加油吧!


字符串左旋右旋——三步旋转法和移相法相关推荐

  1. 字符串的左旋右旋问题(C语言实现,三种方法求解)

    字符串左旋右旋问题其实是同理的,下边以左旋为例: 方法一 思路:左旋一次就是将整个字符串向左移一个字符,第一个字符(arr[0])移动到最右侧.这样循环操作左旋次数就是最终左旋结果,如上图所示. 实现 ...

  2. 字符串的左旋右旋问题

    字符串的左旋右旋其实是一个问题,下面只对右旋进行分析. 当一个字符串进行旋转的时候,字符串的大小会决定有效旋转次数.这里面的有效是指,后面的旋转会与前面的旋转相同,所以我们必须要对旋转次数进行去重. ...

  3. 二叉树旋转--左旋|右旋

    二叉树旋转 二叉树的旋转主要是应用在AVL树中,当添加一个节点时候导致左右两个子树的高度差不在是-1 , 1 , 0而变成了2 或者-2.此时就需要用到左旋/右旋了.当然左右旋或者有左旋也是基于左旋和 ...

  4. HashMap 数据结构之红黑树, 红黑树在什么时候左旋 右旋 如何旋转

    树结构是数据结构中最经典最常用的结构之一,也是面试中常问的面试题,最近学习了一下红黑树的知识,记录整理一下 文章目录 一.红黑树的特征 二.变色左旋和右旋 1.变色规则 2.左旋 3.右旋 总结 前言 ...

  5. 【每天学一点系列~】字符串左/右旋的本质,你真的认清了嘛?

    学透字符串的旋转 Part I.前言 Part II.左/右旋 1.定义 2.共同特点 Part III.初阶解法 解法一:创建新数组 解法二:原地算法(直接法) Part IV.进阶解法 1. 三步 ...

  6. 搞懂平衡二叉树的左旋右旋双旋(Java实现)

    刚看到韩顺平老师的数据结构与算法对于平衡二叉树的讲解(最后会附上地址),有如下理解,希望能帮助大家!哪里需要改正的欢迎指正! 平衡二叉树:一种二叉排序树(BST Binary Sort Tree)的升 ...

  7. nyoj202 红黑树 (二叉树的左旋右旋)

    题目202 题目信息 运行结果 本题排行 讨论区 红黑树 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 什么是红黑树呢?顾名思义,跟枣树类似,红黑树是一种叶子是黑色果子 ...

  8. avl树左旋右旋的理解

    一直没搞懂非平衡二叉树变平衡二叉树时左旋右旋,今天下定决心搞懂,然后在众多博客中终于找到了这样一篇,非常形象,记录如下: AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大 ...

  9. 左旋右旋问题一次搞定!!!

    左旋右旋问题的解决 编程思想 1.在左右旋函数中实现该函数功能首先要想好如何存放移位后的字符元素 2.左旋时将字符串首元素赋给临时变量tmp而后将字符串元素依次前移一位 3.将tmp的值再赋给字符串的 ...

最新文章

  1. 智能车百度赛道培训第一弹-基础篇
  2. 更新linux内核版本,求问Linux最新内核版本以及发布日期。
  3. BPI:bit for Webduino WEB:Bit 教育版平台正式发布,支持离线安装使用
  4. 达摩院2020十大科技趋势发布:科技浪潮新十年序幕开启
  5. 文件I/O实践(1) --基础API
  6. python中xpath如何获取内容_python requests + xpath 获取分页详情页数据存入到txt文件中...
  7. rhel5.5下安装oracle10g报libXp.so.6错误
  8. 朱嘉明《火药:改变了人类历史演变模式》
  9. zheng-环境搭建及系统部署文档
  10. C++:实现量化基础互换利率basis swap rate helpers测试实例
  11. 宠物收养所[Treap]
  12. PTA Python函数题 7-1 模拟乒乓球比赛 (20 分)
  13. 爱创课堂分享web前端学习路线自学如何找到工作
  14. python青蛙跳台阶_Python算法题(一)——青蛙跳台阶
  15. python自动点赞微信_基于AirTest+Python的ios自动化测试demo(微信朋友圈无限点赞)
  16. Windows桌面应用程序(1-2-4-4th) 您的第一个Direct2D程序
  17. python学了可以干什么,python是用来干嘛的
  18. 约翰·刘易斯·加迪斯《论大战略》读书笔记
  19. FreeBSD install
  20. office2003和office2007比较

热门文章

  1. Unity使用System.Data.dll报错
  2. 罕见!谷歌员工成立工会,国外网友:员工维权行动已席卷硅谷!
  3. 论文阅读笔记: (2022 TPAMI) Ultra Fast Deep Lane Detection with Hybrid Anchor Driven Ordinal Classification
  4. 【YBT2023寒假Day9 B】买棉花糖(DP)(分治)
  5. 基于JAVA的城市公交查询系统毕业论文
  6. 编程规范 写 if 语句不要任性
  7. FastDFS,Redis,Solr,ActiveMQ核心技术整合三
  8. 泛微ecology9后端二开环境搭建及远程调试教程
  9. ST-LINK/V2烧录AT32芯片方法
  10. canvas 菜鸟入门笔记