OJ题库:字符串反转(包含进阶)

简介: OJ题库:字符串反转(包含进阶)

1.基础的字符串反转

初始化:

     首先,我们需要一个字符数组来保存我们需要反转的字符串,但是在 C99 之前是不允许使用变长数组的,所以在此(VS2022)的情况下,我们一开始就设置一个很大的数组,然后进行初始化

使用何种输入:        


在输入的时候,我们则需要考虑使用何种输入方式,因为我们输入的字符串往往都是包含空格的,所以我们就排除使用 scanf 的方法,当然 scanf 也不是不能用,后文笔者会进行详细介绍的,这里就不再赘述。然后我们就考虑在 gets 和 get 中使用哪个,因为我们需要输入的是字符串,使用 get 的话需要添加循环来判断是否持续输入,所以综合考虑下,选择使用 gets 函数(因为笔者使用的编译器VS2022中对于 gets 函数会判断为不安全,所以这里使用 gets_s 函数来避免这个问题,但正常都是可以运行的)


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

scanf("%[^\n]%*c", string);

如何交换:


  首先我们得拿到字符串的长度,在这里可以考虑使用 srtlen 函数(得包含头文件 #include<string.h> )然后进行反复交换字符,第一个和最后一个交换,第二个和倒数第二个交换,第三个和倒数第三个交换,想要达到这种效果就可以考虑使用指针,交换首位字符 ,然后移动指针,再交换下一位,当左指针 left 小于 右指针 right 就进行交换,这样做是为了保证中间有空余字符空余交换,如下图所示

完整代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<windows.h>
void reverse(char* left, char* right)
{
  while (left < right)
  {
    char temp = 0;
    temp = *left;
    *left = *right;
    *right = temp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };//初始化字符数组
  gets_s(arr);//输入数组
  int len = strlen(arr);//拿到字符串长度
  reverse(arr, arr+len-1);//传入字符串首地址和尾地址
  printf("%s\n\n", arr);
  system("pause");
  return 0;
}

运行结果示例:

2.进阶字符串反转(要求原单词不变)

分析设计思路:


     初始化和输入都是和上述基础部分是一样的,我们只需要思考如何做到字符串反转了,但是单词里面的字母顺序是保持不变的,观察上述基础部分的运行结果,我们可以发现单词的位置是没问题的,要是能把每一个单词再反转一次,就能达到我们的目的了,那么问题来了,怎么把每一个单词反转一遍?


我们可以观察我们设置的反转字符串的函数

void reverse(char* left, char* right)

函数内部的参数是俩个指针,分别用来拿到字符串的首地址和位地址,也就是说我们只要知道一个字符串的首地址和尾地址,那我们就可以反转这个字符串,所以我们只需要在原有的代码基础上对字符串进行遍历,然后拿到每一个单词的首地址和尾地址,就可以解决我们的问题了

遍历字符串拿到单词首尾地址:

我们可以使用 while 循环来判断当前字符是否为空,如果不为空,那我们就移动指针,继续判断下一个字符,当判断读取到空格时,就跳出循环,然后用当前位置减一就可以拿到单词的尾地址

char* start = cur;//记录每一个单词的起始位置
    while (*cur != ' ' && *cur != '\0')
    {
      cur++;//判断此处字符是有效字符后继续判断下一个
    }
    char* end = cur - 1;//拿到每一个单词的末尾位置
    reverse(start, end);//反转一个单词

   以上我们就拿到了一个单词的首地址和尾地址,但是我们的输入往往是有多个单词组成的句子,所以我们还不能停止遍历,还得继续拿到下一个单词的首尾地址,我们可以做如下设计,在前面的代码中再在外边套一个 while 循环,直接用 cur 指针指向的字符进行判断,我们知道 \0 的 ACSII 码的值为 0 ,当 while 读取到 \0 后判断为假,结束循环,此时刚好对所有的字符遍历完成,另外,在我们每一个拿到一个单词的首尾地址后,我们得跳过这个单词后面的空格,所以使用 if 语句进行判断跳过

  while (*cur)
  {
    char* start = cur;//记录每一个单词的起始位置
    while (*cur != ' ' && *cur != '\0')
    {
      cur++;//判断此处字符是有效字符后继续判断下一个
    }
    char* end = cur - 1;//拿到每一个单词的末尾位置
    reverse(start, end);//反转一个单词
    if (*cur == ' ')
    {
      cur++;
    }
  }

完整代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
#include<string.h>
void reverse(char* left, char* right)
{
  while (left < right)
  {
    char temp = 0;
    temp = *left;
    *left = *right;
    *right = temp;
    left++;
    right--;
  }
}
int main()
{
  char arr[1000] = "0";//初始化字符数组
  gets_s(arr);//输入字符串
  int len = strlen(arr);
  //反转字符串
  reverse(arr, arr + len - 1);
  //反转每一个单词
  char* cur = arr;
  while (*cur)
  {
    char* start = cur;//记录每一个单词的起始位置
    while (*cur != ' ' && *cur != '\0')
    {
      cur++;//判断此处字符是有效字符后继续判断下一个
    }
    char* end = cur - 1;//拿到每一个单词的末尾位置
    reverse(start, end);//反转一个单词
    if (*cur == ' ')
    {
      cur++;
    }
  }
  printf("%s\n\n", arr);
  system("pause");
  return 0;
}

运行结果示例:

以上就是本次分享,如有不对,欢迎多多指正,希望我的分享能为您带来帮助

目录
相关文章
|
8天前
|
存储
力扣面试经典题之数组/字符串
力扣面试经典题之数组/字符串
27 0
|
8月前
|
C语言
C语言简单题目的优化合集(多种解法分享)
C语言简单题目的优化合集(多种解法分享)
38 0
|
8天前
|
算法 测试技术 索引
力扣面试经典题之数组/字符串(二)
力扣面试经典题之数组/字符串(二)
15 0
|
8天前
|
存储 算法 索引
刷题专栏(二十六):字符串中的第一个唯一字符
刷题专栏(二十六):字符串中的第一个唯一字符
80 1
刷题专栏(二十六):字符串中的第一个唯一字符
|
Python
Python 力扣刷题之单链表专场!例题20+ 属性和方法60+
Python 力扣刷题之单链表专场!例题20+ 属性和方法60+
73 0
|
索引 Python
Python 力扣刷题之单链表专场!例题20+ 属性和方法60+(2)
Python 力扣刷题之单链表专场!例题20+ 属性和方法60+
100 0
Python 力扣刷题之单链表专场!例题20+ 属性和方法60+(2)
|
存储
【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!
【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!
55 0
LeetCode每日一题——791. 自定义字符串排序
给定两个字符串 order 和 s 。order 的所有单词都是 唯一 的,并且以前按照一些自定义的顺序排序。
72 0
|
算法
​LeetCode刷题实战415:字符串相加
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
120 0
|
算法 索引
​LeetCode刷题实战387:字符串中的第一个唯一字符
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
84 0

热门文章

最新文章