OJ题库:左移n位字符串(2种方法)

简介: OJ题库:左移n位字符串(2种方法)

一.什么是左移

左移就是指将一个字符串中的部分字符向左移动到字符串的末尾。

       比如 ABCDE左移 1位后的结果就是 BCDEA ,左移 2 位后的结果就是CDEAB ,左移 4 位就是 EABCD

二.方法一

1.设计思路(怎么实现左移)

       在理解了左移是什么之后,我们会发现,这很像我们对数组进行排序然后交换位置,都是将元素放在临时变量中,然后再反复赋值,所以我们可以考虑使用临时变量拿到首个字符串,然后放在字符串末尾,重复完成这样的操作,直到我们完成需要的左移次数。


       但是这样写代码是会有问题的,首先,字符串数组的长度是有限的,我们单纯的将首个字符放在字符串末尾,字符串的长度是发生变化了的,我们相当于对这个字符串数组多赋了几个值,并且在打印这样的字符串的时候,从哪个地方开始打印又是一件非常麻烦的事情,所以我们在用临时变量保存首元素后,我们还得先将整个字符串向前移动一格,将末尾字符串的位置空出来,然后再把临时变量中的首元素放在末尾位置上去。这样的话,数组的长度就是一直保存不变的,打印的时候我们也好直接从第一个元素开始打印。

如下图所示(左移一位):

2.实现细节

  •        要实现上诉操作,我们首先初始化一个非常大的数组,因为在 C99 之前是不支持边长数组的,笔者使用的 VS2022 也是在如此。
  •        然后是对数组的输入功能,考虑到实际情况,我们对字符串数组的输入可能是中文,可能是英文,可能是数字,也有可能是空格等特殊的符号,而 scanf 函数在接收到空格输入则会停止接收输入,所以综合考虑下,我们使用 gets 函数进行输入

scanf 也是可以输入空格的,加入[^\n]  即可,具体演示如下)

scanf("%[^\n]%*c", string);
  •   在完成输入后,我们还需要使用 strlen 函数拿到字符串的有效长度,然后传递给自定义的左旋函数,这样做是为了拿到字符串的尾部地址,方便操作        
  •        在具体实现左旋的时候,我们可以使用俩个循环进行嵌套,一个用来不断的取出首元素的字符,另一个用来不断的让首元素后的字符串向前移动

3.代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
void left_rotate_string(char* first,int len,int k)
{
  assert(first != NULL);
  char* end = first + len - 1;
  for (int i = 0; i < k; i++)
  {
    char temp = 0;
    temp = *first;//将首部字符暂时存放在零时变量中
    for (int j = 0; j < len - 1; j++)//将后面的字符依次向前移动
    {
      *(first + j) = *(first + j + 1);
    }
    *end = temp;//将第一个字符放在最后一个位置上
  }
}
int main()
{
  int k = 0;//记录左旋个数
  char string[10000] = "0";
  printf("请输入要左旋的字符串:\n");
  gets_s(string);
  printf("请输入要左旋的个数:\n");
  scanf("%d", &k);
  size_t len = strlen(string);
  left_rotate_string(string,len,k);
  puts(string);
  return 0;
}

三.方法二

1.设计思路

       我们可以使用三次反转的方法来达到我们的目标,先将需要左移的字符串反转,然后对于剩余的字符串反转,最后再对整个字符串反转,这样也能达到我们想要的效果,具体操作如下图所示

 如果对于反转字符串有不了解的小伙伴们欢迎点击笔者的这篇文章,里面对反转字符串有详细的教学:一篇文章拿下反转字符串

2.代码实现

void reverse(char* first, char* end)//实现翻转函数
{
  char* left = first;//记录左指针
  char* right = end;//记录右指针
  while (left < right)
  {
    char tmp = *left;
    *left = *right;
    *right = tmp;
    left++;
    right--;
  }
}
void left_rotate_string(char* first, int k,int len)
{
  //传进reverse的是两个指针
  reverse(first, first + k - 1);    //第一步翻转 ——反转首部需要左移的字符
  reverse(first + k, first + len - 1);//第一步翻转 ——反转后面的字符串
  reverse(first, first + len - 1);  //第一步翻转 ——反转整个字符串
}
int main()
{
  int k = 0;//记录左旋个数
  char string[10000] = "0";
  printf("请输入要左旋的字符串:\n");
  gets_s(string);
  printf("请输入要左旋的个数:\n");
  scanf("%d", &k);
  int len = strlen(string);
  left_rotate_string(string, k,len);
  printf("%s\n", string);
  return 0;
}

四.运行结果示例

 

文章内容如有不对,欢迎积极指正,本次分享就到此为止了,谢谢大家的支持

目录
相关文章
|
6月前
|
Java 测试技术 Python
每日一题《剑指offer》字符串篇之表示数值的字符串
每日一题《剑指offer》字符串篇之表示数值的字符串
48 0
每日一题《剑指offer》字符串篇之表示数值的字符串
|
6月前
剑指Offer LeetCode 面试题17. 打印从1到最大的n位数
剑指Offer LeetCode 面试题17. 打印从1到最大的n位数
36 0
|
6月前
剑指Offer LeetCode 面试题50. 第一个只出现一次的字符
剑指Offer LeetCode 面试题50. 第一个只出现一次的字符
35 0
|
算法
代码随想录算法训练营第八天 | LeetCode 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串
代码随想录算法训练营第八天 | LeetCode 344.反转字符串、541. 反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串
60 0
|
算法 索引
代码随想录算法训练营第八天 | 344.反转字符串541. 反转字符串II 剑指Offer 05.替换空格151.翻转字符串里的单词剑指Offer58-II.左旋转字符串
代码随想录算法训练营第八天 | 344.反转字符串541. 反转字符串II 剑指Offer 05.替换空格151.翻转字符串里的单词剑指Offer58-II.左旋转字符串
|
Python Cloud Native
【刷题日记】415. 字符串相加
本次刷题日记的第 48 篇,力扣题为:415. 字符串相加 ,简单
剑指offer_字符串---左旋转字符串
剑指offer_字符串---左旋转字符串
48 0
|
算法 API
LeetCode:剑指Offer 05. 替换空格 (字符串)
题目描述:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
【牛客在线OJ】-字符逆序
【牛客在线OJ】-字符逆序
75 0
|
存储 容器
代码随想录刷题|LeetCode 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和
代码随想录刷题|LeetCode 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和
代码随想录刷题|LeetCode 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和