【华为机试】入门/简单

365 阅读3分钟

HJ4 字符串分隔

方法1

const str = readline()
function splitStr(str){
    if(str.length%8 != 0){
        const zeroNum = 8 - str.length%8;
        str = str.padEnd(str.length+zeroNum,'0')
    }
   for (let i=0;i<str.length/8; i++){
    console.log(str.slice(i*8,i*8+8))
   }
}
splitStr(str)

方法2

while(str = readline()){
    str +='0000000'
    const length = Math.floor(str.length/8)
    for(i=0;i<length;i++){
        console.log(str.substr(i*8,8))
    }
}

字符串补齐方法:padEnd(),padStart()

HJ10 字符个数统计

//char.charCodeAt()范围在0到127
//去重
while(line = readline()){
    const arr = line.split('')
    const uniqueCharArr = arr.filter((item,index,arr)=>{
        if(item.charCodeAt()<=127&&item.charCodeAt()>=0){
            if(arr.indexOf(item,0)=== index) return true;
            else return false;
        }else return false;
    })
    console.log(uniqueCharArr.length);
}

HJ7 取近似值

while(line = readline()){
    let num = parseFloat(line);
    console.log(Math.round(num));
}

Math.round()四舍五入 Math.floor()向下取整 Math.ceil()向上取整

这道题也可以取出小数部分,与0.5进行比较,再处理

浮点数取小数部分、整数部分:

var num = "23.56";
var numArray = a.split(".");
var numInt=numArray[0];
var numdecimal=numArray[1];

HJ31 单词倒排

方法1:

while(line=readline()){
    let inputs = line.split("");
    let arr = inputs.map((x)=>{
        if(x.charCodeAt()<65 || x.charCodeAt()>122) return 0;
        else return x;
    })
    let str = arr.join("");
    let resArr = str.split("0");
    resArr = resArr.reverse();
    console.log(resArr.join(" "));
}

不是字母的部分全部改成0,再拼接成字符串,再以0为分割拆开,反向后再拼接起来

方法2:

while(line=readline()){
    const arr = line.split(/[^A-Za-z]+/).reverse().join(" ");
    console.log(arr);   
}

利用正则表达式,非字母部分分割

HJ21 简单密码

while(line=readline()){
    let inputs = line.split("");
    //String.fromCharCode()
    //大写65-90 小写97-122
    let res = inputs.map((x)=>{
        return passwordChage(x)
    });
    console.log(res.join(""));
//     console.log(passwordChage('Z'))
}
function passwordChage(char){
    //数字
    if(!isNaN(parseInt(char))){
        return parseInt(char)
    }
    //大写字母
    else if(char<'a'){
        let code = char.charCodeAt()+32+1;
        if(code>122) code=97;
        return String.fromCharCode(code)
    }
    //小写字母
    else{
      if(char<='r') return Math.ceil(char.charCodeAt()/3-31);
      else if(char === 's') return 7;
      else if(char<="v")  return 8;
      else return 9;
    }
}

判断字符类型还可以用正则表达式 /[0-9]/.test(char)

HJ23 删除字符串中出现次数最少的字符

while(line = readline()){
    const lines =line.split("");
    //用map存字符和出现次数
    const charMap = new Map();
    for(let i=0;i<lines.length;i++){
        if(!charMap.has(lines[i])){
            charMap.set(lines[i],1);
        }else{
            const newVal = charMap.get(lines[i])+1;
            charMap.set(lines[i],newVal)
        }
    }
    let keys =charMap.keys();
    const arr = [...keys];
    //计算最少的次数
    let minCount = Infinity;
    let temps=[];
    for(let i=0;i<arr.length;i++){
        if(charMap.get(arr[i])<=minCount){
            minCount = charMap.get(arr[i]);
            temps.push(arr[i]);
        }
    }
    //出现次数最少的字符 数组,有可能多个字符出现的次数都最少
    let minChar = [];
    while(charMap.get(temps[temps.length-1]) === minCount){
        minChar.push(temps.pop());
    }
    //把出现次数最少的字符过滤掉
    let resArr = lines.filter(x=>{
        return minChar.indexOf(x)===-1;
    })
    console.log(resArr.join(""));  
}

HJ73 计算日期到天数的转换

方法1:

while(line=readline()){
    const inputs = line.split(" ");
    const year = parseInt(inputs[0]);
    const month = parseInt(inputs[1]);
    const date = parseInt(inputs[2]);
    let days = -2;
    if(year%400===0||(year%4===0&&year%100!=0)){
        days++;
    }
    if(month>8){
        days+=(month-1)*30+Math.ceil(month/2)+date
    }else if(month>2){
        days+=(month-1)*30+Math.floor(month/2)+date
    }else{
        days=(month-1)*30+Math.floor(month/2)+date
    }
    console.log(days)
}

方法2:

使用Date对象

while(line=readline()){
    const inputs = line.split(" ");
    const year = parseInt(inputs[0]);
    const month = parseInt(inputs[1]);
    const date = parseInt(inputs[2]);
    const ms=new Date(year,month-1,date)-new Date(year,0,0);
    const days = ms/(1000*60*60*24);
    console.log(days);
}

HJ76 尼科彻斯定理

规律 第一个数=n(n-1)+1 最后一个数n(n+1)-1

while(line=readline()){
    const arg =parseInt(line);
    let str = "";
    const start = arg*(arg-1)+1;
    const end = arg*(arg+1)-1;
    for(let i=start;i<end;i=i+2){
        str=str+i;
        str=str+"+";
    }
    str=str+end;
    console.log(str);
}

也可以用arr.push() arr.join("+"),不过要求空间复杂度O(1)

HJ54 表达式求值

方法1:

直接用eval(), eval()函数会将传入的字符串当做JavaScript代码进行执行。

while(line=readline()){
    console.log(eval(line));
}

方法2:

题解上看到的

  • 构建运算符对象,增加优先级
  • 构建取出两个数和一个运算符计算的函数
  • 构建主函数,初始化双栈
const opsMap = {
  "+": 1,
  "-": 1,
  "*": 2,
  "/": 2,
};

const calc = (nums = [], ops = []) => {
//   console.log(nums, ops)
  if (nums.length < 2 || ops.length === 0) return;
  const op = ops.pop();
  const b = ~~nums.pop();
  const a = ~~nums.pop();
//   console.log(op, a, b)

  switch (op) {
    case "+":
      nums.push(a + b);
      break;
    case "-":
      nums.push(a - b);
      break;
    case "*":
      nums.push(a * b);
      break;
    default:
      nums.push(a / b);
  }
};

const calculator = (str = "") => {
  const cs = str.split("");
  const nums = [0];
  const ops = [];

  for (let i = 0; i < cs.length; i++) {
    let c = cs[i];
    if (c === "(") {
      // 入栈
      ops.push("(");
      if (cs[i + 1] === "-" || cs[i + 1] === "+") {
        nums.push(0);
      }
    } else if (c === ")") {
      while (ops.length) {
        if (ops[ops.length - 1] !== "(") {
          calc(nums, ops);
        } else {
          ops.pop();
          break;
        }
      }
    } else {
      if (/\d/.test(c)) {s
        while (i + 1 < cs.length && /\d/.test(cs[i + 1])) {
          c += cs[i + 1];
          i++;
        }
        nums.push(c);
      } else {
        // 加减乘除
        while (ops.length && ops[ops.length - 1] !== "(") {
          // 根据优先级进行运算
          const topOp = ops[ops.length - 1];
          if (opsMap[topOp] >= opsMap[c]) {
            calc(nums, ops);
          } else {
            break;
          }
        }
        ops.push(c);
      }
    }
  }
  while (ops.length) calc(nums, ops);
  return nums[nums.length - 1];
};

while(input = readline()) {
  console.log(calculator(input))
}

HJ62 查找输入整数二进制中1的个数

while(line=readline()){
    const binaryArr = parseInt(line).toString(2).split('');
    const sum=binaryArr.reduce((pre,cur)=>parseInt(pre)+parseInt(cur),0);
    console.log(sum);
}

number.toString(base)转换为相应进制的数字字符串

HJ97 计负均正

小数位数 toFixed(bit);

HJ108 求最小公倍数

最小公倍数 = 两数相乘 / 最大公约数
最大公约数:辗转相除法/更相减损

方法一:更相减损

while(line=readline()){
    const lines=line.split(" ");
    let a = parseInt(lines[0]);
    let b = parseInt(lines[1]);
    while(a!=b){
        if(a>b) a=a-b;
        else b=b-a;
    }
    console.log(parseInt(lines[0])*parseInt(lines[1])/a);
}

方法二:辗转相除

while(line=readline()){
    const lines=line.split(" ");
    let a = parseInt(lines[0]);
    let b = parseInt(lines[1]);
    const GCD=gcd(a,b);
    const LCM= a*b/GCD;
    console.log(LCM);
}
function gcd(a,b){
    if(a<b) [a,b]=[b,a];
    if(a%b===0) return b;
    else return gcd(b,a%b);
}

HJ61 放苹果

  • m个苹果 n个盘子
  • 如果有一个空盘子 => 在n-1个盘子放m个苹果
  • 没有空盘子 => n个盘子至少每个盘子有1个 =>m-n个苹果放在n个盘子 递归和动态规划都能做
while(line=readline()){
    const lines=line.split(" ");
    const m = parseInt(lines[0]);
    const n = parseInt(lines[1]);
    console.log(apple(m,n));
}
function apple(m,n){
    if(n<=0||m<0) return 0;
    if(n===1||m===1) return 1;
    else return apple(m-n,n)+apple(m,n-1);
}

HJ6 质数因子

思路: 从k = 2开始进行循环

  • 只要n能够被k整除,就把k放入结果数组,n/k作为新的n继续循环
  • 只要n不能够被k整除,k=k+1;继续循环
  • 当n=1时结束循环

如何保证能整除n的k一定是质数?
当k=i不能整除n时,k=i的倍数肯定也不能整除n,所有质数的倍数都会被排除掉

while(line = readline()){
    let n = parseInt(line);
    const res = [];
    for(let k=2;k<=n;k++){
        while(n%k===0){
            res.push(k);
            n/=k;
        }
    }
    console.log(res.join(" "));
}

HJ91 走方格的方案数

横着要走n步竖着要走m步 下一步要么是横着要么是竖着

迭代:

function steps(n,m){
    if(n<0||m<0) return 0
    else if(n===0||m===0) return 1;
    else return  steps(n-1,m)+steps(n,m-1);
}

动态规划:

function stepsDP(n, m) {
  const dp = [];
  for (let i = 0; i <= n; i++) {
    dp[i] = new Array(m+1).fill(1);
  }
  for (let i = 1; i <= n; i++) {
    for (let j = 1; j <= m; j++) {
      dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
    }
  }
  return dp[n][m];
}