• [倒置字符串]



    前言

    大家好,我是熊猫,今天要和大家一起学习的是牛客网上一道编程题----倒置字符串,本题解法多样,熊猫今天整理了三种不同的解法,希望可以给大家提供不同的解题思想。


    一、题目描述

    将一句话的单词进行倒置,标点不倒置。比如 “I like beijing.”,经过处理后变为:“beijing. like I”。
    字符串长度不超过100。

    输入描述:
    输入一个仅包含小写字母、空格、‘.’ 的字符串,长度不超过100。
    ‘.’ 只出现在最后一个单词的末尾。

    输出描述:
    依次输出倒置之后的字符串,以空格分割。

    二、题目解析

    (一)解法1

    首先我们一起来分析分析这道题,‘将一句话的单词进行倒置,标点不倒置’,那么我们首先想到的可能就是从后往前将单词逆序拿出来,这种方法当然是行得通的,那我们就需要创建一个新的数组来存放取出来的单词,同时大家需要注意最后的‘.’不要忘记了。

    下面函数中调用了一个assert函数,我们需要在前方引用头文件
    它的用途是判断条件是否为真,在debug环境下可以当做 if语句来看待

    代码如下(示例):

    #include
    #include
    #include
    #include
    char* inv(const char str[], char arr[], const int sz) {
    assert(str && arr);//断言(判断)
    int right = sz - 1;
    int left = right;
    int i = 0;
    for (; right >= 0; right--) {
        if (str[right] == ' ' || right == 0) {
        //单词与单词之间都有空格间隔,遇到空格就讲它之后的单词复制到arr数组中
            if (right == 0)
                left = 0;
            else
                left = right + 1;
            do {
                arr[i++] = str[left++];//这样可以直接将空格也同时录入
                if (str[left] == '\0')
                    arr[i++] = ' ';
            } while (isalpha(arr[i - 1]));//中的函数,该字符是字母返回1,否则返回0
        }
    }
        arr[i] = '\0';
    return arr;
    }
    
    int main() {
    char str[101] = { 0 };//字符串长度不超过100,最后还有一个'\0'
    gets(str);//由于scanf遇到空格或者换行会停止读取数据,所以这里使用gets(读取字符串)
    char arr[101] = { 0 };
    int sz = strlen(str);//求字符串长度,不包括'\0'
    printf("%s\n", inv(str, arr, sz));
    return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    (二)解法2

    这里我们来认识一种很巧妙的方法,先将每个单词进行逆序,之后再将整个字符串进行逆序,这种方法还有一个优点就是:不用考虑空格与’\0’。

    代码如下(示例):

    void reverse(char str[], int left, int right) {
    	assert(str);
    	while (left <= right) {
    		char ch = str[left];
    		str[left] = str[right];
    		str[right] = ch;
    		left++;
    		right--;
    	}
    }
    
    int main() {
    	char str[101] = { 0 };
    	gets(str);
    	int sz = strlen(str);
    	int i = 0;//用来记录单词最后一个字母的下标(最后的句号也算在单词里)
    	int j = 0;//用来记录单词第一个字母的下标
    	for (i = 0; i <= sz; i++) {
    		if (str[i] == ' ' || str[i] == '\0') {
    			reverse(str, j, i - 1);//每个单词进行倒置
    			j = i + 1;
    		}
    	}
    	reverse(str, 0, sz - 1);//整个句子进行倒置
    	printf("%s\n", str);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    (三)解法3

    下面我们介绍一种“偷鸡”取巧的方法,通过递归,将每一个单词存在一个字符串中,倒序输出。

    代码如下(示例):

    void fun() {
    	char str[101] = { 0 };
    	if (scanf("%s", &str) != EOF) {//EOF一般是-1,当数据读取失败时会返回EOF,自行测试的时候按“Ctrl+z”结束
    		fun();
    	printf("%s ", str);//scanf遇到空格就停止读取,所以空格需要我们自行输出
    	}
    }
    
    int main() {
    	fun();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    总结

    以上就是熊猫对这个题目的理解,顺带一提:题解一的适用范围很小,甚至可以说只使用与题目这种情况,如果再增加其他字符那就很可能得不到我们想要的结果,而如果递归使用的不是那么精通的话,题解三是很难想到的,所以大家做题时尽可能地使用解法二。
    如果大家还有其他好的做法欢迎在评论区留言,大家的点赞与收藏在这里插入图片描述不断更新的动力,感谢大家的支持。

  • 相关阅读:
    spring框架有哪些优点呢?
    基于C++的RSA公钥加密算法实验
    Linux aarch64交叉编译之sqlite数据库
    04_面向对象
    分库分表(一)
    免费开箱即用微鳄OA办公系统
    [go学习笔记.第十六章.TCP编程] 1.基本介绍以及入门案例
    TCP通讯程序的编写
    SVPWM的原理及法则推导和控制算法详解
    卷积神经网络相比循环神经网络具有哪些特征
  • 原文地址:https://blog.csdn.net/m0_66363962/article/details/126213887