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;
}

运行结果示例:

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

目录
相关文章
|
7月前
|
存储 算法 索引
刷题专栏(二十六):字符串中的第一个唯一字符
刷题专栏(二十六):字符串中的第一个唯一字符
103 1
刷题专栏(二十六):字符串中的第一个唯一字符
|
7月前
|
存储 C语言
【PTA刷题】请编写函数,求子串(详解+代码)
【PTA刷题】请编写函数,求子串(详解+代码)
126 0
OJ题库:左移n位字符串(2种方法)
OJ题库:左移n位字符串(2种方法)
127 0
|
存储
华为机试每日一练--第九题: 字符串反转
华为机试每日一练--第九题: 字符串反转
华为机试每日一练--第九题: 字符串反转
|
C++
AcWing语法基础课笔记 第二章 printf语句与C++中的判断结构
学习语言最好的方式就是实践,每当掌握一个新功能时,就要立即将这个功能应用到实践中。 ——闫学灿
106 0
|
数据安全/隐私保护 C++
AcWing语法基础课笔记 第五章 C++中的字符串
字符串是计算机与人类沟通的重要手段。 ——闫学灿
110 0
|
存储 人工智能 C++
C++学习笔记(十二)——String类练习题(下)
C++学习笔记(十二)——String类练习题(下)
C++学习笔记(十二)——String类练习题(下)
|
存储
【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!
【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!
71 0
|
算法 索引 Python
Python每日一练(牛客网新题库)——第2天:逆序输出字符串
Python每日一练(牛客网新题库)——第2天:逆序输出字符串
286 1
|
机器学习/深度学习
牛客网练习题(函数部分)
牛客网练习题(函数部分)
98 0