字符串反转_JavaScript


Posted in Javascript onApril 28, 2016

今天在freeCodeCamp上面刷题,碰到一题是有关于字符串反转。反转一个字符串是JavaScript中常见的面试题之一。可能面试官会给你一个字符串“Hello Word!”,让你通过JavaScript的方法,将其变成"!droW olleH"。

我也是初学者,利用前面所学数组相关的知识以及题目的提示,我算是过关了,后来想,是不是还有其他的方法能破此题呢?搜索了一下,还是有不少的方法,这里把这些方法罗列一下,以备后面可以使用。

要做的事情

我们要做的事情:

将提供的字符串反向显示在反向字符串之前,需要将字符串转化成一个数组最终结果依旧是一个字符串

接下来,我们一起看看有哪些方法能实现上述要求。

使用内置函数

在练习题中,提示我们可以使用三种方法配合,能顺利让一个字符串反向显示:

String.prototype.split()Array.prototype.reverse()Array.prototype.join()

简单的过一下:

split()方法将一个字符串对象的每个字符拆出来,并且将每个字符串当成数组的每个元素reverse()方法用来改变数组,将数组中的元素倒个序排列,第一个数组元素成为最后一个,最后一个变成第一个join()方法将数组中的所有元素边接成一个字符串

来看个实例:

function reverseString(str)
 { // 第一步,使用split()方法,返回一个新数组 
// var splitString = "hello".split(""); 
var splitString = str.split(""); 
//将字符串拆分 // 返回一个新数组["h", "e", "l", "l", "o"] 
// 第二步,使用reverse()方法创建一个新数组 
// var reverseArray = ["h", "e", "l", "l", "o"].reverse(); 
var reverseArray = splitString.reverse(); 
// 原数组元素顺序反转["o", "l", "l", "e", "h"] 
// 第三步,使用join()方法将数组的每个元素连接在一起,组合成一个新字符串 
// var joinArray = ["o", "l", "l", "e", "h"].join(""); 
var joinArray = reverseArray.join(""); // "olleh" 
// 第四步,返回一个反转的新字符串 return joinArray; 
// "olleh"}reverseString("hello"); 
// => olleh

将上面的方法简化一下,可以写成这样:

function reverseString(str) {
 return str.split("").reverse().join("");
}reverseString("hello"); 
// => olleh

使用一个递减循环遍历将字符串反转

这种方法使用的是一个for循环给原字符串做一个递减遍历,然后将遍历的字符串重新合并成一个新字符串:

function reverseString(str) { 
// 第一步:创建一个空的字符串用来存储新创建的字符串 var newString = ""; 
// 第二步:使用for循环 
// 循环从str.length-1开始做递减遍历,直到 i 大于或等于0,循环将继续
 // str.length - 1对应的就是字符串最后一个字符o for (var i = str.length - 1; i >= 0; i--) {
 newString += str[i]; // 或者 newString = newString + str[i]; } 
// 第三步:返回反转的字符串 return newString; }reverseString('hello'); 
// => // "olleh"

简单的看看字符串遍历的过程。假设需要将字符串"hello"反转。其整个遍历过程如下表所示:

迭代顺序 对应i的值 新字符串 newString 每次迭代 str.length - 1 newString + str[i] 第一次迭代 5 - 1 = 4 "" + "o" = "o" 第二次迭代 4 - 1 = 3 "o" + "l" = "ol" 第三次迭代 3 - 1 = 2 "ol" + "l" = "oll" 第四次迭代 2 - 1 = 1 "oll" + "e" = "olle" 第五次迭代 1 - 1 = 0 "olle" + "h" = "olleh"

其实上面的for循环,也可以换成while循环:

function reverseString (str) {
 var newString = '';
 var i = str.length; while (i > 0) {
 newString += str.substring(i - 1, i);
 i--; 
} 
return newString;}reverseString("hello"); 
// => olleh

while循环中substring()方法。substring() 返回字符串两个索引之间(或到字符串末尾)的子串。

使用递归实现字符串反向

使用String.prototype.substr()String.prototype.charAt()方法也可以将一个字符串反向。

substr() 方法返回字符串中从指定位置开始到指定长度的子字符串。比如:

var str = "abcdefghij";
console.log("(1,2): " + str.substr(1,2));
 // (1,2): bcconsole.log("(-3,2): " + str.substr(-3,2));
 // (-3,2): hiconsole.log("(-3): " + str.substr(-3)); 
// (-3): hijconsole.log("(1): " + str.substr(1)); 
// (1): bcdefghijconsole.log("(-20, 2): " + str.substr(-20,2)); 
// (-20, 2): abconsole.log("(20, 2): " + str.substr(20,2)); 
// (20, 2):

charAt() 方法返回字符串中指定位置的字符。字符串中的字符从左向右索引,第一个字符的索引值为 0,最后一个字符(假设该字符位于字符串 stringName 中)的索引值为 stringName.length - 1。 如果指定的 index 值超出了该范围,则返回一个空字符串。

var anyString = "Brave new world";
console.log("The character at index 0 is '" + anyString.charAt(0) + "'"); 
// =>The character at index 0 is 'B'console.log("The character at index 1 is '" + anyString.charAt(1) + "'"); 
// =>The character at index 1 is 'r'console.log("The character at index 2 is '" + anyString.charAt(2) + "'"); 
// =>The character at index 2 is 'a'console.log("The character at index 3 is '" + anyString.charAt(3) + "'"); 
// => The character at index 3 is 'v'console.log("The character at index 4 is '" + anyString.charAt(4) + "'"); 
// => The character at index 4 is 'e'console.log("The character at index 999 is '" + anyString.charAt(999) + "'"); 
// => The character at index 999 is ''

结合起来,我们可以这样做实现字符串反向:

function reverseString(str) { if (str === "") { 
return ""; } else { 
return reverseString(str.substr(1)) + str.charAt(0); }
}reverseString("hello"); 
// => olleh

第一部分的递归方法。你需要记住,你不会只调用一次,你将会有几个嵌套的调用。

每次调用str === "?" reverseString(str.subst(1)) + str.charAt(0) 第一次调用 reverseString("Hello") reverseString("ello") + "h" 第二次调用 reverseString("ello") reverseString("llo") + "e" 第三次调用 reverseString("llo") reverseString("lo") + "l" 第四次调用 reverseString("lo") reverseString("o") + "l" 第五次调用 reverseString("o") reverseString("") + "o"

第二部分的递归方法。

每次调用 返回 第五次调用 reverseString("") + "o" = "o" 第四次调用 reverseString("o") + "l" = "o" + "l" 第三次调用 reverseString("lo") + "l" = "o" + "l" + "l" 第二次调用 reverserString("llo") + "e" = "o" + "l" + "l" + "e" 第一次调用 reverserString("ello") + "h" = "o" + "l" + "l" + "e" + "h"

上面的方法还可以继续改良一下,改成三元操作符

function reverseString(str) { 
return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);}
reverseString("hello"); 
// => olleh

还可以换成这样的方式

function reverseString(str) { 
return str && reverseString(str.substr(1)) + str[0];
}reverseString("hello");
 // => olleh

其他方法

除了上面的方法之外,其实还有其他一些方法:

方法一

function reverseString (str) { var newString = []; for (var i = str.length - 1, j = 0; i >= 0; i--, j++) { newString[j] = str[i]; } return newString.join('');}reverseString("hello"); // => olleh
方法二
function reverseString (str) { for (var i = str.length - 1, newString = ''; i >= 0; newString += str[i--] ) { } return newString;}reverseString("hello"); // => olleh
方法三
function reverseString (str) { function rev(str, len, newString) { return (len === 0) ? newString : rev(str, --len, (newString += str[len])); } return rev(str, str.length, '');}reverseString("hello"); // =>olleh
方法四
function reverseString (str) { str = str.split(''); var len = str.length, halfIndex = Math.floor(len / 2) - 1, newString; for (var i = 0; i <= halfIndex; i++) { newString = str[len - i - 1]; str[len - i - 1] = str[i]; str[i] = newString; } return str.join('');}reverseString("hello"); // => olleh
方法五
function reverseString (str) { if (str.length < 2) { return str; } var halfIndex = Math.ceil(str.length / 2); return reverseString(str.substr(halfIndex)) + reverseString(str.substr(0, halfIndex));}reverseString("hello"); // =>olleh
方法六
function reverseString(str) { return [].reduceRight.call(str, function(prev, curr) { return prev + curr; }, '');}reverseString("hello"); // =>olleh
ES6的方法

在ES6中,可以变得更为简单一些,如:

[...str].reverse().join('');

[...str].reduceRight( (prev, curr) => prev + curr );

或者:

const reverse = str => str && reverse(str.substr(1)) + str[0];

字符串反转是一个小而简单的算法,前面也说了,常被用来面试JavaScript基础。你可以使用上面各种方法来解决这个问题,甚至使用更为复杂的解决方案。如果你有更好的方法,欢迎在下面的评论中补上,与我们一起分享。

Javascript 相关文章推荐
javascript 打印页面代码
Mar 24 Javascript
javascript 有用的脚本函数
May 07 Javascript
CSS和Javascript简单复习资料
Jun 29 Javascript
javascript onmouseout 解决办法
Jul 17 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
Nov 11 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
Jan 23 Javascript
编写高性能Javascript代码的N条建议
Oct 12 Javascript
js 获取经纬度的实现方法
Jun 20 Javascript
浅析Node.js非对称加密方法
Jan 29 Javascript
详解Vue中使用插槽(slot)、聚类插槽
Apr 12 Javascript
简述vue-cli中chainWebpack的使用方法
Jul 30 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
Sep 30 Javascript
使用 stylelint检查CSS_StyleLint
Apr 28 #Javascript
基于BootStarp的Dailog
Apr 28 #Javascript
浅析jquery与checkbox的checked属性的问题
Apr 27 #Javascript
JavaScript 消息框效果【实现代码】
Apr 27 #Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
Apr 27 #Javascript
js实现人民币大写金额形式转换
Apr 27 #Javascript
javascript实现不同颜色Tab标签切换效果
Apr 27 #Javascript
You might like
php实现的在线人员函数库
2008/04/09 PHP
PHP 将逗号、空格、回车分隔的字符串转换为数组的函数
2012/06/07 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
CI框架整合smarty步骤详解
2016/05/19 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
2017/05/08 PHP
用js自动判断浏览器分辨率的代码
2007/01/28 Javascript
JS 日期验证正则附asp日期格式化函数
2009/09/11 Javascript
javascript之Partial Application学习
2013/01/10 Javascript
js 调用父窗口的具体实现代码
2013/07/15 Javascript
jquery.cookie() 方法的使用(读取、写入、删除)
2013/12/05 Javascript
jqGrid读取选择的多行的某个属性代码
2014/05/18 Javascript
JavaScript模拟深蓝vs卡斯帕罗夫的国际象棋对局示例
2015/04/22 Javascript
js实现四舍五入完全保留两位小数的方法
2016/08/02 Javascript
H5实现中奖记录逐行滚动切换效果
2017/03/13 Javascript
原生JS封装animate运动框架的实例
2017/10/12 Javascript
AngularJS创建一个上传照片的指令实例代码
2018/02/24 Javascript
浅谈vue.js导入css库(elementUi)的方法
2018/03/09 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
python如何获取服务器硬件信息
2017/05/11 Python
python中import reload __import__的区别详解
2017/10/16 Python
Python定时器实例代码
2017/11/01 Python
python实现对任意大小图片均匀切割的示例
2018/12/05 Python
python接口调用已训练好的caffe模型测试分类方法
2019/08/26 Python
Python模块 _winreg操作注册表
2020/02/05 Python
python序列类型种类详解
2020/02/26 Python
keras K.function获取某层的输出操作
2020/06/29 Python
Python sublime安装及配置过程详解
2020/06/29 Python
Lookfantastic德国官网:英国知名美妆购物网站
2017/06/11 全球购物
过滤器的用法
2013/10/08 面试题
自动化专业毕业生自荐信
2013/11/01 职场文书
工作疏忽检讨书
2014/01/25 职场文书
关于期中考试的反思
2014/02/02 职场文书
年终晚会主持词
2014/03/25 职场文书
乡镇领导干部个人对照检查材料思想汇报
2014/09/23 职场文书
2014年中学生检讨书大全
2014/10/09 职场文书
CSS font-variation 可变字体的魅力(实例详解)
2022/03/03 HTML / CSS