【C语言刷题】字符串逆序

简介: 【C语言刷题】字符串逆序

一、字符串逆序(基础题)

链接:字符逆序__牛客网

来源:牛客网

这道题的要求是让我们实现一个字符串逆序

1.一个经典的错误,标准的零分

这道题其实,思路上不难,但是有一个点处很容易犯错,我们看下面这个代码

#include<stdio.h>
#include<string.h>
void reverse(char* str)
{
  int left = 0;
  int right = strlen(str) - 1;
  while (left < right)
  {
    char tmp = 0;
    tmp = *(str + left);
    *(str + left) = *(str + right);
    *(str + right) = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };
  scanf("%s", arr);
  reverse(arr);
  printf("%s", arr);
  return 0;
}

看似正确,但实际上存在一个问题,我们现在牛客网上跑一下

果然如我们所料,出现意外了,那么问题出在哪里了呢?其实,问题是出在scanf上了,scanf默认读取到空格就结束了,因此这道题其实只读取了一个d,反转之后当然是d了

2.采用gets函数来修补漏洞

既然scanf不能用,那么该如何解决呢?,其实我们c语言中还有一个函数叫做gets()函数,他也可以读取一个字符串,他不会读取到空格就结束了

代码如下

#include<stdio.h>
#include<string.h>
void reverse(char* str)
{
  int left = 0;
  int right = strlen(str) - 1;
  while (left < right)
  {
    char tmp = 0;
    tmp = *(str + left);
    *(str + left) = *(str + right);
    *(str + right) = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };
  gets(arr);
  reverse(arr);
  printf("%s", arr);
  return 0;
}

牛客网运行结果为

3.非要使用scanf怎么办?

有些时候,非要使用scanf解决这个问题,那么我们如何实现呢?,其实我们可以将%s修改为%[^\n],意思是,读取到\n才结束读取

代码如下

#include<stdio.h>
#include<string.h>
void reverse(char* str)
{
  int left = 0;
  int right = strlen(str) - 1;
  while (left < right)
  {
    char tmp = 0;
    tmp = *(str + left);
    *(str + left) = *(str + right);
    *(str + right) = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };
  //gets(arr);
  scanf("%[^\n]", arr);
  reverse(arr);
  printf("%s", arr);
  return 0;
}

牛客网运行结果为

4.使用指针来实现逆序函数

上面的实现方式,其实本质上仍然属于数组的形式,那么我们能不能改为指针呢?答案是可以的,请看下面的代码

#include<stdio.h>
#include<string.h>
void reverse(char* str)
{
  char* left = str;
  char* right = str + strlen(str) - 1;
  while (left < right)
  {
    char tmp = 0;
    tmp = *left;
    *left = *right;
    *right = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };
  //gets(arr);
  scanf("%[^\n]", arr);
  reverse(arr);
  printf("%s", arr);
  return 0;
}

牛客网运行结果为

5.将函数修改为,只要传入两个地址,就能逆序这两个地址之间的字符串。

经历了上面的思考,我们在想,这个逆序多多少少还是有一点不方便,比如在某一个字符串中,我们不想逆序整个字符串,我们只想要逆序一部分,这时候我们上面的函数适用性就不够了,所以我们最好将其改成只要传入两个地址,就可以逆序这两个地址之间的字符串,这样的话,这个函数就变得很好用了。

代码如下

#include<stdio.h>
#include<string.h>
void reverse(char* left,char* right)
{
  while (left < right)
  {
    char tmp = 0;
    tmp = *left;
    *left = *right;
    *right = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[10000] = { 0 };
  //gets(arr);
  scanf("%[^\n]", arr);
  reverse(arr, arr + strlen(arr) - 1);
  printf("%s", arr);
  return 0;
}

牛客网运行结果为

二、字符串逆序(进阶)

有了上面那到题目作为基础,我们可以尝试做一下这道题

链接:倒置字符串_牛客题霸_牛客网

来源:牛客网

这道题我们可以看的出来,是上一道题的进阶版,但是根据我们上一道题的思考之后,这道题其实也没有那么难,因为我们已经创建一个函数,只要传入两个地址,就可以逆序这两个地址之间的字符串。

所以我们的思路就是,先逆序,整个字符串,然后逆序每一个单词

代码如下

#include<stdio.h>
#include<string.h>
void reverse(char* left,char* right)
{
  while (left < right)
  {
    char tmp = 0;
    tmp = *left;
    *left = *right;
    *right = tmp;
    left++;
    right--;
  }
}
int main()
{
  char arr[100] = { 0 };
  gets(arr);
  //逆序整句话
  reverse(arr, arr + strlen(arr) - 1);
  //逆序每一个单词
  char* p1 = arr;
  char* p2 = arr;
  while (*p2 != '\0')
  {
    p1 = p2;
    while (*p2 != ' '&&*p2!='\0')
    {
      p2++;
    }
    reverse(p1, p2 - 1);
    if (*p2 == '\0')
    {
      break;
    }
    p2++;
  }
  printf("%s", arr);
  return 0;
}

对于这段代码的逆序每一个单词环节,可能有很多人都有所困惑。为什么是这样实现的呢?

我们逆序单词是采用的双指针的方法。先定义两个字符指针他们指向字符串的首元素地址,然后我们令p1先不动,p2往下走,只要我的p2不是'\0',自然就可以一直走下去,在里面我们先采用一个while循环,来让p2 走到单词的末尾,然后使用逆序函数,逆序这两者之间的单词,然后判断一下p2的里面的值是否为\0,如果此时为\0就不需要进行接下来的步骤了,直接结束即可。

但是如果此时不为'\0',那么就要继续执行下去,先让p2++,让我们的p2指向下一个单词的首元素,将下一个单词的首元素交给p1,然后p2继续走下去,这样循环下去就可以实现目标了。

牛客网运行结果为

相关文章
|
1月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
1月前
|
机器学习/深度学习 编译器 C语言
C语言刷题(中)(保姆式详解)
C语言刷题(中)(保姆式详解)
15 0
|
2月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
2月前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
141 7
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
2月前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
3月前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
31 4
|
3月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
63 0
|
3月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
55 0
|
3月前
|
C语言
【C语言刷题训练】——第7节(含代码与分析思路)
【C语言刷题训练】——第7节(含代码与分析思路)