[剑指Offer]替换空格

今天看题的时候,遇到一个替换空格的题目,分析一下哈。

题目要求:把字符串中的每个空格替换成“%20”。例如输入“we are happy”,则输出“we%20are%20happy”。

解题思路:我们首先想到的是:移位思想。遇到空格就将空格后的所有字符后移两位,然后填充空格为%20。

实现代码

#pragma once
#include<assert.h>
#include<string.h>char* StrReplace(char* str,size_t length)
{assert(str && length > 0);char *p = str;char *p1 = str;size_t len = strlen(str)+1;size_t i = len;while(p){while(*p != ' '){p++;if(*p == '\0'){return str;}}while((p1+i) != p){*(p1+i+1) = *(p1+i-1);i--;}len+=2;i = len;*p = '%';*(p+1) = '2';*(p+2) = '0';p+=2;}return str;
}void Test()
{char str[20] = "we are happy";cout<<StrReplace(str,20)<<endl;
}

但是,我们再看看它的时间复杂度哈。显然,每次移位操作都是O(N),这样经过多次移位,使它的时间复杂度就变为O(N^2)。这样的效率实在有点低。我们如何提高它的时间复杂度呢?

思路2:我们可以用计数的方式,统计字符串中总共的空格数,然后从后向前移位,使用两个指针,p1指向字符串开始的位置,p2指向字符串尾部,移位将p2移动2*空格个数位,遇到空格后填充,直到两指针相遇,才停止移位。如图所示(移位过程):

这里写图片描述

实现代码

#pragma once
#include<assert.h>
#include<string.h>
char* StrReplace(char* str,size_t length)
{assert(str && length > 0);char *p = str;char *p1 = NULL;char *p2 = NULL;size_t len = strlen(str);int count = 0;//统计空格数while(*p != '\0'){if(*p == ' ')count++;p++;}count*=2;p1 = str+len;        //指向字符串尾p2 = str+len+count;  //指向修改后字符串正确的位置while(p1 != p2){if(*p1 == ' '){p2 -= 2;*p2 = '%';*(p2+1) = '2';*(p2+2) = '0';if(p1 != p)    //如果p1没有到字符串头时再减,防止越界{p1--;p2--;}}else              //不是空格则直接后移{*p2 = *p1;p1--;p2--;}}return str;
}void Test()
{char str[20] = "we are happy";cout<<StrReplace(str,20)<<endl;char str1[20] = " are happy";cout<<StrReplace(str1,20)<<endl;
}

执行结果

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言关键字 ISO/ANSI C90 C99 C11

面试考点 https://blog.csdn.net/csdn_kou/article/details/81113215 * 有的常用的我们都不知道是关键字&#xff0c;比如sizeof.这是面试中的考点&#xff0c;要注意。 * 同时当回答C语言中有多少关键字时&#xff0c;要回答前题条件&#xff0c;时针对哪一个版本

关于sudo

之前&#xff0c;我们使用sudo的时候&#xff0c;是因为其用户本身具有root权限&#xff0c;所以可以sudo后执行相关操作&#xff0c;但是对于普通用户来说&#xff0c;它是既不具有sudo权限&#xff0c;又不在sudo用户组中&#xff0c;那么我们来研究一下如何将新创建的用户添…

Bash入门

Bash简介&#xff1a; Bash&#xff08;GNU Bourne-Again Shell&#xff09;是一个为GNU计划编写的Unix shell&#xff0c;它是许多Linux平台默认使用的shell。 shell是一个命令解释器&#xff0c;是介于操作系统内核与用户之间的一个绝缘层。准确地说&#xff0c;它也是能力…

线程之售票系统pthread_mutex,_lock,_unlock

先看一下这篇文章 https://blog.csdn.net/csdn_kou/article/details/81148268 四个人同时买票票&#xff0c;引出线程 #include "head.h" int ticket 100; void * route(void *arg) {char *id (char *)arg;while(1){if(ticket>0){usleep(1000);printf("…

Bash基本语法

1. 变量赋值 a375 hello$a 这里需要注意的是&#xff0c;等号两边不能有空格 还有一个例子是这样的 例1&#xff1a; 结果为&#xff1a; 关于上述&#xff0c;主要有如下几点&#xff1a; $hello和${hello}是一样的&#xff0c;在bash中如果遇到空格&#xff0c;tab键时&a…

关于fd和fp(fd:file descirptor fp:file pointor)

通常&#xff0c;我们在输入数据或输出数据的设备为键盘或者显示器。当然&#xff0c;我们比较熟悉的输入输出&#xff0c;可能就是对于文件的操作&#xff0c;还有直接从终端输出&#xff0c;显示到显示器上。在C语言中&#xff0c;我们使用fopen,fclose,fread,fwrite对文件进…

[linux]wait详解

wait&#xff1a;进程等待 主要有两种等待方式&#xff1a;阻塞式等待和非阻塞式等待 阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;父进程将会一直等待着子进程运行结束&#xff0c;并且自己什么事都不干 非阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;…

[Linux]消息队列

我们知道进程间通信的方法有多种&#xff0c;主要有管道&#xff0c;消息队列&#xff0c;信号量&#xff0c;共享内存&#xff0c;socket等。之前介绍过管道&#xff0c;今天再介绍一个新的概念–消息队列。 消息队列&#xff1a;将一个进程到另一个进程之间发送数据块的方式…

C++关键字速查手册

[TOC] https://blog.csdn.net/csdn_kou/article/details/81113215 C98关键字 C11 关键字共73个 alignas alignof用于获取取指定表达式指定的&#xff08;类似sizeof&#xff0c;可以直接是类型名&#xff09;的对齐(alignment)。alignas用于声明时指定对齐类似于现有的类型…

[Linux]信号

Linux下的信号是一个什么概念呢。我们在现实生活中也遇到过信号之类的。比如红绿信号灯&#xff0c;班主任叫你去办公室并且脸色不好&#xff0c;诸如此类的都会给你一个信号。让你辨别事情的发生。同样&#xff0c;Linux下也有许多的信号&#xff0c;让你执行相应的操作。比如…

[数据结构]Map和Set

说起map和set&#xff0c;想必我们都学过红黑树了吧&#xff0c;map和set就是红黑树的一个应用领域。它的底层就是由红黑树来实现的。下面简单说一下map和set的使用吧。 首先&#xff0c;有一个栗子是这样的&#xff0c;让我们统计出每种水果出现的次数。 我们会想到怎么解决…

linux之信号

信号&#xff1a;在生活中&#xff0c;我们遇到过不同种类的信号&#xff0c;比如&#xff1a;&#xff08;交通信号&#xff0c;乃至某个人的表情&#xff0c;动作等带给你不同的信号&#xff09;然而&#xff0c;在我们的linux下&#xff0c;我们最熟悉的就是&#xff0c;当遇…

[Linux]继续探究mysleep函数(竞态条件)

之前我们探究过mysleep的简单用法&#xff0c;我们实现的代码是这样的&#xff1a; #include<stdio.h> #include<signal.h>void myhandler(int sig) {}unsigned int mysleep(unsigned int timeout) {struct sigaction act,oact;act.sa_handler myhandler;sigempt…

[Linux]死锁

死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局&#xff0c;当进程处于这种僵持状态时&#xff0c;若无外力作用&#xff0c;它们都将无法再向前推进。之前信号量的时候我们知道&#xff0c;如果多个进程等待&#xff0c;主要体现在占有锁的问题上。死锁也可以被定义…

[Linux]线程安全和可重入函数

线程安全&#xff1a;一个函数被称为线程安全的&#xff0c;当且仅当被多个并发进程反复调用时&#xff0c;它会一直产生正确的结果。如果一个函数不是线程安全的&#xff0c;我们就说它是线程不安全的。 重入&#xff1a;函数被不同的控制流程调用,有可能在第一次调用还没返回…

[Linux]信号量

信号量是一个计数器&#xff0c;用于为多个进程提供对共享数据对象的访问。 在信号量上只有三种操作可以进行&#xff0c;初始化、递增和增加&#xff0c;这三种操作都是原子操作。递减操作可以用于阻塞一个进程&#xff0c;增加操作用于解除阻塞一个进程。 为了获得共享资源…

[Linux]关于SIGCHLD

之前我们就学过&#xff0c;关于wait和waitpid来处理僵尸进程&#xff0c;父进程等待子进程结束后自己才退出&#xff0c;这样的方法有俩种方式&#xff0c;一种是父进程死死的等子进程退出&#xff0c;也就是使用阻塞的方式等待子进程退出&#xff0c;另一种方式是通过非阻塞的…

C语言思维导图

本人能力有限&#xff0c;知识点难免概括不全&#xff0c;如有错误欢迎指正

pthread和互斥量条件变量函数意义速查表

数据类型 pthread_t 线程 互斥量和条件变量