字符串等笔试题记录


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1 最长公共连续子串的长度

在这里插入图片描述

/*请完成下面这个函数,实现题目要求的功能
当然,你也可以不按照下面这个模板来作答,完全按照自己的想法来 ^-^
******************************开始写代码******************************/
function longestSubStrLength(s1, s2) {
    if (s1 === '' || s2 === '') {
        return 0
    }
    s1 = s1.toLowerCase()
    s2 = s2.toLowerCase()
    if (s1.length > s2.length ) {
        [s1, s2] = [s2, s1];
    }
    let m = s1.length         //5
    let n = s2.length          //7
    for (let i = m; i > 0; i--) {
        for (let j = 0; j < n - j; j++) {
            let str = s1.substr(j, i);
            if (s2.indexOf(str) >= 0) {
                return str.length
            }
        }
    }
    return 0
}
/******************************结束写代码******************************/
let res;
// let _s1 = read_line();
// let _s2 = read_line();
let _s1 = 'abcde';
let _s2 = 'abcebob';
res = longestSubStrLength(_s1, _s2);
// print(res);
console.log(res);

2 比较版本号大小

在这里插入图片描述
在这里插入图片描述

3 乘积最大子序列

在这里插入图片描述

// let arr = read_line().split(' ').map((a) => parseInt(a));
let arr = [2, 3, -2, 4]
let max = 1, min = 1, res = 1;
for (let i = 0; i < arr.length; i++) {
    if (arr[i] >= 0) {
        max = Math.max(max * arr[i], arr[i]);
        min = Math.min(min * arr[i], arr[i]);
    }else{
        let temp = max;
        max = Math.max(min * arr[i], arr[i]);
        min = Math.min(temp * arr[i], arr[i]);
    }
    res = Math.max(max, res);
}
// print(res )
console.log(res );

4 两个复数相乘

  • 实部乘以实部 减去 虚部乘以虚部作为res的实部;
  • 实部与虚部交叉相乘然后 相加 作为res的虚部;
let str1 = readline();//第一个数 如 1+2i
let str2 = readline();//第二个数 如 3+4i
let a1 = parseInt(str1.split('+')[0]);//1
let a2 = parseInt(str1.split('+')[1]);//2
let b1 = parseInt(str2.split('+')[0]);//3
let b2 = parseInt(str2.split('+')[1]);//4
let m = a1 * b1 - a2 * b2;
let n = a1 * b2 + a2 * b1;
let res = m +'+'+ n + 'i';
print(res)

5 计算某一年过去的天数

  • 2004-01-01 输出1
  • 2004-03-05 输出 65 因为31+29+5=65天
let str = readline(); // let str = '2004-01-01'
let arr1 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let arr2 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let year = parseInt(str.split('-')[0]);
let month = parseInt(str.split('-')[1]);
let day = parseInt(str.split('-')[2]);
if (month == 1) {
    print(day)
} else {
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
        let temp = arr2.slice(0, month - 1);
        print(eval(temp.join('+')) + day);
    } else {
        let temp = arr1.slice(0, month - 1);
        print(eval(temp.join('+')) + day);
    }
}

6 数字k节翻转,不足k则不翻转直接拼接

  • 数字都以#结束
  • '1 2 3 4 5 #',k=2,则输出2 1 4 3 5
  • '1 2 3 4 5 #',k=3,则输出3 2 1 4 5
let str = '1 2 3 4 5 #';
let k = parseInt('2');
// let str = readline();
// let k = parseInt(readline());
let arr0 = str.split(' ').map((a) => parseInt(a))
let arr = arr0.slice(0, arr0.length - 1);
let res = [];
for (let i = 0; i < arr.length && k < arr.length; i++) {
    res = res.concat([], arr.splice(0, k).reverse());//splice会改变原数组
}
let res1 = res.concat(arr);
console.log(res1.join('->'));

7 验证小括号是否闭合

  • (())(),输出true
  • ((()),输出false
  • 若为空'',输出true

正则法

//let str='(   )'.trim()
let str='( ( ) ))()'.replace(/\s/g,'')// \s 匹配空格,在这里是去掉空格
let p=/\(\)/g
while (p.test(str)) {
    str = str.replace(p,'')//将匹配到的()都变为空'',注意不是空格,是空
}
console.log(!str.length);//str.length只有0和1两种情况 用!变为Boolean值
//最后有剩余匹配不到的,即str长度为1个以上,输出false,剩0个,则为true

下图是用stack栈法,但有点问题,准确率只有85.7%
在这里插入图片描述

8 找出字符串中字母出现次数最多的字符及其出现次数

  • 如输入success,输出s 3
  • 思路:
    1、先创建一个空对象temp;
    2、将字母中的值作为对象temp的键key,将其出现的次数作为temp键的值value;
    3、通过比较temp中value的大小,输出该键key和值value
let str = 'success'
if (str.length == 1) {
    print(str+' '+1)
} else {
    let strArr = str.split('');
    let temp = {};
    for (let i = 0; i < strArr.length; i++) {
        temp[strArr[i]] = temp[strArr[i]] ? ++temp[strArr[i]] : 1
    }
    let key = '', value = 1;
    for (let k in temp) {
        if (temp[k] >= value) {
            key = k;
            value = temp[k];
        }
    }
    print(key + ' ' + value);
}

9 字符型数字(不安全数)的相加

leetcode上有这样一道题目:
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

注意:

num1 和num2 的长度都小于 5100.
num1 和num2 都只包含数字 0-9.
num1 和num2 都不包含任何前导零。
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。

javascript:
这道题用js解答很简单,因为javascript中有很多隐式类型转换可以为我们所用,一下子就可以实现数值和字符串互换。(字符串直接转化为数字然后加起来简直作弊。)
举个例子:

var a="123456";
a=+a; // a=123456

小的数字相加不会出错,到这种大的数字便出错了,很容易想到可能是跟数值数据类型存储的大小有关。
这里就得发问了,javascript的数值型数据类型一律存为double类型,整整8个字节,按照8个字节存储的话范围应该为:2.23x10^(-308) ~ 1.79x10^308
这么大的范围还不够存吗?
这里是个坑:对于整数的情况,js可以保证在53位的范围内能有正确的结果。这53位是一个安全的范围。
它存储的数值的范围在-263+1~263 - 1之间,即-9007199254740991~9007199254740991,超过这个范围js不保证数值的准确性。

console.log(Number.MAX_SAFE_INTEGER); //9007199254740991
console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991

解决办法:
不用数值类型存储,使用字符串类型存储,当然这要付出一点代价,使用字符串得读取字符串的每一位,还得处理进位

代码如下:

// let arr=readline().split('');
let str ='13254 4354325'
let arr = str.split(' ');
let a = arr[0];
let b = arr[1];
let len1 = a.length;
let len2 = b.length;
let sum = '', val1, val2;
let i = 0, j = 0;// let p = 1;
while (len1 > 0 || len2 > 0) {
    val1 = +(len1 > 0 ? a[len1 - 1] : 0);
    val2 = +(len2 > 0 ? b[len2 - 1] : 0);
    i += (val1 + val2 + j);
    j = 0;
    while (i>=10) {
        i -= 10;
        j++;
    }
    sum = i + '' + sum;
    i = 0;// p *= 10;
    len1--;
    len2--;
}
if (j > 0) {
    sum = j + sum;
}
console.log(sum);

10 return只能用于函数中

注意一下:

function fun(a) {
    if (a == 1) {
        console.log(111);
        return;
    }
    console.log(222);
}
fun(1);//只输出111
fun(2);//只输出222

在这里插入图片描述

11 查找数组中重复元素方法

js 查找数组重复元素方法
在这里插入图片描述

  let arr = [2, 3, 2, 1, 4, 5, 3];
    function fun1(arr) {
        let tmp = [];
        arr.sort().sort(function (a, b) {
            if (a === b && tmp.indexOf(a) === -1) {
                tmp.push(a)
            }
        })
        return tmp
    }
    function fun2(arr) {
        let tmp = [];
        arr.forEach(function (item) {
            (arr.indexOf(item) !== arr.lastIndexOf(item) && tmp.indexOf(item) === -1) && tmp.push(item)
        })
        return tmp;
    }
    console.log(fun1(arr))
    console.log(fun2(arr))

12 JS用户密码安全强度判定

JS用户密码安全强度判定

13 使用正则实现字符去重及多行去重

使用正则实现字符去重及多行去重

14 数字分解为若干的和

在这里插入图片描述
在这里插入图片描述

let num = 4;
let arr = [];
function fenjie(num, s, x) {
    if(num>0){
        for (let i = s; i <= num; i++) {
            arr[x] = i;
            fenjie(num - i, i, x + 1);
        }
        return;
    }
    s = arr[0];
    for (let i = 1; i < x; i++) {
        s+='+'+arr[i]
    }
    console.log(s);
}
fenjie(num,1,0)

在这里插入图片描述

15 人浪 字符串(主要学习splice的用法)

let str = 'hello';
let arr = [];
let temp = '';
let p=[]
for (let i = 0; i < str.length; i++) {
    temp = str[i].toUpperCase();//string
    p = str.split('');//数组
    p.splice(i, 1,temp);
    // console.log(p.join(''));
    arr.push(p.join(''))
}
console.log(arr);

let pp = ["h", "e", "l", "l", "o"];
pp.splice(0, 1,'H')
console.log(pp.join(''));

在这里插入图片描述
定义和用法

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。

注释:该方法会改变原始数组

在这里插入图片描述

16 华为手撕题

let arr = [0, 1, 3, 4, 5, 7, 9, 66, 88];
let a = 2, b = 99;
let brr = [];
for (let i = 0; i < arr.length; i++) {
    if (arr[i] >= a && arr[i] <= b) {
        brr.push(arr[i]);
    }
}
console.log(brr);
for (let i = 0; i < brr.length; i++) {
    let cha = brr[i + 1] - brr[i];
    if (cha > 2) {
        let left = brr[i] + 1
        let right = brr[i+1] - 1
        console.log(left + '->' + right);;
    }else if(cha == 2){
        console.log(brr[i]+1);
    }
}

在这里插入图片描述

17 统计字符个数(a12c2a4b6->a16b6c2)

在这里插入图片描述
在这里插入图片描述

    function betterCompression(s) {
        let p = /[a-z]\d+/g;
        let a = s.match(p);  //s = 'a12c56a1b5'
        console.log(a);//返回匹配到的数组

        let strArr = [], numArr = [];
        for (let i = 0; i < a.length; i++) {
            strArr.push(String(a[i].split('').splice(0, 1)))
            numArr.push(Number(a[i].split('').splice(1).join('')))
        }
        console.log(strArr, numArr);//将字符和出现次数分开计算

        let len = strArr.length;
        for (let i = 0; i < len; i++) {
            for (let j = i + 1; j < len; j++) {
                if (strArr[i] == strArr[j]) {
                    numArr[i] = numArr[i] + numArr[j];
                    strArr.splice(j, 1);
                    numArr.splice(j, 1);
                } else {
                    numArr[i] = numArr[i];
                }
            }
        }
        console.log(strArr, numArr);//遍历,得到次数和

        let obj = {};
        for (let i = 0; i < strArr.length; i++) {
            obj[strArr[i]] = numArr[i];
        }
        console.log(obj);//将键和值写成对象的形式

        let resArr = [];
        Object.keys(obj).sort().forEach(k => resArr[k] = obj[k]);
        console.log(resArr);//根据对象obj中的键值进行排序

        let res = '';
        for (let i in resArr) {
            res += i + resArr[i];
        }
        console.log(res);//将键和值相加组成新字符串打印输出
    }
    betterCompression('a12c2a4b6');

18 统计字符串中字符个数相关的几道题

    // js统计字符串中某个字符的个数
    let str = "abaabvddb";
    let target = "a"; // 要计算的目标字符
    let regex = new RegExp(target, 'g'); // 使用g表示整个字符串都要匹配
    let result = str.match(regex);
    let count = !result ? 0 : result.length;
    console.log(target + " 的数量为 " + count);


    // js统计字符串每个字符的个数,放入对象中存储
    function findStrNum(str) {
        let strArr = str.split('');
        let obj = {}, current = '';
        for (let i = 0; i < strArr.length; i++) {
            current = strArr[i];
            obj[current] = obj[current] ? ++obj[current] : 1;//注意是赋值=号
        }
        console.log(obj);
    }
    findStrNum('aababbc')

    // js统计字符串每个字符的个数,放入对象中存储,然后求出现次数最多的字符
    function fn(str) {
        let strArr = str.split('');
        let temp = {};
        for (let i = 0; i < strArr.length; i++) {
            temp[strArr[i]] = temp[strArr[i]] ? ++temp[strArr[i]] : 1
        }
        console.log(temp);
        let key = '', value = 1;
        for (let k in temp) {
            console.log(k);
            if (temp[k] >= value) {
                key = k;
                value = temp[k];
            }
        }
        console.log(key + ' ' + value);
    }
    fn('aacbabbdc')

19 遍历多层对象

在这里插入图片描述
在这里插入图片描述

20 遍历对象:编写一段js代码实现对对象obj={x:1,y:{a:2,b:{c:3,d:4}}}所有值的遍历

let obj = {
        x: 1,
        y: {
            a: 2,
            b: {
                c: 3,
                d: 4
            }
        }
    };
//获取对象所有的key值
function getKeys(obj) {
    //es6新语法  Object.prototype.toString()方法精准判断参数值属于哪种类型
    if(Object.prototype.toString.call(obj) === "[object Object]") {
        let arr = [];
        let arrValue = [];
        let arrKeyValue = [];
        (function getKeysFn(o, char) {
            for(let key in o) {
                //判断对象的属性是否需要拼接".",如果是第一层对象属性不拼接,否则拼接"."
                let newChar = char == "" ? key : char + "." + key;
                if(Object.prototype.toString.call(o[key]) === "[object Object]") {
                    //如果属性对应的属性值仍为可分解的对象,使用递归函数继续分解,直到最里层
                    getKeysFn(o[key],newChar);
                } else {
                    arrValue.push(o[key]);
                    arr.push(newChar);
                    arrKeyValue.push(newChar + "=" + o[key]);
                }
            }
        })(obj,"");
        console.log(arr);
        console.log(arrValue);
        console.log(arrKeyValue);
    } else {
        console.log("传入的不是一个真正的对象哦!");
    }
}
getKeys(obj);

21 数字翻转

对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0,负数去掉负号再翻转。例如:
如果 X = 123,则rev(X) = 321;
如果 X = -123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1
在这里插入图片描述

22 将对象数组中的键大写改为小写

let goodsSpecJSON = [{
                "SpecA": "颜色"
            }, {
                "SpecB": "容量"
            }, {
                "SpecC": "大小"
            }, {
                "SpecD": "尺寸"
            }, {
                "SpecE": "套餐"
            }];

原数据转换小写

goodsSpecJSON = goodsSpecJSON.map(function (keyo) {
  console.log(keyo)  // 对象数组中的某一个元素(其中的对象,如 {"SpecA": "颜色"})
  let key = Object.keys(keyo)[0];
  let newkey = key.substring(0, 1).toLowerCase() + key.substring(1);  // "specA"
  let dic = {};  // 定义一个新的空对象
  dic[newkey] = keyo[key];
  return dic
});
console.log(goodsSpecJSON)
  // [{"specA": "颜色"
  // }, {
  //     "specB": "容量"
  // }, {
  //     "specC": "大小"
  // }, {
  //     "specD": "尺寸"
  // }, {
  //     "specE": "套餐"
  // }];
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值