进入刷编程题的阶段,从牛客网开始。尝试着自己写,写不出来的时候会去大佬们的博客找一些答案,然后自己试着去理解,虽然一开始基本没写出来可以通过的代码,但是接下来的训练,希望有所成效。
参考文档:
https://segmentfault.com/a/1190000002976199#articleHeader0
https://www.nowcoder.com/questionTerminal/2ded24e34ec34325a62d42d0c8479bae?toCommentId=51551
https://blog.csdn.net/hhthwx/article/details/79784205
2018.08.05总结
1.用JavaScript实现斐波那契数列函数,返回第n个斐波那切数。f(1)=1,f(2)=2等。
代码实现:
function fibonacci(n){
If(n==1 | n==2){
return 1;
}else{
return fibonacci(n-1)+fibonacci(n-2);
}
}
2.获取字符串的长度:如果第二个参数bUnicode255For1 === true,则所有字符长度为1,否则如果字符Unicode编码>255,,则长度为2。
代码实现:
function strlength(s,bUnicode255For1){
var len;
if(bUnicode255For1 === true){
return s.length;
}
for(var i =0;i<s.length;i++){
if(s.charCodeAt(i)>255){
len += 2;
}else{
len +=1;
}
}
console.log(len);
return len;
}
说明:
①题目要求说的是如果第二个参数为true,则每个字符长度为1,一开始我理解成了整个字符串的长度为1。
②charCodeAt()方法返回一个字符的Unicode编码。
3.DOM节点查找:查找两个节点的最近的一个共同父节点,可以包括节点自身。
function commonParentNode(oNode1,oNode2){
if(oNode1.contains(oNode2)){
return oNode1;
}else if(oNode2.contains(oNode1)){
return oNode2;
}else{
return commonParentNode(oNode1.parentNode,oNode2);
}
}
说明:
通过递归来判断oNode1的父节点是不是包含oNode2节点。
4.数组去重:为Array对象添加一个去除重复项的方法。
代码实现:
array.prototype.uniq = function(){
var arr = [];
var flag = true;
for(var i = 0;i<this.length;i++){
//判断当前数组中的值与当前的值是否相等,如果相同则返回那个位置;如果不相等则返回-1
if(arr.indexOf(this[i]) == -1){
//判断是否为NAN类型的数
if(this[i] != this[i]){
if(flag){
arr.push(this[i]);
flag = false;
}
}else{
arr.push(this[i]);
}
}
}
return arr;
}
说明:
①思路:首先我们要判断数组中的每一个字符是否出现在了新定义的数组arr中,这里使用indexOf()方法来判断;如果是只出现了一次则将该字符push进我们定义的arr数组中;还要判断数组中的字符是否为NAN类型的值。
②indexOf()方法:该方法可返回某个指定的字符串值在字符串中首次出现的位置。字符位置是从0开始的。如果在数组中没有找到字符串则返回-1.
参数值:array.indexOf(item,start);//item必需,表示要查找的元素;start可选,规定在字符串中开始检索的位置,合法取值是0~arr.length-1.
③NAN属性:Not A Number,表示某个值不是数字,由于NAN与其他数值进行比较的结果总是不相等的,包括它自身,因此我们不能用Number.NaN比较来检测一个值是不是数字,只能调用isNAN()来比较。
④存在的问题:不理解为什么定义一个flag=true,当为true时,才将这个字符push进arr数组,然后将flag的值设置为false。
5.将字符串转换为驼峰格式:css中经常有类似text-indent这种通过‘-’连接的字符,通过javaScript设置样式的时候需要将这种样式转化成textIndent驼峰格式,请完成此转换功能:以‘-’为分隔符,将第二个起的非空单词首字母转为大写。
思路:我们首先判断第一个字符是不是‘-’,如果是则将第一个字符移除,然后依次遍历;检测出‘-’之后,将其移除,然后把它后面的字母通过toUpperCase()方法转换成为大写。
代码实现:
function cssStyle2DomStyle(sName){
var arr = sName.split(‘’);
//判断第一个字符是否为‘-’,如果是则移除
if(arr.indexOf(‘-’) == 0){
arr.splice(0,1);
}
for(var i=0;i<arr.length;i++){
if(arr[i] == ‘-’){
arr.splice(i,1);
arr[i] = arr[i].toUpperCase();
}
}
return arr.join(‘’);
}
说明:
①split()方法:把一个字符串分割成字符串数组,这里我们将sName字符串分割成字符串数组,每个字符中间用逗号来隔开(默认),然后依次遍历判断每个字符是否为‘-’。
②splice()方法:用于插入、删除或替换数组的元素。返回数组。
array.splice(index,howmany,item1,item2,...itemX);
Index是必须的,规定从何处添加/删除元素,这个数值是指的第几个元素,而不是数组的下标索引;howmany是必须的,规定应该删除多少元素;剩下的项是可选的,要添加到数组的新元素。
③join()方法:用于把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分割的。该方法的作用和split()方法的作用相反。
2018.08.06总结
6.找出元素item在给定数组arr中的位置。如果数组中存在item,则返回元素在数组中的位置,否则返回-1。
function indexOf(arr, item){
return arr.indexOf(item);
}
但是所有主要的浏览器都支持indexOf()方法,但是IE8及更早的IE版本不支持该方法,所以我们可以像下面的方式一样写:
function indexOf(arr, item){
if(Array.prototype.indexOf){
return arr.indexOf(item);
}else{
for(var i=0;i<arr.length;i++){
if(arr[i] == item){
return i;
}else{
return -1;
}
}
}
}
说明:
参考文档:https://blog.csdn.net/sinat_35803474/article/details/68068789
7.移除数组arr中的所有值与item相等的元素,不要直接修改数组arr,结果返回新的数组。
①push():
function remove(arr, item){
var newArr = [];
for(var i=0;i<arr.length;i++){
if(arr[i] != item){
newArr.push(arr[i]);
}
}
return newArr;
}
push():
function remove(arr, item){
var newArr = [];
arr.forEach(function(e){
if(e != item){
newArr.push(e);
}
})
return newArr;
}
②splice():
function remove(arr, item){
var newArr = arr.slice(0);
for(var i=0;i<arr.length;i++){
if(newArr[i] == item){
newArr.splice(i,1);
i--;
}
}
return newArr;
}
③filter():
function remove(arr,item){
return arr.filter(function(e){
return e != item;
})
}
说明:
①参考文档:https://blog.csdn.net/cristina_song/article/details/77917251
②push()方法:可向数组的末尾添加一个或多个元素,并返回新的长度。
语法:arr.push(newElement1,newElement2, ... ,newElement3)
直接修改原来的数组,而不是创建一个新的数组。
③forEach()方法:用于调用数组的每个元素,并将元素传递给回调函数。
④slice()方法:从已有的数组中返回选定的元素。
语法:arr.slice(start,end);start是必需的,规定从何处开始选取;如果是负数则从数组尾部开始算起,如-1是数组的最后一个元素。该方法不会修改数组,而是返回一个子数组。
这里slice()方法涉及到深拷贝和浅拷贝的概念,这里先不做详细展开,等后面再解释。
⑤filter()方法:该方法创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
但是该方法不会对空数组进行检测,也不会改变原始数组。
语法:arr.filter(function(currentValue,index,arr),thisValue);函数是必需的,数组中的每个元素都会执行这个函数。
⑥这道编程题涉及到五种方法来实现这一操作,虽然总结了出来,但是仍然对forEach()方法和filter()方法理解不是特别透彻。
8.在数组arr末尾添加元素item。不要直接修改数组arr,结果返回新的数组。
function append(arr,item){
return arr.concat(item);
}
说明:
①concat()方法:用于连接两个或者多个数组。
该方法不会改变现有的数组,而会返回被连接数组的一个副本。
②浅拷贝和深拷贝:
浅拷贝:我们平时使用的简单的赋值操作是浅拷贝,只要我们改变其中一个的任何一个,其他的也会跟着改变。
深拷贝:上面涉及到的slice()方法和该题中涉及到的concat()方法,都是深拷贝。
深拷贝出来的数组我们在改变了某一项之后,对原来的数组是没有影响的。
详情请移步至该文档:https://www.cnblogs.com/baiyangyuanzi/p/6518218.html
2018.08.07总结
9.在数组arr开头添加元素item。不要直接修改数组arr,结果返回新的数组。
代码实现:
function prepend(arr,item){
var newArr = arr.slice(0);
newArr.unshift(item);
return newArr;
}
说明:
unshift()方法:可向数组的开头添加一个或更多元素,并返回新的长度
语法:arr.unshift(newElement1,newElement2,…,newElementX);
newElement1是必需的,向数组添加的第一个元素。其余是可选的。
不是创建新的数组,而是直接修改原有的数组。push()方法是在数组的尾部添加元素。
10.删除数组arr第一个元素。不要直接修改数组arr,结果返回新的数组。
代码实现:
function ourtail(arr){
var newArr = arr.slice();
newArr.shift();
return newArr;
}
说明:
shift()方法:用于把数组的第一个元素从其中删除,并返回第一个元素的值。
该方法不创建新的数组,而是直接修改原有的数组。pop()方法是删除并返回数组的最后一个元素。
11.找出数组arr中重复出现过的元素。
编程思路:先对原数组进行排序,然后判断数组中前一个与后一个数值相等且该值没有保存在newArr数组中,便将该值push进newArr数组中。同时i的值增加。
代码实现:
function duplicates(arr){
var newArr = [];
arr.sort();
for(var i=0;i<arr.length;i++){
if(arr[i] == arr[i+1] && newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i]);
i++;
}
}
return newArr;
}
说明:
sort()方法用于对数组的元素进行排序。
语法:arr.sort(sortby);sortby是可选参数,规定排序顺序,必须是函数。
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,是按照字符编码的顺序进行排序。
12.在数组arr中,查找值与item相等的元素出现的所有位置。
代码实现:
function findAllOccurrences(arr,target){
var newArr = [];
var j =0;
for(var i=0;i<arr.length;i++){
if(arr[i] == target){
//设置j,规定开始检索的位置,即规定从上次检索的位置之后再进行检索,避免重复的检索。
newArr.push(arr.indexOf(arr[i]),j);
j++;
}
}
return newArr;
}
2018.08.08总结
13.修改js代码中parseInt的调用方式,使之通过全部测试用例。
代码实现:
function parse2Int(num){
return parseInt(num);
}
说明:
parseInt()函数:可解析一个字符串,并返回一个整数。
语法:parseInt(string,radix);
string是必须的,要被解析的字符串。radix可选,表示要解析的数字的基数,该值介于2~36之间。如果省略该参数或其值为0,则数字将以10为基础解析。如果以“0x”或“0X”开头,将以16位基数来解析。如果该参数小于2或者大于36,则parseInt()将返回NAN。如果string以0开头,则把其解析为八进制或十六进制的数字。如果string以1~9的数字开头,则把它解析成十进制的整数。
14.实现一个打点计时器,要求:
(1)从start到end(包含start和end),每隔100毫秒console.log一个数字,每次数字增幅为1
(2)返回的对象中需要包含一个cancel方法,用于停止定时操作
(3)第一个数需要立即输出
代码实现:
function count(start,end){
console.log(start);
var count = setInterval(
if(start<end){
console.log(Start +=1);
},100);
return {cancel: function(){
clearInterval(timer)
}
}
}
说明:
setInterval()方法可按照指定的周期来调用函数或计算表达式,该方法会不停的调用函数,直到clearInterval()被调用或窗口关闭。由setInterval()返回的ID值可用作clearInterval()方法的参数。
语法:setInterval(code,millisec[,”lang”]);
code是必需的,要调用的函数或要执行的代码串。millisec必需的,周期执行或调用cod之间的时间间隔。
2018.08.10总结
15.获取数字num二进制形式第bit位的值。注意:
(1)bit从1开始
(2)返回0或1
(3)举例:2的二进制为10,第1位为0,第2位为1
代码实现:
function valueAtBit(num,bit){
var newNum = num.toString(2);
return newNum[newNum.length-bit];
}
说明:
toString()方法可把一个逻辑值转换为字符串,并返回结果。
语法:booleanObject.toString();返回字符串true或false