js算法1

五、js算法 

1.js随机生成10000个,长度为8 位的数字号码,找出所有靓号(AAAA,AABB,ABAB,并且后四位不含4 )

<script type="text/javascript">
    //这里是如何获取八位数
    function addNumber(){
        var str = '';
        for(var i = 0; i < 8; i += 1){
        str += Math.floor(Math.random() * 10);
        }
        return str;
    }
    console.log(addNumber());

    //蒋随机号码存入数组
    var addNum = function(){
        //要获取1000个 肯定要数组来存  但是我先用100个来实验  1000个就太恐怖了
        let arrNum = [];
        for(let i =0 ;i<100;i++){
            arrNum.push(addNumber());//存入数组中
        }
        return arrNum;
    }
    console.log(addNum());

    //然后开始对获取到的数组做处理  也就是找出靓号 照样要一个数组来存

    //第一步肯定是去掉后四位有4的数字呀

    var chooseNum = function(){
        const arrNum = addNum();//获取上一步拿到的数组
        for(let i of arrNum.keys()){//循环对每一个数组里面的数字做判断
            for(let j = 4 ;j<8;j++){
                if(arrNum[i][j]==4){
                    // console.log('4');//这里可以打印有多少个数字后四位存在4
                    arrNum.splice(i,1);//删掉这个数字
                    break;//退出循环
                }
            }
        }
        console.log(arrNum);//打印除掉后四位有4的数字
        //拿到后四位没有4的数字了  就可以开始做aabb aaaa  abab的判断了
        let endNum =[];//存储最后的数字
        for(let i of arrNum.keys()){
            if(arrNum[i][0]==arrNum[i][1]&&arrNum[i][1]==arrNum[i][2]&&arrNum[i][2]==arrNum[i][3]){
                // console.log(arrNum[i]);//有没有aaaa的呢
                endNum.push(arrNum[i]);
            }else if(arrNum[i][0]==arrNum[i][1]&&arrNum[i][2]==arrNum[i][3]){
                // console.log(arrNum[i]);
                endNum.push(arrNum[i]);
            }else if(arrNum[i][0]==arrNum[i][2]&&arrNum[i][1]==arrNum[i][3]){
                // console.log(arrNums[i]);
                endNum.push(arrNum[i]);
            }
        }
        return endNum;
    }
    console.log(chooseNum());
</script>

2. 写一个原型链继承的例子

//DOM封装查询
function Elem(id){
	this.elem = document.getElementById(id); 
}
Elem.prototype.html = function(val){
	var elem = this.elem;
	if(val){
		elem.innerHTML = val;
		return this;
	}else{
		return elem.innerHTML;
	}
}
Elem.prototype.on = function (type,fn){
	var elem = this.elem;
	elem.addEventListener(type,fn);
	return this;
}
var div1 = new Elem('div1');
div1.html('<p>hello world</p>').on('click',function(){
	alert('clicked');
}).html('<p>hello javascript</p>');

3.用js创建10个<a>标签,点击的时候弹出来对应的序号

var i;
for(i=0;i<10;i++){
	(function(i){
		var a = document.createElement('a');
		a.innerHTML = i + '<br>';
		a.addEventListener('click',function(e){
			e.preventDefault();
			alert(i);
		});
		document.body.appendChild(a);
	})(i);
}

4.获取2018-4-26格式的日期

function formatDate(dt){
    if(!dt){
        dt = new Date();
    }
    var year = dt.getFullYear();
    var month = dt.getMonth() + 1;
    var date = dt.getDate();
    if(month<10){
        month = '0' + month;    
    }
    if(date<10){
        date = '0' +date;
    }
    return year + '-' + month + '-' + date;
}
var dt = new Date();
var formatDate  = formatDate(dt);
console.log(formatDate);

5.写一个能遍历对象和数组的通用的forEach函数

function forEach(obj,fn){
    var key;
    if(obj instanceof Array){
        obj.forEach(function(item,index){
            fn(index,item);
        });
    }else{
        for(key in obj){
            fn(key,obj[key]);
        }
    }
}
var arr = [1,2,3];//数组
forEach(arr,function(index,item){
    console.log(index,item);
})
var obj = {x:1,y:2};//对象
forEach(obj,function(key,val){
    console.log(key,val);
})

6.冒泡排序

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

module.exports = bubbleSort;

//es6写法
let arr = [43, 32, 1, 5, 9, 22];
const sort = arr => {
    arr.forEach((v, i) => {
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] > arr[j]) {
                [arr[i],arr[j]] = [arr[j],arr[i]]
            }
        }
    })
    return arr
}
console.log(sort(arr))  // [1, 5, 9, 22, 32, 43]

7.字符串转驼峰 

var str="border-bottom-color";
function Change(str){
   var arr=str.split("-");
   for(var i=1;i<arr.length;i++){
      arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substring(1);
   }
   str=arr.join("");
   return str;
}
console.log(Change(str));//borderBottomColor

8.查找字符串中出现次数最多的字符和次数

解决方法一:
var str = "sdddrtkjsfkkkasjdddj";
var max = 0;
var char;
function Search(str) {
    var obj = {};
    for (var i = 0; i < str.length; i++) {
        if (!obj[str[i]]) {
            obj[str[i]] = str[i];
        } else {
            obj[str[i]] += str[i];
        }
    }

    for (var i = 0; i < str.length; i++) {
        if (obj[str[i]].length > max) {
            max = obj[str[i]].length;
            char = str[i];
        }
    }
    console.log("出现次数最多的字符是" + char + ",出现了" + max + "次")
}
Search(str);

解决方法二:
function repeatCharNum(str){
    var arr = str.split('');
    str = arr.sort().join('');
    var re = /(\w)\1+/g;
    var index = 0;
    var value = '';
    str.replace(re,function($0,$1){
        if(index < $0.length){
            index = $0.length;
            value = $1 ;
        }
    });
    alert ('最多字符'+value+'出现的次数'+index);
}

9.编写一个函数,将输入的参数中的数字字符追加为一个数字字符串,参数输入不确定

function getStrChange(){
  var len = arguments.length;//参数不确定时使用arguments关键字
  var re = /^\d+$/;
  var str = '';debugger;
  for(var i =0; i< len; i++){
    if(!(re.test(arguments[i]))){ 
      continue;
    }
    if(i == len-1){
      str = str+arguments[i];
    }else{
      str = str+arguments[i]+',';
    }  
  }
  return str;
}
alert(getStrChange('1','a','45','b','3',1));//('1,45,3,1')

10.JS 把url的参数解析成对象

function parseUrl(str) {
    // 判断是否传入参数
    if (str) {
        var obj = {};
        var queryArr = [];
        // 正则表达式规则
        var re = /^(http\w?):\/\/([0-9a-zA-Z\.]+)([a-zA-Z0-9\/]+)\?([a-zA-Z0-9\=\&]+)#([0-9a-zA-Z\.]+)/;
        // 利用正则表达式将字符串分组
        var reArr = re.exec(str);
        if (reArr) {
            obj.peotocol = reArr[1];
            obj.host = reArr[2];
            obj.path = reArr[3];
            queryArr = reArr[4].split(/[\&\=]+/);
            obj.query = {};
            for (var i = 0; i < queryArr.length; i += 2) {
                obj.query[queryArr[i]] = queryArr[i + 1];
            }
            obj.hash = reArr[5]
            return obj;
        } else {
            return null;
        }
    } else {
        return null;
    }
}

方法二:

// url参数解析
function getUrlkey(url) {
  var params = {};
  var urls = url.split("?");                  console.log('1_分割url:', urls)
  var arr = urls[1].split("&");               console.log('2_分割urls[1]:', arr)
  for (var i = 0, l = arr.length; i < l; i++) {
    var a = arr[i].split("=");                console.log('3_遍历 arr 并分割后赋值给a:', a[0], a[1])
    params[a[0]] = a[1];                      console.log('4_a给params对象赋值:', params)
  }                                           console.log('5_结果:', params)
  return params;
}

console.log(6,getUrlkey('http//aaa/txt.php?a=1&b=2&c=3'))

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

11.JS实现add(1)(2)(3)(4)的调用方式

第一种:

var add = function (m) {
    var temp = function (n) {
        return add(m + n);
    }
    temp.toString = function () {
        return m;
    }
    return temp;
};
 
add(3)(4)(5); // 12
add(3)(6)(9)(25); // 43

这个add函数可以无限次调用循环调用,并且把所有传进去的值相加,最后返回相加总数。这道题咋一看有点特别,但代码量极其少而精,重点技术在于:作用域、交替、匿名函数、toString的巧妙。
让我们来解释这个过程:add(3)(4)(5)
1、先执行add(3),此时m=3,并且返回temp函数;
2、执行temp(4),这个函数内执行add(m+n),n是此次传进来的数值4,m值还是上一步中的3,所以add(m+n)=add(3+4)=add(7),此时m=7,并且返回temp函数
3、执行temp(5),这个函数内执行add(m+n),n是此次传进来的数值5,m值还是上一步中的7,所以add(m+n)=add(7+5)=add(12),此时m=12,并且返回temp函数
4、关键性一步来了,后面没有传入参数,等于返回的temp函数不被执行而是打印,了解JS的朋友都知道对象的toString是修改对象转换字符串的方法,因此代码中temp函数的toString函数return m值,而m值是最后一步执行函数时的值m=12,所以返回值是12。
看到这其实就很明白了,代码中temp.toString的重写只是为了函数不执行时能够返回最后运算的结果值,所以这个地方是可以任意修改的,你让它返回什么它就返回什么,比如改写:

temp.toString = function () {
    return “total : ” + m;
}

 执行结果:add(3)(4)(5);  //total : 12

第二种:

function add(x) {
    var sum = x;
    var tmp = function (y) {
        sum = sum + y;
        return tmp;
    };
    tmp.toString = function () {
        return sum;
    };
    return tmp;
}
console.log(add(1)(2)(3)); //6
console.log(add(1)(2)(3)(4)); //10

首先要一个数记住每次的计算值,所以使用了闭包,在tmp中记住了x的值,第一次调用add(),初始化了tmp,并将x保存在tmp的作用链中,然后返回tmp保证了第二次调用的是tmp函数,后面的计算都是在调用tmp, 因为tmp也是返回的自己,保证了第二次之后的调用也是调用tmp,而在tmp中将传入的参数与保存在作用链中x相加并付给sum,这样就保证了计算;

但是在计算完成后还是返回了tmp这个函数,这样就获取不到计算的结果了,我们需要的结果是一个计算的数字那么怎么办呢,首先要知道JavaScript中,打印和相加计算,会分别调用toString或valueOf函数,所以我们重写tmp的toString和valueOf方法,返回sum的值。

12.js中0.1+0.2不等于0.3问题,解决方法

因为js使用的双精度浮点,所以在计算机内部存储数据的编码会出现误差,导致0.1+0.2=0.30000000000000004。和0.3相比较结果为false。
我目前所知道的解决方法有以下几种:
1.将其先转换成整数,再相加之后转回小数。具体做法为先乘10相加后除以10.如下图

 let x=(0.1*10+0.2*10)/10;
 console.log(x===0.3)

2.使用number对象的toFixed方法,toFixed方法可以指定运算结果的小数点后的指定位数的数字,使保留一位小数就是toFixed(1)。

//let x=(0.1+0.2).toFixed(1)
//因为使用toFixed方法将number类型转换成了字符串类型
//,所以使用parseFloat将字符串转回number类型
let x=parseFloat((0.1+0.2).toFixed(1));
console.log(x===0.3);

3.使用es6新增的Number.EPSILON方法,这个方法表示js的最小精度,使用这个方法通常只是对0.1+0.2是否=0.3做判断,并不像前两种改变0.1+0.2的值。

function equal(a, b) {
 	return Math.abs(a - b) < (Number.EPSILON ? Number.EPSILON : Math.pow(2, -52));
           //此处使用了三目运算符对IE进行兼容,也可以使用if(Number.EPSILON)进行兼容判断。
}
/*不考虑兼容
function equal(a,b){
   return Math.abs(a-b)<Number.EPSILON;
   //相当于把比较的boolean值返回
}
*/
console.log(equal(0.1 + 0.2, 0.3))

13.数组中两项之和等于某个固定值

算法一:遍历每一个元素,让指定值减去每一个元素,得到的数再进行判断是否有在该数组中,返回对应的索引

function addToTarget(arr,target){
    let result = []
    for (let i = 0; i < arr.length; i++) {
        const val = target - arr[i];
        //这里用slice(i + 1)截取i之后的字符串,避免取出重复数据
        const index = arr.slice(i + 1).indexOf(val); 
        if (index !== -1) {
            result.push([arr[i],val]);
        }
    }  
    return result

}
const arr = [1,4,5,3,8,9];
addToTarget(arr,13)

算法二: Map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值