【图文解析】字符串的左旋与右旋


例题描述

实现一个函数,将一给定字符串str,与给定一特定值k,要求将字符串改变为旋转后的顺序。

示例:

  1. 字符串ABCD左旋2次:CDAB
  2. 字符串ABCD右旋3次:DABC

左旋

思路一

保存首字符,所有字符向前挪动一位,将首字符置于字符串尾部,循环k次

  1. 创建临时字符变量保存首字符,因为如若不保存的话,就会被后一位的字符覆盖。
    在这里插入图片描述
  2. 创建一临时指针cur充当传入指针(为了不影响传入的参数),作为“搬运工”。
  3. 建立循环使操作多次执行,循环判定条件为:指针的下一位不指向字符串结束符\0,而不是指针不指向\0
    在这里插入图片描述
    因为我们要在cur指针指向它本身的结束符之前,将首字符插入进去。这就要求cur最后的指向不能是结束符,否则此时插入首字符,字符间就有了“空缺”。
    在这里插入图片描述
  4. 字符的搬运逻辑很简单,简单的后字符对于前字符的赋值操作。即图中的红箭头。
  5. 以上为单此逻辑,左旋了1次,为了使用参数k,即左旋k次。通过大循环逐次递减完成。
    在这里插入图片描述
    最终得到的处理后的字符串:BCDA

代码实现

void left_rotate(char *str,int k){
  while(k--){
    //1. 保存首字符
    char temp = *str;
    char *cur = str;
    while(*(cur+1)){
      *cur = *(cur + 1);
      cur++;
    }
    //2. 把首字符放在最后一个位置
    *cur = temp;
  }
}

思路二

左旋k次,相当于逆转前k个字符,在逆转剩余字符,再整体逆转

  1. ABCDEF字符串,假如要左旋3次,相当于前三个字符串先进行逆转:CBADEF
  2. 在对剩下的字符串进行逆转:CBAFED
  3. 最终整体逆转:DEFABC

代码实现

因为字符串逆序操作在下面经常使用,所以我们选择将它封装成为一个函数,多次调用。
传入函数的参数为字符指针。

void reverse(char *left,char *right){
  while(left < right){
    char temp = *left;
    *left = *right;
    *right = temp;
    left++;
    right--;
  }
}

正式逻辑

void left_rotate2(char *str,int k){
  //第一次逆转前k个字符
  reverse(str,str+k-1);

  //第二次逆转剩下字符
  reverse(str+k,str+strlen(str)-1);

  //第三次整体逆转
  reverse(str,str+strlen(str)-1);
}

右旋

解题思路

右旋k次,相当于左旋(str长度 - k)次

  1. 字符串ABCD右旋1次:DABC
  2. 相当于其左旋3次:DABC
  3. 所以如果要通过左旋函数完成右旋,需要直到字符串的长度,所以用到了strlen的字符串库函数,通过直接调用完成右旋逻辑。
void right_rotate(char *str,int k){
  //A B C D --> 一次 D A B C    右旋一次相当于左旋3次,右旋k次,相当于左旋strlen(str) - k次
  left_rotate2(str,strlen(str) - k);
}

小结

我们编写程序时一定要学会“偷懒”与联想,有可能我们之前书写的函数逻辑可以变相应用与其他函数中,这种函数间的相互调用十分常见,题目中左旋函数与右旋函数通过strlen库函数产生了关联,这是我们多次使用总结出来的规律,所以将以往的经验融会贯通,加以联想,就可以“出一份力而受益多次”,学会“偷懒”。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值