常见编程题


尝试多种方法实现:

1. 数组去重

`(1)ES5常用:利用for嵌套for,然后splice去重(两个null消失,NaN和{}没有去重)`
    function unique(arr) {
        for (var i = 0; i < arr.length; i++) {
            for (var j = i + 1; j < arr.length; j++) {
                if (arr[i] == arr[j]) { //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j, 1);
                    j--;
                }
            }
        }
        return arr;
    }
    var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,
        'NaN', 0, 0, 'a', 'a', {}, {}
    ];
    console.log(unique(arr))

`(2)ES6常用:Set去重(去重代码少。但是无法去除{}空对象。)`
function unique(arr) {
    return Array.from(new Set(arr))
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,'NaN', 0, 0, 'a', 'a', {}, {}
    ];

console.log(unique(arr))
 
`(3)indexOf去重(NaN、{}没有去重)`
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array = [];//新建空数组,for循环原数组,判断数组是否存在当前元素,如果相同的值跳过,不同push进数组
    for (var i = 0; i < arr.length; i++) {
        if (array.indexOf(arr[i]) === -1) {
            array.push(arr[i])
        }
    }
    return array;
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,'NaN', 0, 0, 'a', 'a', {}, {}
];
console.log(unique(arr))

`(4)sort()排序`
//排序后的结果,遍历对比
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    arr = arr.sort()
    var arrray = [arr[0]];
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] !== arr[i - 1]) {
            arrray.push(arr[i]);
        }
    }
    return arrray
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,
    'NaN', 0, 0, 'a', 'a', {}, {}
];
console.log(unique(arr))

`(5)hasOwnProperty (所有都去重) `
function unique(arr) {
    var obj = {};
    return arr.filter(function(item, index, arr){
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

`(6)filter({}没有去重、NaN两个都没有了)`
function unique(arr) {
    return arr.filter(function (item, index, arr) {
        //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
        return arr.indexOf(item, 0) === index;
    });
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, 	NaN, NaN,
    'NaN', 0, 0, 'a', 'a', {}, {}
];
console.log(unique(arr))

2. 字符串去空格

`方法1:(最常用)全部去除掉空格`
 var str = '  abc d e f  g ';
function trim(str) {
    var reg = /\s+/g;
    if (typeof str === 'string') {
        var trimStr = str.replace(reg,'');
    }
    console.log(trimStr)
}
trim(str)



`方法二:(强烈推荐)全部去除`
 
function trimAll(ele){
    if(typeof ele === 'string'){
       return ele.split(' ').join('');
           
    }else{
        console.error(`${typeof ele} is not the expected type, but the string type is expected`)
    }
  
}
 
trimAll(str)  // 1234456


`方法三:指定位置清楚空格(第二个参数控制位置)`
function deleSpac(str,direction) { // 1 串的模板 2 清除哪边空格
            if(typeof str !== 'string'){ // 限制下条件,必须是字符串
                 console.error(`${typeof ele} is not the expected type, but the string type is expected`)
                return false
            }
            let Reg = '';
            switch(direction) {
                case 'left' : // 去除左边
                    Reg = /^[\s]+/g;
                    break;
                case 'right' : // 去除右边
                    Reg = /([\s]*)$/g;
                    break;
                case 'both' : // 去除两边
                    Reg = /(^\s*)|(\s*$)/g
                    break;
                default :   // 没传默认全部,且为下去除中间空格做铺垫
                    Reg = /[\s]+/g;
                    break;
            }
            let newStr = str.replace(Reg,'');
            if ( direction == 'middle' ){
                let RegLeft = str.match(/(^\s*)/g)[0]; // 保存右边空格
                let RegRight = str.match(/(\s*$)/g)[0]; // 保存左边空格
                newStr = RegLeft + newStr + RegRight; // 将空格加给清完全部空格后的字符串
            }
            return newStr;
        }

3. 深拷贝(一种)

var obj = {
  name: "karen",
  its: [10, 20, 30]
} //[10,20,30,[90,100]]//null//"hello"//{x1:null,x2:new Date(),x3:"hello",son:{age:20}}
var obj2 = new Person()
function deepcopy(data) {
  if (typeof (data) == "object") {
    if (data.constructor == Date) {  //时间格式
      return new Date(data.getTime()) //返回一个新的时间对象
    } else if (data == null) {  
      return null
    } else if (data.constructor == RegExp) {  //正则表达式
      return new RegExp(data)
    } else if (data.constructor == Array) {
      var newArray = new Array()
      for (var i = 0; i < data.length; i++) {
        var temp = data[i]
        newArray.push(arguments.callee(temp)) //函数的自调用
      }
      return newArray
    } else {
      var newobj = new data.constructor() //构造函数,既可以拷贝成员,也不会让原型链上的方法丢失
      // Object.keys()  //这个方法也可以遍历对象,和下面的 for in一样都可以实现遍历
      for (var key in data) {
        newobj[key] = arguments.callee(data[key]) //函数的自调用
      }
      return newobj
    }
  } else {
    return data
  }
}
var obj2 = deepcopy(obj)
// console.log(obj2,obj==obj2,obj[3]==obj2[3])
console.log(obj2, obj == obj2, obj.its == obj2.its)

4. 防抖节流 (一种)

//防抖:在第一次触发事件时,不立即执行函数,而是给出一个限定值,比如200ms,然后:
//如果在200ms内没有再次触发事件,那么执行函数
//如果在200ms内再次触发函数,那么当前的计时取消,重新开始计时

//基础版
function debounce(fn, delay) {
    var timer = null;
    return function () {
        if (timer) clearTimeout(timer);
        timer = setTimeout(function () {
            fn();
        },delay)
    }
}

//优化版
function debounce(fn, delay) {
  var timer = null;
  return function() {
    if (timer) clearTimeout(timer);
    // 获取this和argument
    var _this = this;
    var _arguments = arguments;
    timer = setTimeout(function() {
      // 在执行时,通过apply来使用_this和_arguments
      fn.apply(_this, _arguments);
    }, delay);
  }
}





//节流:
//如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效

//基础版
    function throttle(fn, interval) {
        var last = 0;
        return function () {
            // this和arugments
            var _this = this;
            var _arguments = arguments;
            var now = new Date().getTime();
            if (now - last > interval) {
                fn.apply(_this, _arguments);
                last = now;
            }
        }
    }
//优化版
    function throttle(fn, interval) {
        var last = 0;
        var timer = null; // 记录定时器是否已经开启
        return function () {
            // this和arguments;
            var _this = this;
            var _arguments = _arguments;
            var now = new Date().getTime();
            if (now - last > interval) {
                if (timer) { //若已经开启,则不需要开启另外一个定时器了
                    clearTimeout(timer);
                    timer = null;
                }
                fn.apply(_this, _arguments);
                last = now;
            } else if (timer === null) { // 没有立即执行的情况下,就会开启定时器
                //只是最后一次开启
                timer = setTimeout(function () {
                    timer = null; // 如果定时器最后执行了,那么timer需要赋值为null
                    fn.apply(_this, _arguments);
                },interval)
            }
        }
    }

5. 计算素数

` 验证一个数字是不是素数/质数`
function primeNum(nub) {
    let n = parseInt(nub);
    // 声明变量num,初始值为true
    let isPrime = true;
    /* for循环里面的 i 变量初始值从2开始,去掉了可以整除的 1,把等号删掉,
    	可以去除它本身*/
    for(let i = 2; i < n; i++) {
        if(n % i == 0) {
        	/*走到这里,说明这个整数除了1和他本身之外,还可以被其他数整除,
        		isPrime变为false,同时终止循环*/ 
            isPrime = false;
            break;
        }
    }
    if(!isPrime) {
        console.log(n + ' 是合数')
    } else {
        console.log(n + ' 是质数')
    }
}
primeNum(7)

`求1到100以内素数`
for (var i=2;i<=100;i++) {
    //假设i是质数,
    var b=true;
    //求证的过程,在1到i之间有没有能被整数整除的数
    for (var j=2;j<i;j++) {
        if(i%j==0){
            //有数被整除了,就证明这个数不是质数
            b=false;
            break;
        }
    }
    if(b==true){
        document.write(i+"<br />")
    }
}

6. 判断是否平年闰年

var year = parseInt(prompt('请输入你的年份:'));
if ((year % 4 == 0 && !(year % 100 == 0)) || year % 400 == 0) {
    alert('闰年');
} else {
    alert('平年');
}

7. 找出字符串中指定字母下标 , 次数

`1、indexOf()查找指定字符串`
const str = 'abcdef';
console.log(str.indexOf('c'));					// 输出:2

`2、search()查找指定字符串`
const str = 'abcdef';
const reg = RegExp(/e/);
console.log(str.search(reg));					// 输出:4

`3、match()查找指定字符串`
const str = 'abcdef';
const reg = RegExp(/d/);
console.log(str.match(reg));

`js查找字符串中某个字符出现的位置和次数`
var str='sabdcpadhja';
var index=str.indexOf('a');
var num=0;
while(index!==-1){
    console.log(index)//打印出a的索引
    num++;//记录出现的次数
    index=str.indexOf('a',index+1); //利用index为索引,从index+1的位置开始找
}
console.log(num);

`统计一个字符串中,出现次数最多的字符,出现了多少次?`
`第一种方法`
var str = "zhaochucishuzuiduodezifu";
var o = {};
for (var i = 0, l = str.length; i < l; i++) {
    // var char = str[i];
    var char = str.charAt(i);
    if (o[char]) { //char就是对象o的一个属性,o[char]是属性值,o[char]控制出现的次数
        o[char]++; //次数加1
    } else {
        o[char] = 1; //若第一次出现,次数记为1
    }
}
console.log(o); //输出的是完整的对象,记录着每一个字符及其出现的次数
//遍历对象,找到出现次数最多的字符和次数
var max = 0;
var maxChar = null;
for (var key in o) {
    if (max < o[key]) {
        max = o[key]; //max始终储存次数最大的那个
        maxChar = key; //那么对应的字符就是当前的key
    }
}
console.log("最多的字符是" + maxChar); // 最多的字符是u
console.log("出现的次数是" + max); // 出现的次数是5

`第二种方法`
var testStr = 'zhaochucishuzuiduodezifu';
function fn1(str) {
    var strArr = str.split(''); // 把字符串分割成字符串数组
    var strJson = {};
    var maxLength = 0;//最长的长度
    var value = '';//字符值
    for (var i = 0; i < strArr.length; i++) {
        //没有就创建,每一个不同的字符都用一个数组来存放
        if (!strJson[strArr[i]]) {
            strJson[strArr[i]] = [];
        }
        strJson[strArr[i]].push(strArr[i]);// 把当前下标的值push进数组
    }
    //遍历json找到最长的
    for (var attr in strJson) {
        if (strJson[attr].length > maxLength) { // 经过比较得到最长的数组
            maxLength = strJson[attr].length; // 该数组的长度就是出现的次数
            value = attr;
        }
    }
    return '字符最多的是' + value + ',出现了' + maxLength + '次';
}
console.log(fn1(testStr)); // 字符最多的是u,出现了5次

8. 数组排序

`1.js中的sort()方法`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
function func(a,b){
	return a-b;
}
console.log(arr.sort(func)); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

`2.选择排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
for(var i=0;i<arr.length;i++){
	for(var j=i+1;j<arr.length;j++){
		//如果第一个比第二个大,就交换他们两个位置
		if(arr[i]>arr[j]){
			var temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

`3.冒泡排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
for(var i=0; i<arr.length-1; i++){
	//每一轮比较要比多少次
	for(var j=0; j<arr.length-1-i; j++){
	    //如果第一个比第二个大,就交换他们两个位置
	    if(arr[j]>arr[j+1]){
	        var temp = arr[j];
	        arr[j] = arr[j+1];
	        arr[j+1] = temp;
	    }
	}    
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

`4.插入排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
var preIndex, current;
for(var i=1;i<arr.length;i++){
	preIndex = i-1;
	current = arr[i];
	while(preIndex>=0 && arr[preIndex]>current) {
	    arr[preIndex+1] = arr[preIndex];
	    preIndex--;
	}
	arr[preIndex+1] = current;
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

`5.快速排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];	
//创建快速排序函数
function quickSort(tempArr){
	//递归终止条件
	if(tempArr.length<=1){
		return tempArr;
	};
	//取基准
	var pivotIndex = Math.floor(tempArr.length/2);
	var pivot = tempArr.splice(pivotIndex,1);
	//分左右
	var leftArr = [];
	var rightArr = [];
	for(var i=0;i<tempArr.length;i++){
		if(tempArr[i]>pivot){
			rightArr.push(tempArr[i]);
		}else{
			leftArr.push(tempArr[i]);
	    };
	};
	return quickSort(leftArr).concat(pivot,quickSort(rightArr));
};
console.log(quickSort(arr)); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值