前端常见算法

1、获取一个给定字符串中出现次数最多的字符及其出现次数

	function getLongsetStr(str) {
		var length = str.length;
		var strToNum = {};
		//以key-value形式存储 str:number
		for(let i = 0; i < length; i ++) {
			if (!strToNum[str[i]]) {
				strToNum[str[i]] = 1;
			} else {
				strToNum[str[i]] ++;
			}
		}

		var str = '';
		var num = 0;
		//逐个比较value,找出最大的输出
		for(let item in strToNum){
			if(strToNum[item]>num) {
				num = strToNum[item];
				str = item;
			}
		}

		console.log(strToNum,str,num);
	}

2、数组去重

	function removeRepeat(arr) {
		var newarr = [];
		var json = {};
		for(let i = 0; i < arr.length; i++) {
			if(!json[arr[i]]) {
				json[arr[i]] = 1;  //标记arr[i]已经存在,只是标记作用
				newarr.push(arr[i]);
			}
		}
		console.log(newarr);
	}


	function removeRepeat(arr) {
    	var newarr= arr.filter(function(element, index, arr) {
       		 return arr.indexOf(element) == index;
    	});
    	console.log(newarr);
	}

	function removeRepeat(arr) {
		var newarr = [];
	    for(var i=0; i<arr.length; i++) {
	        if((newarr.indexOf(arr[i])) < 0) {
	            newarr.push(arr[i]);
	        }
	    }
	    console.log(newarr);
	}

3、从两组字符串中获取不同部分按顺序生成对称字符串

	function removeRepeat(str) {
		var newstr = [];
		for (let i = 0; i < str.length; i ++) {
			if(newstr.indexOf(str[i]) == -1) {
				newstr.push(str[i])
			}
		}
		return newstr.join('');
	}

	function compare(str1,str2) {
		var newstr1 = remove(str1);
		var newstr2 = remove(str2);
		var length1 = newstr1.length;
		var length2 = newstr2.length;
		var result = [];
		//将newstr1中存在且newstr2中不存在的字符保存下来
		for(let i = 0; i < length1; i ++) {
			if(newstr2.indexOf(newstr1[i]) == -1) {
				result.push(newstr1[i])
			}
		}
		//将newstr2中存在且newstr1中不存在的字符保存下来
		for(let i = 0; i < length2; i ++) {
			if(newstr1.indexOf(newstr2[i]) == -1) {
				result.push(newstr2[i])
			}
		}
		//将两字符串不同部分按照ascii排序
		result.sort(function(a,b){return a.charCodeAt(0) - b.charCodeAt(0)});
		return result.join('') + result.reverse().join('');
	}

4、URL参数的提取

例子:

有这样一个 URL: http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,
请写一段 JS 程序提取 URL 中的各个 GET 参数(参数名和参数个数不确定),

将其 按 key-value 形式返回到一个 json 结构中,
如{a:’ 1′, b:’ 2′, c:” , d:’ xxx’, e:undefined}。

	function getURL(url) {
		var result = {};
		var parmList = url.split("?")[1];
		var parm = 	parmList.split("&");
		for(let i=0; i<parm.length; i++) {
			//拆分后数组中有几个元素,若只有一个则value为undefined
			if(parm[i].split("=").length == 2) {
				result[parm[i].split("=")[0]] = parm[i].split("=")[1];
			} else {
				result[parm[i].split("=")[0]] = undefined;
			}
		}
		console.log(result);
	}

5、LazyMan问题

`
实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)输出:
Hi! This is Hank!

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
//等待10秒…
Wake up after 10
Eat dinner~

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
Hi This is Hank!
Eat dinner~
Eat supper~

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper

以此类推。

function lazyMan(name){
	(function(){
		console.log('Hi! This is ' + name)
	})(name)
}
lazyMan.prototype.sleep = function(time) {
	console.log(time)
}


6、冒泡排序算法

function bubbleSort(arr) {
	var length = arr.length;
	for(let i = 0; i < length; i++) {
		//每一轮外循环,最后一个数已经排序完成
		for(let j = 0; j < length - i; j++) {
			if(arr[j] > arr[j+1]) {
				[arr[j],arr[j+1]] = [arr[j+1],arr[j]]
			}
		}
	}
	return arr;
}

7、不借助中间变量交换两个数字

function swap(a , b) {  
  b = b - a;
  a = a + b;
  b = a - b;
  return [a,b];
}

8、计算一个数组中最大值和最小值的差

function reduce(arr) {
	var max = arr[0];
	var min = arr[0];
	for(let i = 1; i < arr.length; i ++) {
		if(max < arr[i]) {
			max = arr[i]
		}
		if(min > arr[i]) {
			min = arr[i]
		}
	}
	return max - min;
}

8、随机生成指定长度的字符串

function randomString(n) {  
    var str = 'abcdefghijklmnopqrstuvwxyz9876543210';
    var tmp = '';
    var l = str.length;
    for (let i = 0; i < n; i++) {
      //tmp += str.charAt(Math.floor(Math.random() * l));
      tmp += str[Math.floor(Math.random() * l)];
    }
    return tmp;
}

9、获取指定范围内的随机数

function getRadomNum(min,max){
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

10、随机获取数组中的元素

function getRadomArr(arr) {
	return arr[Math.floor(Math.random()*arr.length)];
}

11、对象转化为数组

//该方法键必须是数字,且对象必须拥有length属性
function objToStr(obj) {
	return Array.from(obj);
}

function objToStr(obj) {
	var result = [];
	for(let key in obj) {
		result.push(obj[key])
	}
	return result;
}

12、获取数组中的最大值和最小值

function maxAndMin(arr){
	return {
		max:Math.max.apply(null,arr),
		min:Math.min.apply(null,arr)
	}
}

13、找出数组中出现此说最多的元素,并给出出现过的位置

function getMaxAndIndex(arr){
	var result = {};
	var length = arr.length;
	for(let i = 0; i < length; i ++) {
		if(!result[arr[i]]) {
			result[arr[i]] = 1;
		}else {
			result[arr[i]] ++;
		}
	}
	var num = 0;
	var str = '';
	for(let key in result) {
		if(num < result[key]) {
			num = result[key];
			str = key;
		}
	}
	var index = [];
	for(let i = 0; i < arr.length; i ++) {
		if(arr[i] == str) {
			index.push(i)
		}
	}
	console.log(num,str,index);
}

14、 给定一个字符串,每隔n个字符添加一个“,”

function splitStr(str,n) {
	var arr = str.split("");
	var length = arr.length;
	if(n >= length) {
		return str;
	}
	var j = 0;
	for(let i = n; i < length; i = i + n) {
		arr.splice(i+j,0,",");
		j ++;
	}
	if (arr[arr.length - 1] == ",") {
		arr.splice(arr.length);
	}
	return arr.join("");
}

15、通过一个输入框,输入一个自定义的数组,例如1,4,5,23,2,17,24,10000000。请把他按照中间高两边低进行排序,最后的结果是1,4,5,23,10000000,24,17,2,算法越准确越好,请注意左右翼数据数据的平衡性。

function 

16、js去掉空格字符串

//去掉全部字符串
str = str.replace(/\s*/g,"");
//去掉左边字符串
str = str.replace(/^\s*/g,"");
//去掉右边字符串
str = str.replace(/\s*$/g,"");
//去掉两头空格
str = str.replace(/^\s*|\s*$/g,"");

17、假设现在有两个函数function A()和function B(),现在希望创建一个新的函数function C(),新函数的逻辑是将自己接收到的前两个参数传给函数A,剩余所有参数传给函数B,请用原生javascript实现函数C

举例:
如果调用函数C:C[a,b,c,d,e]
相当于调用函数A和函数B:A(a,b),B(c,d,e)

function C(){
     var a_args=Array.prototype.slice.call(argumens,0,2);
     var b_args=Array.prototype.slice.call(arguments,2);
     A.apply(this,a_args);
     B.apply(this,b_args);
}



function C(...s){
      A.call(this,s[0],s[1]);
      B.call(this,s.slice(2));
}



function C(...s){
      A.apply(this,s.slice(0,2));
      B.apply(this,s.slice(2));
}



function C(){
   A(arguments[0],arguments[1]);
   B(Array.prototype.slice.call(arguments,2));
}


function C(a1,a2,...args) {
    A(a1,a2)
    B(...args)
}

Array.prototype.slice表示数组的原型中的slice方法。这个slice方法返回的是一个Array类型的对象。可以把类数组对象转化成真正的数组,与Array.from类似。


18、请实现以下template方法,用于模板解析

var conplied = template(“hello <%=user%>!”);
complied({“user”:“world”}); => hello world!

var conplied = template(“welocm to <%=location%>!”);
complied({“location”:“CVTE”}); => welcom to CVTE!;

function template(source){
   var temp=source;
   return function(obj){
       for(var prop in obj){
              var tpl="<%="+prop+"%>";
              temp=temp.replace(tpl,obj[prop]);
       }
       console.log(temp);
   }
}

19、写一个函数,将传进去的数组按深度展开

例子:
list:[1,2,[3,4],[5,6,[7,8],9],10,11]
depth 等于 1 时输出
depth = 1 :[1,2,3,4,5,6,[7,8],9,10,11]

depth 等于 2 时输出
depth = 2 :[1,2,3,4,5,6,7,8,9,10,11]

function flattern(array,num = 0) {
	var length = array.length;
	var newArray = array;
	for(let i = 0; i < num; i ++) {
		newArray = [].concat(...newArray)
	}
	return newArray;
}

console.log(flattern([1,2,3,[4,5,[6,7]]],2))

20、实现一个简单的模板引擎

例子:

let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = {
  name: '姓名',
  age: 18
}
render(template, data); // 我是姓名,年龄18,性别undefined
方法1:先将模板与数据中均存在的属性替换掉,再将数据中不存在模板中存在的属性设置为undefined
function render(template, data) {
	for(let key in data) {
		if(template.indexOf(key)) {
			var reg =new RegExp("{{" + key + "}}","g");
			template = template.replace(reg,data[key])
		}
	}

	template = template.replace(/\{\{(\w+)\}\}/g,'undefined')

	return template;
}


方法2 迭代,一个一个替换,注意exec匹配到的第一项是匹配字符串,第二项为分组内的字符串[{{name}},name]
function render(template, data) {
  const reg = /\{\{(\w+)\}\}/; // 模板字符串正则
  if (reg.test(template)) { // 判断模板里是否有模板字符串
    const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段
    template = template.replace(reg, data[name]); // 将第一个模板字符串渲染
    return render(template, data); // 递归的渲染并返回渲染后的结构
  }
  return template; // 如果模板没有模板字符串直接返回
}
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端的diff算法在虚拟DOM的实现中起着重要的作用,它用于比较两个虚拟DOM树的差异,然后只对差异部分进行更新,以提高性能和效率。在面试中,可能会问到一些与前端diff算法相关的问题。以下是一些常见的问题和答案供参考: 1. 什么是前端diff算法前端diff算法是指用于比较两个虚拟DOM树之间差异的算法。通过比较新旧虚拟DOM树的差异,可以确定需要更新的部分,从而减少不必要的页面重绘和重新渲染,提高性能和效率。 2. 常见前端diff算法有哪些? 常见前端diff算法包括: - O(n²)算法:遍历新旧节点进行比较,时间复杂度为O(n²),性能较差。 - O(n)算法:采用双指针或者哈希表等方式,将遍历时间复杂度优化为O(n),例如React中采用的Virtual DOM diff算法。 - Fiber算法:React Fiber算法是一种增量渲染算法,通过将更新操作拆分为多个单元,可以在每个帧中执行一部分工作,从而提高用户体验。 3. React中采用的前端diff算法是什么? React中采用的是一种基于O(n)算法的Virtual DOM diff算法。该算法通过遍历新旧虚拟DOM树的节点,对比差异并更新只有差异的部分,以提高性能。 4. 前端diff算法的优化策略有哪些? 前端diff算法可以通过以下优化策略提高效率: - 对比时忽略静态节点:对比时可以忽略没有变化的静态节点,减少不必要的对比操作。 - 使用唯一标识符:给每个节点添加唯一标识符,可以更精确地确定哪些节点需要更新。 - 列表元素的优化:在对比列表元素时,可以使用Key属性标识唯一性,以减少重新排序和重渲染的开销。 这些问题涵盖了前端diff算法的概念、常见算法以及优化策略。在面试中,你可以根据自己的理解和经验进行回答。希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值