js算法题

原创 2018年04月17日 21:11:46

1. == 与 === 的区别

①如果是两个相同类型的原始类型数据相比,==和===一样,都是比较他们的值。

②如果两个都是引用类型,==和===一样,都是看他们是否指向同一个对象。

③如果两个类型不同,===直接返回false,==会进行数据格式。如果是两个基本类型相比,==会把他们都转换为Number型,比较他们实际的值;如果是一个基本类型一个引用类型,则会调用引用类型的valueOf函数,得到他的原始值再与基本类型的数进行判断。

④null与undefined都与自身严格相等;但是null与undefined是普通相等。

注意下面这种情况也是相等的哦~

        var arr = ['a'];
        arr.valueOf = function(){
            return '1';
        };
        var num = 1;
        arr.toString = function(){
            return 'b';
        }
        console.log(arr == num);//true

会先调用arr的valueOf得到'1'这个字符串,再将字符串转成数值1与num进行比较。


2.实现add(1)(2)(3)

只有充分理解闭包,才能做对的一道题。

原本应该写成

       function add(x){
            return function(y){
                return function(z){
                    return x+y+z;
                }
            }
        }

但是当我再增加一个参数的时候,这个就又要再return,肯定是不可取的。

我们要做的是return出去一个函数,里面包含本次传来的参数:

        function add(x){
            var temp = function(y){
                return add(x+y);
            };
            return temp;
        };

由于我们要打印成字符串或是显示他原始值,因此我们需要:

            //JavaScript中,打印和相加计算,会分别调用toString(获得字符串)或valueOf(获得原始值)函数
            //所以我们重写tmp的toString和valueOf方法,返回sum的值
            temp.valueOf = temp.toString = function(){
                return x;
            }

完整的版本是:

        function add(x){
            var temp = function(y){
                return add(x+y);
            };
            //JavaScript中,打印和相加计算,会分别调用toString(获得字符串)或valueOf(获得原始值)函数
            //所以我们重写tmp的toString和valueOf方法,返回sum的值
            temp.valueOf = temp.toString = function(){
                return x;
            }
            return temp;
        };

3.验证素数

首先了解素数的含义:任何只能被1和自身整除的大于1的数。所以我们首先排除小于等于1的,其次搞清楚这个数如果再自己的一半这个数之前不能被整除,那他就永远不能被整除了,所以我们的循环只需要写到他的一半即可。

       function isPrime(n){
            if(n<=1) return false;
            for(var i=2; i<=n/2; i++){
                if(n%i === 0) return false;
            }
            return true;
        }

4.统计一个字符串出现最多的字母

首先我们需要声明一个对象,他的属性是传入字符串所拥有的字母,对应的值是字母重复的次数,最后我们通过比较出对象中最大值,找到字符串中重复次数最多的字母。得到对象可以通过先将字符串转化成数组,再使用forEach参数element、i、arr得到这个数组从i位之后是否还包含element。

       function count(str){
            var arr = str.split("");
            var obj = {};
            arr.forEach(function(element,i,arr) {
                obj[element] = obj[element]||0;
                if(arr.slice(i+1,arr.length).indexOf(element) !== -1){
                    obj[element]++;
                }
            }, this);
            var maxChar = '',maxValue = 1;
            for(var i in obj){
                if(obj[i]>=maxValue){
                    maxChar += i;
                    maxValue = obj[i];
                }
            };
            return maxChar;
        };

从其他地方看到一种获得对象的方法是通过charAt函数,此法不需要先把字符串转化为数组,很方便。

            let obj = {};
            for(var i=0; i<str.length; i++){
                if(!obj[str.charAt(i)]){
                    obj[str.charAt(i)] = 1;
                }else{
                    obj[str.charAt(i)] += 1;
                }
            }


5.数组从小到大或从大到小排列

冒泡排序:掌握一个重点,声明一个中间量,先将小的给中间量,再将大的给小的位置上,将中间量的值给大的位置,完成转换。

       function bubbleSort(arr){
            for(let i=0; i<arr.length; i++){
                for(let j=i+1;j<arr.length; j++){
                    if(arr[i]>arr[j]){
                        let temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
            return arr;
        }

插入排序:插入排序的重点是选取一个关键数,并将此数与他之前排着的已经排序完毕的数进行比较,如果一直比那些数小,则把关键数前面的一个数向后错一位,直到找到比关键数小的数,就把关键数插到这个数的后面。

       function insertSort(arr){
            for(let i=1; i<arr.length; i++){
                let temp = arr[i];
                let j= i-1;
                while(j>0 && arr[j]>temp){
                    arr[j+1] = arr[j];
                    j--;
                }
                arr[j+1] = temp;//注意是j+1不是j,因为你是要把temp插到小于他的数后面
            }
            return arr;
        }

快速排序:找到中间那个点并从数组中取出他,并将小于它的放在左边,大于他的放在右边,然后再对左右两个数组进行递归快速排序,直到这个数组只有中间一个值构成的数组时,就返回这个数组(这是最底层)。

       function quickSort(arr){
            if(arr.length<=1){
                return arr;//如果数组只有一个数,就直接返回;
            }

            var num = Math.floor(arr.length/2);//找到中间数的索引值,如果是浮点数,则向下取整
            var numValue = arr.splice(num,1);//找到中间数的值并取出他
            var left = [];
            var right = [];

            for(var i=0;i<arr.length;i++){
                if(arr[i]<numValue){
                    left.push(arr[i]);//基准点的左边的数传到左边数组
                }
                else{
                    right.push(arr[i]);//基准点的右边的数传到右边数组
                }
            }
            return quickSort(left).concat(numValue,quickSort(right));//递归不断重复比较
        }


6.实现类似getElementsByClassName 的功能

本题最重要的是要搞清楚className这个DOM属性,它的样子是"className1 className2……"可以选择两种方式。

首先是简单的分成数组进行判断:

       function getElementsByClassName(oEle,sClass){
            var aEle = oEle.getElementsByTagName('*');
            var arr = [];
            for(var i=0; i<aEle.length; i++){
                var arrClass = [];
                arrClass = aEle[i].className.split(" ");
                if(arrClass.includes(sClass)){
                    arr.push(aEle[i]);
                }
            }
            return arr;
        }

也可以使用正则:

        function getElementsByClassName(oEle,sClass){
            var aEle = oEle.getElementsByTagName('*'),
            //reg = new RegExp('(^|[ \n\r\t\f])'+sClass+'($|[ \n\r\t\f])'),
            //reg = new RegExp('(^|[ \s])'+sClass+'($|[ \s])'),
            //\n	匹配一个换行符
            //\r	匹配一个回车符
            //\t	匹配一个制表符
            //\f	查找换页符
            //\s与\n\r\t\f是等效果的,但是他不包括空格,所以需要加上空格
            arr = [];
            for(var i=0; i<aEle.length; i++){
                if(reg.test(aEle[i].className)){
                    //className是"myDic myDiv"这种形式
                    arr.push(aEle[i]);
                }
            }
            return arr;
        }

很多地方都能用到正则,正则帮助我们简化代码。

如果我们想获得url的某个参数的值,采用正则会非常简单:

        function getURL(name){
            let search = window.location.search,
            reg = new RegExp("[^&?]*"+name+"=([^&]*)","g"),//name前面0~无数个不为&或?的字符,后面0~无数个不为&的字符
            result = search.substring(1).match(reg);
            return result;
        }

如果我们使用split先根据&分再根据=分会很麻烦:

        function getParam(){
            //window.location.search是包括?的
            var search = window.location.search.substring(1);
            var arr = search.split("&");
            var obj = {};
            for(var i=0; i<arr.length; i++){
                obj[arr[i].split("=")[0]]=arr[i].split("=")[1];
            }
            return obj;
        };


7.实现一个去除字符串前后空格trim的函数

       function trim(str){
            //判断这个字符串的类型是否为string
            if(str&&typeof(str)==='string'){
                return str.replace(/^(\s)|(\s)$/g,"");
            }
        }


8.降维数组

我想的是使用扩展字符串...

        function Jw(obj){
            return [].concat(...obj);
        }

看到一个答案是使用Array.prototype.concat.apply,和我这个大同小异,只是一定要注意apply从第二个参数是作为参数的数组,数组中的每一项都是前面函数(concat)的参数。

        function Jw(obj){
            return Array.prototype.concat.apply([],obj);
        }


9.自定义一个bind函数

思想是先拿到此时的this,最后要返回一个函数,这个函数里要返回“改变this”

        Function.prototype.myBind = function(){
            var self = this;
            var content = Array.prototype.slice.call(arguments)[0];
            var args = Array.prototype.slice.call(arguments,1);
            return function(){
                return self.apply(content,args);
            }
        };
        var obj = {
            name:'Ann',
            getName: function(){
                return this.name;
            }
        };
        console.log(obj.getName());//Ann
        var getName2 = obj.getName;
        console.log(getName2());//空
        var getName3 = obj.getName.myBind(obj);
        console.log(getName3());//Ann

10.实现已经排序好的两个数组的排序合并

我犯了一个错误(i<a.length&&j<b.length)导致如果两个数组个数不一样就会扫不完长的那个。一定要扫完所有,所以需要判断:如果a已经扫完需要将b送进去,又或者a大于b而b也确实没扫完,此时也将b送进去。

       function mergeSortedArray(a,b){
            var arr = [],i=0,j=0;
            if(!a.length) arr=b;
            if(!b.length) arr=a;
            while(i<a.length||j<b.length){
                if(a[i]>b[j]&&j!==b.length||i===a.length){
                    arr.push(b[j]);
                    j++;
                }else{
                    arr.push(a[i]);
                    i++;
                }
            }
            return arr;
        }

11.实现单词翻转和字符翻转

单词只需要翻转一遍,通过空格将他们拆成一个一个数组:

        function reverseStr(str){
            var arr = str.split(" ");
            return arr.reverse().join(" ");
        }

字符反转需要翻转两遍,首先单词翻转,再整个句子翻转,实现内部字符翻转:

        function reverseWord(str){
            var arr = str.split(" ");
            return arr.reverse().join(" ").split("").reverse().join("");//反转两次
        }


12.查找这个数组中是否有两个数的和满足给定值

重点是扫到的每个数,将每个数与给定值的差值存入对象作为属性,接下来检测这个数是否是对象中的属性。

       function twoSum(arr,sum){
            var obj = {};
            for(var i=0; i<arr.length; i++){
                var n = sum-arr[i];
                if(!obj[n]){
                    obj[arr[i]]=true;
                }else{
                    return true;
                }
            }
            return false;
        }

面试题:十大经典算法总结(Javascript描述)

十大经典算法总结(Javascript描述) 应该是个96年的孩子写的,95的我要努力哦
  • yCharlee
  • yCharlee
  • 2016年09月24日 11:32
  • 1946

js面试算法

验证一个数是否是质数 质数只能被1和它自己整除,因此令被除数从2开始,若能整除则不是质数,若不能整除则加一,直到被除数到达根号n,此时n则是质数。 var isPrime = function(n...
  • crystal6918
  • crystal6918
  • 2017年03月09日 23:18
  • 2797

一道javascript算法面试题

实现一个数组内所有元素的和。 代码如下: function add(runningTotal, currentValue) { return runningTotal + currentValu...
  • ikscher
  • ikscher
  • 2014年12月30日 13:35
  • 2156

JS基础算法题解析

先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串。...
  • liu_pen
  • liu_pen
  • 2017年05月24日 17:53
  • 526

javascript编写acm算法题

我们都所知,acm算法题一般用c++或者java敲比较多。一个是效率搞,运行速度快,另外一个是处理输入输出比较简单。随着javascript语言的不断完善,我们如今也可以用js这门语言来实现算法题。作...
  • Szu_AKer
  • Szu_AKer
  • 2016年10月26日 13:59
  • 1604

一些经典算法的js实现方案

题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。function Fi...
  • qq_18663357
  • qq_18663357
  • 2017年01月18日 14:28
  • 1205

js 算法 面试常见的问题

JS 面试 前端找工作 算法 简单组件
  • bingyuewheel
  • bingyuewheel
  • 2017年02月04日 15:27
  • 653

JS面试常见算法题

学习数据结构与算法对于工程师去理解和分析问题都是有帮助的。如果将来当我们面对较为复杂的问题,这些基础知识的积累可以帮助我们更好的优化解决思路。下面罗列在前端面试中经常撞见的几个问题吧。 1.统计一个...
  • youjinli122
  • youjinli122
  • 2017年09月10日 15:45
  • 185

leetcode算法刷题-持续更新

最近,听了同学的建议准备刷leetcode的算法题目,提高下自己的算法能力。 不多说,直接来题: 一. Given an array of integers, return indices of ...
  • qq_34309305
  • qq_34309305
  • 2017年05月04日 13:43
  • 451

js简单算法练习(一)

前端工程师为什么要学习算法?没有这些,好像我们也可以做一些漂亮的工作。 实际上算法是一种我们如何去做事情的方式,而算法知识是对前人经验的总结,以及应对未来出现问题的无数种可能。算法不一定只有c或其他语...
  • wzdlovewen
  • wzdlovewen
  • 2016年09月09日 09:48
  • 952
收藏助手
不良信息举报
您举报文章:js算法题
举报原因:
原因补充:

(最多只允许输入30个字)