題庫練習一

  1. 實現一個檢驗對象是否循環指向的方法
/** 實現一個檢驗對象是否循環指向的方法
  說明:當一個對象存在對自身引用時,稱之循環指向
  如`var o = { a: {} }; o.a = o;`
  o -> a -> o 就形成循環指向
  示例:
  isCyclic(window); // true
  isCyclic({}); // false
  var o = {}; o.o = o;
  isCyclic(o); // true

  var obj = { foo: { bar: { baz: { qux:{} } } } };
  obj.foo.bar.baz.qux = obj.foo;
  isCyclic(obj); // true
*/

function isCyclic (obj) {
  const arr = [];
  function check(childObj) {
    let res = false
    for(let i in childObj) {
      if (typeof childObj[i] === 'object' && childObj[i]!==null){
        if(!arr.includes(childObj[i])) {
          arr.push(childObj[i])
          res = check(childObj[i])
        } else {
          return true
        }
      }
    }
    return res
  }
  return check(obj)
}

console.log(isCyclic(window)); // true
console.log(isCyclic({})); // false
var o = {}; o.o = o;
console.log(isCyclic(o)); // true

var obj = { foo: { bar: { baz: { qux:{} } } } };
obj.foo.bar.baz.qux = obj.foo;
console.log(isCyclic(obj)); // true
  1. 實現一個評星方法
/** 實現一個評星方法
  說明:
  1. 可根據傳入的評分和總數,返回評星結果(用 ★ 和 ☆ 描述)
  2. 評分必選,四捨五入,總數可選,大於0的整數,默認爲5
  3. 對於評分爲空或小於0、評分大於總數、總數小於等於0或總數非整數的情況,返回'error'
  示例:
  getRate(4); // ★★★★☆
  getRate(4, 8); // ★★★★☆☆☆☆
  getRate(3.4); // ★★★☆☆
  getRate(5, 2); // 'error'
  getRate(-2); // 'error'
  getRate(3, 5.5); // 'error'
*/

function getRate (score, total) {
  let err = 'error'
  // 校驗類型
  if (typeof score !== 'number') {
    return err;
  }
  if (total !== undefined && (typeof total) !== 'number') {
    return err;
  }
  total = total === undefined ? 5 : total;
  score = Math.round(score)
  // 校驗格式
  if (score < 0 || score > total) {
    return err;
  }
  if (total <= 0 || total.toString().includes('.')) {
    return err;
  }
  let res = Array(total).fill('★',0, score).fill('☆', score);
  return res.join('');
}

console.log(getRate(4)); // ★★★★☆
console.log(getRate(4, 8)); // ★★★★☆☆☆☆
console.log(getRate(3.4)); // ★★★☆☆
console.log(getRate(5, 2)); // 'error'
console.log(getRate(-2)); // 'error'
console.log(getRate(3, 5.5)); // 'error'
  1. 判斷括號匹配
/** 判斷括號匹配
  說明:給定一個只包含'() {} []'6種字符的字符串
    實現一個方法來檢測該字符串是否合法,其規則爲'()'、'{}'、'[]'必須互相匹配、可嵌套
  示例:
    isValid('(');           // false
    isValid('()');          // true
    isValid('()[]{}');      // true
    isValid('{()[]}');      // true
    isValid('(]');          // false
    isValid('([)]');        // false
    isValid('({}[]([]))');  // true
*/

function isValid (str) {
  let endChar = [];
  for(let i = 0; i < str.length; i++) {
    switch (str[i]) {
      case '(':
        endChar.push(')')
        break;
      case '[':
        endChar.push(']')
        break;
      case '{':
        endChar.push('}')
        break;
      default:
        if (endChar.pop() !== str[i]) {
          return false
        }
        break;
    }
  }
  return endChar.length === 0
}

console.log(isValid('('));           // false
console.log(isValid('()'));          // true
console.log(isValid('()[]{}'));      // true
console.log(isValid('{()[]}'));      // true
console.log(isValid('(]'));          // false
console.log(isValid('([)]'));        // false
console.log(isValid('({}[]([]))'));  // true
  1. 給定一個編碼字符,按編碼規則進行編碼,輸出字符串
/** 給定一個編碼字符,按編碼規則進行編碼,輸出字符串
  編碼規則是`count[letter]`,將letter的內容count次輸出
  count是0或整數,letter是區分大小寫的純字母
  示例:
  const s = '3[a]2[bc]'; decodeString(s); // 返回'aaabcbc'
  const s = '3[a2[c]]'; decodeString(s); // 返回'accaccacc'
  const s = '2[abc]3[cd]ef'; decodeString(s); // 返回'abcabccdcdcdef'
*/

function decodeString (str) {
  let letterReg = /(?<count>\d+)\[(?<letter>[a-zA-Z]*)\]/
  function replaceStr (count, letter) {
    return Array(count).fill(letter).join('')
  }
  while(letterReg.test(str)) {
    const {count, letter} = str.match(letterReg).groups
    str = str.replace(letterReg, replaceStr(Number(count), letter))
  }
  return str;
}

const s = '3[a]2[bc]';
console.log(decodeString(s)); // 返回'aaabcbc'
const s2 = '3[a2[c]]';
console.log(decodeString(s2)); // 返回'accaccacc'
const s3 = '2[abc]3[cd]ef';
console.log(decodeString(s3)); // 返回'abcabccdcdcdef'
  1. 平鋪節點數組轉嵌套樹
/** 平鋪節點數組轉嵌套樹
  說明:將一個包含深度信息的節點數組轉換成一棵樹,要求只能遍歷一次該數組
  輸入值:TreeNode數組 TreeNode爲包含depth(正整數,深度不限)字段的Object
  輸出值:組裝好的嵌套樹,子節點掛載在對應父節點的children字段上
  示例:
  輸入:[
    { depth: 1 },
    { depth: 2 },
    { depth: 3 },
    { depth: 3 },
    { depth: 2 },
    { depth: 1 },
    { depth: 2 },
  ]
  輸出:[
    { "depth": 1, "children": [{"depth":2,"children":[{"depth":3},{"depth":3}]},{"depth":2}] },
    { "depth": 1, "children": [{"depth":2}]}
  ]
*/

function arrayToTree(arr) {
  const ans = [];
  // 定位
  let pos = []
  
  for (let obj of arr) {
    setPos(obj.depth)
    arrayToTreeHelper(pos, obj.depth);
  }

  return ans;

  // 更新定位
  function setPos(depth) {
    if (depth <= pos.length) {
      pos = pos.slice(0,depth)
    }
    pos[depth-1] = (pos[depth-1] || 0) + 1
  }

  // 嵌套每一項
  function arrayToTreeHelper(pos, depth) {
    if (depth === 1) {
      ans.push({
        depth: depth
      })
      return;
    }
    
    pos.reduce((end,curt,index) => {
      if (index === 0) {
        return end[curt-1]
      }
      end.children = end.children || []
      if(end.children[curt-1] === null || end.children[curt-1] === undefined) {
        end.children[curt-1] = {
          depth: depth
        }
      }
      return end.children[curt-1]
    }, ans)
  }
}

const arr = [
  { depth: 1 },
  { depth: 2 },
  { depth: 3 },
  { depth: 3 },
  { depth: 2 },
  { depth: 1 },
  { depth: 2 },
]
console.log(JSON.stringify(arrayToTree(arr)))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章