c++反转字符
这是我在leetcode上看见的题目
尝试了几种写法,耗时均不同,这里先说一下第一种算法“交换法”
交换法反转字符就是从尾部一直向前挪移:
如:
abcd = dbca
这是第一次交换,第二次交换就是:
dcba
可以看到每次交换都是首位交换,以此向中心扩展,通俗易懂的说就是两者之间向中心点靠拢,每次交换会交换两个字符,所以交换时间是:o(s\2)
四个字符两次就可以完成反转
实现:
声明一个函数,这里leetcode使用的是vector容器,我们也一样.
void reverseString(std::vector& s) {
}
第二步编写一个循环:
注意循环条件是字符大小/2,因为上面说过每次交换是两个字符
for(int i = 0;i<(s.size()/2);++i){

}
这里我的写法为了省掉内存开辟空间以及内存交互的方式,使用加减法来保存要交换的字符,防止被覆盖,因为字符也是ascii码
s[i] += s[(s.size()-i)-1];
这里说一下这段代码
s[I]是指向从0开始的字符下标,比如abcd那么现在下标就是a
s[(s.size()-i)-1]
这段代码是算出字符尾部的坐标,每次-i是为了下一次的移动,比如现在是d,那么下次循环i是1,就是b与c的交换了.
最后的-1是为了跳过\0,c/c++里对字符结尾的定义是\0,不能把\0放到首位,如果\0在首位c/c++会认为这就是这段字符的结束.
这里+=是为了存储第一位的值,比如a的ascii是97,d的ascii码是100,那么相加就是197
此时s[i]=197相当于保存了两个字符
s[(s.size()-i)-1] = s[i] - s[(s.size()-i)-1];
这段代码就是把末尾的值减去s[i],也就是197-d的ascii码就等于了a的ascii码,这样尾部就有了a
同时还需要把首部的值在减去末尾的值,因为末尾的值刚好是a,那么197-a的ascii码就等于了d
s[i] -= s[(s.size()-i)-1];
完整代码:
void reverseString(std::vector& s) {
for(int i = 0;i<(s.size()/2);++i){
s[i]+=s[(s.size()-i)-1];
s[(s.size()-i)-1] = s[i] - s[(s.size()-i)-1];
s[i] -= s[(s.size()-i)-1];
}
}

可惜力扣那边测试,我们的算法还是比较慢的,这里就要想想别的办法,因为我们上面的算法造成了一部分的计算,还有内存数据交换,还是比较耗时的
c++内置了一种函数move,这个函数的用法是直接将一个值变成左值,也就是立即数的方式,直接跟着指令集去运算,那么就可以直接不用内存的方式去做这些工作了
比如:
int a = 10;
Int b = 0;
b = a;
如果想要让b=a,cpu需要到a的内存里取数据,复制一份数据然后再到b的内存地址里,把数据写入
这个过程比较繁琐,但是move不一样,这个函数可以把a里的值直接变成左值返回
b = std::move(a)
则变成了:b = 10;
如果不实用move则会翻译成:b = &a;
这里不用指令集的方式表示,这样表示更加的直观,
汇编的方式就是:
move方式:
mov byte ptr ds:[b],10
非move方式:
mov ax, byte ptr ds:[a] //取出a的值
mov byte ptr ds:[b],ax //放入b中
这里汇编是大致写了一下,详细可以去返汇编看一下
我们修改一下代码加上move试试:
for(int i = 0;i<(s.size()/2);++i){
s[i]+=std::move(s[(s.size()-i)-1]);
s[(s.size()-i)-1] = std::move(s[i] - s[(s.size()-i)-1]);
s[i] -= std::move(s[(s.size()-i)-1]);
}
看下力扣测试:

速度一下快了很多,也证实了我们上面说的.有时候算法固然重要,但是编译优化也很重要,很多硬件加速就是这样的方法,使用一些特定的指令集.
上面这套算法因为有了move的方式,可以省略内存访问,这里我们就完全没必要在进行运算了,直接用一个内存变量来存储临时的值:
char _c = s[i];
s[i] = std::move(s[(s.size()-i)-1]);
s[(s.size()-i)-1] = std::move(_c);
因为不用计算,也不用去取地址,看一下力扣的测试:

如果你想更懒一点,你可以使用swap函数直接实现,不过这样就丢失了这道题的意义了.
for(int i = 0;i<(s.size()/2);++i){
std::swap(s[i],s[(s.size()-i)-1]);
}
Move的方式就是我在查阅c++的代码时找到的加速方法,因为我发现c++提供的一些函数,或是c,提供的一些基础函数总是比我们自己写的要快,我一开始以为是他们的算法比较好,后来我去查阅了一些glibc的代码和c++的一些实现,发现内部内嵌汇编极多,都是使用汇编优化,还有一些编译器指令优化比如move,虽然说可以调整优化编译器等级,但是这些细节往往是最重要的.
Swap函数的实现:
template inline
void _Swap(_Ty& _Left, _Ty& _Right)
{ _Ty _Tmp = std::move(_Left);
_Left = std::move(_Right);
_Right = std::move(_Tmp);
}

注意c++的实现里有一个inline声明,这是一个类似c语言的宏展开的声明
比如你的函数add
前面加上inline声明以后,你在别处调用的时候,会直接变成实现代码,省去了函数调用的栈保存地址跳转等等开销. 这是c++特有的关键字

c++反转字符,算法优化与实现相关推荐

  1. 【整数反转】算法优化笔记

    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1:输入: 123输出: 321示例 2:输入: -123输出: -321示例 3:输入: 120输出: 21 假设我们 ...

  2. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)

    目录 一.BF算法(暴力算法) 二.KMP算法 三.KMP算法优化 一.BF算法(暴力算法) 一个一个往后匹配,匹配失败继续从母串下一个和头(子串的头)往后继续匹配. 虽然简单,但是需要较多的时间复杂 ...

  3. 校园地图设计——任意两点间的算法优化流程与while搭配switch语句的bug解读

    建议大家看着篇文章之前,先把我的校园地图设计那篇文章了解一下,这篇文章是阐述程序设计中存留的优化问题 话不多说,先上代码 /输出任一两点间的最短路径与长度 void Dispath(int dist[ ...

  4. C语言实现井字棋游戏(含算法优化)

    目录 序言 代码1 小结 算法优化 代码2 总结 序言 井字棋 英文名叫Tic-Tac-Toe 想必大家对这个小游戏都不陌生了 无论是小时候课堂上被画的全是"井"字的草稿纸 还是长 ...

  5. deeplearning算法优化原理

    deeplearning算法优化原理 目录 • 量化原理介绍 • 剪裁原理介绍 • 蒸馏原理介绍 • 轻量级模型结构搜索原理介绍 Quantization Aware Training量化介绍 1.1 ...

  6. 蚁群算法优化神经网络matlab源程序,粒子群优化神经网络的程序大集合

    粒子群程序集合 866867259psobp psobp.m pso(粒子群算法)优化神经网络 粒子群算法(PSO)应用于神经网络优化[matlab] PSOt A Particle Swarm Op ...

  7. MAT之PSO:利用PSO算法优化二元函数,寻找最优个体适应度

    MAT之PSO:利用PSO算法优化二元函数,寻找最优个体适应度 目录 实现结果 设计代码 实现结果 设计代码 figure [x,y] = meshgrid(-5:0.1:5,-5:0.1:5); z ...

  8. 初等数论--同余--MILLER-RABIN素性检测算法优化

    初等数论--同余--MILLER-RABIN素性检测算法优化 Euler theorem.Fermat's little theorem Primality Test: Fermat.MILLER-R ...

  9. 群友福利 | 55 本《AI 嵌入式系统: 算法优化与实现》免费送

    一年春至,同学们开始陆续返回校园,上班党也在欢天喜地的 "逗利是" 中开启了新一年的打工生活. 为了回馈广大开发者的大力支持,和广大开发者一起成长的极术社区为大家带来了壬寅虎年的第 ...

最新文章

  1. Unable to start activity ComponentInfo
  2. python语法怎么读-python怎么读sql数据?
  3. Java多线程之死锁编码及定位分析
  4. notepad php源码,GitHub - CharlesKiki/Web-Notepad: 这是一个仿制有道云笔记的原生PHP小玩具。...
  5. mysql 修改密码演练
  6. 软件测试计划包括哪些内容,测试计划如何编写。分享测试计划模板
  7. android获取网络时间工具类,Android检测网络接口访问速度,ping接口获取访问时间平均值...
  8. android preference-headers 字体颜色,如何修改CheckBoxPreference 中title ,summary字体的颜色...
  9. 自动化专业好找工作吗?就业方向是什么?
  10. dd 删除引导扇区_硬盘U盘数据怎么用bootice彻底删除及清零引导记录教程
  11. mysql哨兵模式_redis 哨兵模式集群搭建
  12. 关于gitlab Web IDE功能使用
  13. 在c的基础上关于c#入门的一些个人理解
  14. android开发 自定义锁屏界面,插件锁屏桌面自定义 “安卓4.0”界面美化教程
  15. mysql gbk排序规则_Mysql 字符集及排序规则
  16. 雷军给陈年总结的小米十条经验
  17. QQ网络存储随便用(原创)
  18. 淘宝API获取——商品详情信息、DESC信息、主图
  19. python分析:爬取《灵笼》这部国产动漫弹幕,分析词云!看看网友究竟在说啥?
  20. 基于Matlab的载波同步建模与仿真(科斯塔斯环)

热门文章

  1. java实现红包要多少钱_Java实现抢红包功能
  2. 神通数据库打开服务_数据库周刊30丨数据安全法草案将亮相;2020数据库产业报告;云南电网上线达梦;达梦7误删Redo…...
  3. python中质数的表达方式_python求质数的3种方法
  4. vue一个页面用两个以上页面 时时刷新
  5. 计算机c语言在线课堂,计算机(C语言)
  6. MySQL数据库反向生成powerdesigner模型
  7. matlab find返回空集,Model.find()在猫鼬中返回空
  8. python通信原理实验报告_【Python之旅】第五篇(一):Python Socket通信原理-阿里云开发者社区...
  9. 高中计算机学ppt吗,高中信息技术人工智能教学培训课件选修5ppt
  10. pythontransform详解_Python自定义聚合函数merge与transform区别详解