js实现字符串中字符重复次数的大小排列输出(基础面试题二)
题目(较难):实现一个函数,如果传入的参数是字符串,则将该字符串按照字符出现的次数由大到小重新排列并输出;如果传入的参数不是字符串,则将参数返回。
关于对字符串处理的题目有很多,是否有同学觉得自己一直学不好,异或是看懂了,过段时间后又忘记了,始终记忆不起最重要的核心逻辑思想,那么是时候动动手了,边编程边思考,为什么要用这种逻辑。
分析:
1)首先,题目给出我们之后,我们便会想要用for循环找出相同的字母,但是却好像无法得知字母的次数
2)随后可能会想到,给它们排序(sort()方法),但是sort()方法是数组的方法,那怎么办?
3)进而联想到将字符串先转化为数组,处理完毕之后再转化回来
4)那该怎么转化成数组呢?用split()方法(字符串方法,输出为数组)好像可行,但是括号里面具有写什么呢?如果不写任何字符,那么返回的则是将整个字符串作为数组的第一个元素输出且数组只包含这一个元素;如果写',',那么输出与不写任何字符一样;那么写'',则字符串里的每个字符分开分别作为输出数组的元素。
5)处理完之后,应该再还原成字符串才行,应该用join()方法(数组方法,输出为字符串),而join()里面也只用写''就可以实现了,就可以得到一连串的字符串输出了
6)可是到底该怎么查找重复的字符呢?这个说实话比较不容易想出来,得对算法有一定的掌握才行,这道题是用正则实现的
代码如下:
function sortStringByCount(argc){
if (typeof(argc) !== "string" || argc.constructor !== String) {//constructor 属性返回所有 JavaScript 变量的构造函数
return argc;
}else{
dealtArgc = argc.split('').sort().join('');//将字符串分割输出数组,然后对数组排序,再转换成字符串
newStr = dealtArgc.match(/(.)\1{0,}/g).sort(function(a,b){//match输出的是数组形式,然后用sort排序,最后用join转成字符串
return b.length - a.length
}).join('');
return newStr;
}
}
console.log(sortStringByCount('asdasdasdasdasdasdfsdgdfgdfgdfgerter'));//ddddddddddsssssssaaaaaaffffggggeerrt
这里着重解释下正则吧,首先关于正则的使用手册可以参考链接:点击打开链接
\num匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符;连续两个相同的字符,知识点是 \1的 反向引用 ;
.匹配除“\n”之外的任何单个字符;
{n,}其中n是一个非负整数,至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o,即至少匹配2次。“o{1,}”等价于“o+”,至少匹配一次。“o{0,}”则等价于“o*”,不匹配或匹配多次。即 x{n,} 前面的模式 x 连续出现至少 n 次时匹配。
即/(.)\1{0,}/g这个表达要匹配的是:两个连续的字符,这种字符模式可以不存在或存在多次
那如果要匹配三个连续的字符呢?应该怎么写正则表达式呢?应该要这样写:/(.)\1{2,}/g。也就是说,比如这里有三个连续的字符ooo,那么匹配的时候是进行了两次,前面两个o匹配一次,后面两个o也匹配了一次。
下面把匹配到的字符放在了一个数组里面,因为match输出的是一个数组,但是这个数组还未排序
那么后面的sort()方法就是给数组排序,sort()方法里面是一个匿名函数,充当该怎么排序的依据。菜鸟教程里面给出的sort()方法是这样的,如果对数组使用数字排序,那么必须通过一个函数作为参数来调用,也就是代码中的匿名函数,然后函数指定数字是按升序还是降序排列。代码中匿名函数里面有两个参数,分别为a和b,匿名函数返回一个值,这个值决定是用升序还是降序排列数组,如果返回的是a-b,则数组按升序排序;如果返回的b-a,则按降序排列。具体可查看链接:sort()方法的使用
很明显,要按降序排序,所以返回b-a,由于数组中的元素是字符串,不是数字,所以应该用字符串的长度来表示,即返回b.length-a.length。
当然了,代码肯定不是最完备的,各种情况的输入都要考虑到,这里只给出了主要的逻辑处理方法
以上是对该题的分析与解答,不正之处请留言指正,题目出自微信公众号:较真的前端
上一篇: 关闭centos命令模式的警告声音
下一篇: 统计字符串中子串重复次数