一道很经典的算法题,统计字符串里面出现次数最多的字符以及出现的次数!
对于算法题,我觉得最要的是思维模式,而不是解决的过程,同一种思维模式下也会出现不同的解题过程,首先以我们人的统计方式会怎样解决这个问题呢?那肯定是用记录的方式,也就是把不同的字符串放到不同的容器中,最后统计那个容器中的字符最多不就实现了吗?话说起来容易,但是计算机是不懂人的思维的呀,那我们接下来就用代码来实现我们刚刚的思路。
首先我们先封装一个函数,最后调用这个函数,传入我们要统计的字符串就OK了
function count(str){
}
console.log(count("qzaqawsxda"));
在函数里面我们先使用字符串的切割方法,把该字符串切割为一个数组,并用一个变量s来接收。随后再定义一个变量r来得到数组去重的结果,我们知道Set容器对数组有去重的作用,在我们去重之后我们用数组展开运算符再将其变为数组就可以了
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
}
到了这一步我们已经拿到了所有的数组项数组,以及所有的不重复的数组项数组,那这有什么用呢?别着急,咱们慢慢来
接下来我们声明一个空对象t,并做一个循环进行一个操作
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
let t={}
for (let i = 0; i < r.length; i++) {
t[i]=[]
}
}
那这是什么意思呢?还记得最开始我提到过的用人的思想去解决问题是把不同的字符放到不同的容器里面,那么经过去重之后的数组长度就是不同容器的总个数,就是这个数组有多少个数组项,我们就得准备多少个容器。那我们就循环该数组,每一次都添加一个不同的容器,以对象的属性进行添加。到了这一步,我们的容器就准备好了,接下来就是往容器里面扔东西了。
可东西该怎么扔进去呢!在这里我用了一个双重for循环
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
let t={}
for (let i = 0; i < r.length; i++) {
t[i]=[]
}
for (var i = 0; i < r.length; i++) {
for (var j = 0; j < s.length; j++) {
if(r[i]==s[j]){
t[i].push(s[j])
}
}
}
我们都知道for循环的机制就是外层走一次,内层走一圈,那我们就可以利用这个机制来实现对比效果,外层的数组是去重的数组,所以我们拿它的每一项依次和原数组(未去重数组)进行比较,如果出现了等于的情况,就把未去重数组里面和去重数组相等的这项追加到t对象的i属性里面,i属性在上面我们就已经定义了是空数组,所以放心追加。
追加完以后我们打印对象t
可以看到t对象的每个属性都是一个数组,并且每个数组都是我们分类好的,相同的字符才在一个数组里面,到了这一步基本就已经看到答案了。但是这样展示并不直观,我们要找最多次数的,当然要把它放在第一位,这样我们一眼就能看到,采用对象的Object.values(t)方法,将对象的所有属性值组成一个数组val
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
let t={}
for (let i = 0; i < r.length; i++) {
t[i]=[]
}
for (var i = 0; i < r.length; i++) {
for (var j = 0; j < s.length; j++) {
if(r[i]==s[j]){
t[i].push(s[j])
}
}
}
let val=Object.values(t)
}
然后利用数组的sort方法对val进行降序排列,由于val里面不是纯粹的数字,所以我们无法使用a-b和b-a来进行排序。所以只能使用它们的长度来进行对比来排序
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
let t={}
for (let i = 0; i < r.length; i++) {
t[i]=[]
}
for (var i = 0; i < r.length; i++) {
for (var j = 0; j < s.length; j++) {
if(r[i]==s[j]){
t[i].push(s[j])
}
}
}
let val=Object.values(t)
val.sort((a,b)=>b.length-a.length)
}
此时的数组val已经变成了这样
此时我们可以看到已经从数组的长度由从长到短进行了排序。随后使用map方法将其每个数组的第一项和长度返回出来即可
function count(str){
let s=str.split("")
let r=new Set(s)
r=[...r]
let t={}
for (let i = 0; i < r.length; i++) {
t[i]=[]
}
for (var i = 0; i < r.length; i++) {
for (var j = 0; j < s.length; j++) {
if(r[i]==s[j]){
t[i].push(s[j])
}
}
}
let val=Object.values(t)
val.sort((a,b)=>b.length-a.length)
return val.map((item,index)=>`${item[0]}累计出现${item.length}次`)
}
最后打印看看效果吧!
算法题最重要的是思路,这得长期锻炼才行,各位觉得有用的话就点个赞吧!