美文网首页程序员JavaScript 进阶营
W3Cschool——中级脚本算法题

W3Cschool——中级脚本算法题

作者: cduyzh | 来源:发表于2017-08-26 18:19 被阅读0次
    JS-train

    前言

    W3Cschool上有个编程挑战,里面的题目前是面向前端方面的,也有一些算法和数据结构的题在,最近忙于实习,已经很久没做了,前后隔了一个月,在公司没事的时候又重新做了起来,索性花了2天把剩下的一起做完了。在此做下代码思路的记录。

    区间求值算法挑战

    我们会传递给你一个包含两个数字的数组。返回这两个数字和它们之间所有数字的和。

    最小的数字并非总在最前面。

    function sumAll(arr) {
                return (arr[0] + arr[1]) * (Math.abs(arr[0] - arr[1]) + 1) / 2;
            }
            console.log(sumAll([1, 4]));
    

    找出数组间差异算法挑战

    比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。

    //map或forEach数组方法
            var diff = function(arr1, arr2) {
                var diff = [];
                arr1.map(function(val1) {
                    if (arr2.indexOf(val1) < 0) {
                        diff.push(val1);
                    } else {
                        arr2.splice(arr2.indexOf(val1), 1);
                    }
                });
                return diff.concat(arr2);
            };
            //传统for循环
            // var diff = function(arr1, arr2) {
            //     var diff = [];
            //     for (var i = 0; i < arr1.length; i++) {
            //         if (arr2.indexOf(arr1[i]) < 0) {
            //             diff.push(arr1[i]);
            //         } else {
            //             arr2.splice(arr2.indexOf(arr1[i]), 1);
            //         }
            //     }
            //     return diff.concat(arr2);
            // };
            console.log(diff([1, 2, 3, 6, 5], [1, 2, 3, 4, 5]));
    

    数字转罗马数字

    将给定的数字转换成罗马数字。

    所有返回的 罗马数字 都应该是大写形式。

    代码的关键在于lookup对象里面的键值对,都是1,4,5,9这几个数字进位。 看图更容易明白。


    数字转罗马数字
    function convert(num) {
      var lookup ={M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
      var romanStr = "";
      for (var i in lookup){
        while (num >= lookup[i]){
          romanStr+=i;
          num -= lookup[i];
        }
      }
      return romanStr;
    }
    
    convert(36);
    

    对象搜索算法挑战

    写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。

    例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }],第二个参数是 { last: "Capulet" },那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。

    function where(collection, source) {
                var arr = [],
                    index = 0; // What's in a name? 
                // console.log(Object.getOwnPropertyNames(source).length); //获取对象属性个数
                for (; index < collection.length; index++) {
                    for (var key in collection[index]) {
                        var count = 0;
                        for (var key2 in source) {
                            if (collection[index].hasOwnProperty(key2)) {
                                if (source[key2] == collection[index][key2]) {
                                    count++;
                                }
                                if (count == Object.getOwnPropertyNames(source).length && key == key2) {
                                    arr.push(collection[index]);
                                }
                            }
                        }
                    }
    
                }
                return arr;
            }
    

    查询替换算法挑战

    使用给定的参数对句子执行一次查找和替换,然后返回新句子。

    第一个参数是将要对其执行查找和替换的句子。

    第二个参数是将被替换掉的单词(替换前的单词)。

    第三个参数用于替换第二个参数(替换后的单词)。

    注意:替换时保持原单词的大小写。例如,如果你想用单词 "dog" 替换单词 "Book" ,你应该替换成 "Dog"。

    function myReplace(str, before, after) {
                var newBefore = before.split(""),
                    newAfter = after.split(""),
                    upindex = [],
                    i = 0,
                    index = 0;
                for (; i < newBefore.length; i++) {
                    if (newBefore[i] > 'A' && newBefore[i] < 'Z') {
                        upindex.push(i);
                    }
                }
                for (; index < upindex.length; index++) {
                    if (newAfter[upindex[index]]) {
                        newAfter[upindex[index]] = newAfter[upindex[index]].toString().toUpperCase();
                    }
                }
                return str.replace(before, newAfter.join(""));
            }
    

    字符串移动插入算法挑战

    把指定的字符串翻译成 pig latin。

    Pig Latin 把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 "ay"。

    如果单词以元音开始,你只需要在词尾添加 "way" 就可以了。

    function translate(str) {
                var a = str.search(/[aeiou]/);
                var str2 = str;
                if (a === 0) {
                    str2 += "way";
                } else {
                    str2 = str.substr(a);
                    str2 += str.substr(0, a);
                    str2 += "ay";
                }
                return str2;
            }
           
    
    translate("consonant");
    
    

    字符配对算法挑战

    DNA 链缺少配对的碱基。依据每一个碱基,为其找到配对的碱基,然后将结果作为第二个数组返回。

    Base pairs(碱基对) 是一对 AT 和 CG,为给定的字母匹配缺失的碱基。

    在每一个数组中将给定的字母作为第一个碱基返回。

    例如,对于输入的 GCG,相应地返回 [["G", "C"], ["C","G"],["G", "C"]]

    字母和与之配对的字母在一个数组内,然后所有数组再被组织起来封装进一个数组。

    function pair(str) {
                var arr = new Array();
                str = str.split("");
                for (var index = 0; index < str.length; index++) {
                    arr[index] = new Array();
                    arr[index].push(str[index]);
                    if (str[index] == "G" || str[index] == "C") {
                        (arr[index] == "G") ? arr[index].push(
                            "C"): arr[index].push("G");
                    } else {
                        (arr[index] == "A") ? arr[index].push("T"): arr[index].push("A");
                    }
                }
                return arr;
            }
    

    字符串查询补充算法挑战

    从传递进来的字母序列中找到缺失的字母并返回它。

    如果所有字母都在序列中,返回 undefined。

    function fearNotLetter(str) {
                var sub;
                for (var index = 0; index < str.length - 1; index++) {
                    sub = str.charCodeAt(index + 1) - str.charCodeAt(index);
                    if (sub == 1) {
                        if (index == str.length) {
                            return undefined;
                        }
                    } else {
                        return String.fromCharCode(str.charCodeAt(index) + 1);
                    }
                }
            }
    

    输入检查算法挑战

    检查一个值是否是基本布尔类型,并返回 true 或 false。

    基本布尔类型即 true 和 false。

    function boo(bool) {
      if (bool === true || bool ===false){
          return true;
          }
      return false;
    }
    

    数组去重算法挑战

    写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。

    换句话说,所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值。

    非重复的数字应该以它们原始的顺序排序,但最终的数组不应该以数字顺序排序。

    function unite(arr1, arr2, arr3, arr4) {
                var arr = [],
                    result = [],
                    index = 0;
                if (arr4) {
                    arr = arr1.concat(arr2, arr3, arr4);
                } else if (arr3) {
                    arr = arr1.concat(arr2, arr3);
                } else {
                    arr = arr1.concat(arr2);
                }
                for (; index < arr.length; index++) {
                    if (result.indexOf(arr[index]) == -1) {
                        result.push(arr[index]);
                    }
                }
                return result;
            }
    

    es6实现

    //ES6新增的Set数据结构,类似于数组,但是里面的元素都是唯一的 ,其构造函数可以接受一个数组作为参数
    //let arr=[1,2,1,2,6,3,5,69,66,7,2,1,4,3,6,8,9663,8]
    //let set = new Set(array);
    //{1,2,6,3,5,69,66,7,4,8,9663}
    //ES6中Array新增了一个静态方法from,可以把类似数组的对象转换为数组
    //Array.from(set)
    //[1,2,6,3,5,69,66,7,4,8,9663]
    function removeRepeatArray(arr){
        return Array.from(new Set(arr))
    }
    

    html符号转实体算法挑战

    将字符串中的字符 &、<、>、" (双引号), 以及 ' (单引号)转换为它们对应的 HTML 实体。

    function convert(str) {
      return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');
    }
    convert("Dolce & Gabbana");
    

    数组平铺算法挑战

    对嵌套的数组进行平铺嵌套数组。你必须考虑到不同层级的嵌套。

    function steamroller(arr) {
      // I'm a steamroller, baby
      return arr.reduce(function (acc, val) {
        return acc.concat(Array.isArray(val) ? (val.length > 0 ? steamroller(val) : []) : val);
      }, []);
    }
    
    steamroller([1, [2], [3, [[4]]]]);
    

    二进制转字符算法挑战

    传入二进制字符串,翻译成英语句子并返回。

    二进制字符串是以空格分隔的。

    function binaryAgent(str) {
                var arg = str.split(" ");
                var temp, i;
                var newArg = new Array();
                for (i = 0; i < arg.length; i++) {
                    temp = String.fromCharCode(parseInt(arg[i], 2));
                    newArg.push(temp);
                }
                return newArg.join("");
            }
            console.log(binaryAgent(
                "01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"
            ));
    

    数组元素判断算法挑战

    完善编辑器中的every函数,如果集合(collection)中的所有对象都存在对应的属性(第二个参数),并且属性(第二个参数)对应的值为真。函数返回ture。反之,返回false。

    记住:您可以通过点符号或[]符号来访问对象属性。

    function every(collection, pre) {
                // Is everyone being true?
                function check(element, index, array) {
                    return element[pre];
                }
                if (collection.every(check)) {
                    return true;
                } else return false;
            }
    

    函数迭代可选参数算法挑战

    创建一个计算两个参数之和的 function。如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果。

    例如,add(2, 3) 应该返回 5,而 add(2) 应该返回一个 function。

    调用这个有一个参数的返回的 function,返回求和的结果:

    var sumTwoAnd = add(2);

    sumTwoAnd(3) 返回 5。

    如果两个参数都不是有效的数字,则返回 undefined。

    <!-- 应付答案解法 -->
    var add = function(x, r) {
                if (arguments.length == 1 && !isNaN(x)) {
                    return function(y) {
                        if (y instanceof Array) {
                            return undefined;
                        } else return x + y;
                    };
                } else if (typeof(r) == "string" || isNaN(x)) {
                    return undefined;
                } else return x + r;
            };
    
    <!-- 其他标准解法 -->
    function add() {
      var arr=[].concat(...arguments);
      if( arr.some(function(ele){
        return typeof ele!="number";
      }) ){    //参数出现非数字类型,返回undefined
        return undefined;
      }
      if( arr.length==2 ){
        return arr[0]+arr[1];
      }
      return function(a){
        if( typeof a != "number" ){  //同上
          return undefined;
        }
        return a+arr[0];
      };
    }
    

    注: isNaN()的参数如果不是数值型的会先自动转换成数值型,再来判断这个数值是不是NaN

    MDN文档节选关于isNaN
    // The same effect with Number.isNaN():
            function increment(x) {
                if (Number.isNaN(Number(x))) x = 0;
                return x + 1;
            };
    
            // In the following cases for the function's argument x,
            // isNaN(x) is always false, although x is indeed not a
            // number, but can be used as such in arithmetical
            // expressions
            increment(""); // 1: "" is converted to 0
            increment(new String()); // 1: String object representing an empty string is converted to 0
            increment([]); // 1: [] is converted to 0
            increment(new Array()); // 1: Array object representing an empty array is converted to 0
            increment("0"); // 1: "0" is converted to 0
            increment("1"); // 2: "1" is converted to 1
            increment("0.1"); // 1.1: "0.1" is converted to 0.1
            increment("Infinity"); // Infinity: "Infinity" is converted to Infinity
            increment(null); // 1: null is converted to 0
            increment(false); // 1: false is converted to 0
            increment(true); // 2: true is converted to 1
            increment(new Date()); // returns current date/time in milliseconds plus 1
    

    End

    文中省略了一些题目的答案,因为偏基础和比较简单,我就略过了。如果大家有es6标准下或其他的一些解法思路,也可以跟我讨论。

    相关文章

      网友评论

        本文标题:W3Cschool——中级脚本算法题

        本文链接:https://www.haomeiwen.com/subject/obkvdxtx.html