【问题标题】:Good algorithm for generating A-Z by given A-Z通过给定的 A-Z 生成 A-Z 的好算法
【发布时间】:2017-03-23 21:19:05
【问题描述】:

我不知道如何最好地命名我的问题,这是问题:

有一个函数 y = f(x)

x 的域是一组 [A-Z] 组合的字符串

输出 y 是 x 的一个字母。

例如:

x = A -> y = B

x = Z -> y = AA

x = AB -> y = AC

x = ZZ -> y = AAA

x = ZZA -> y = ZZB

有没有人有在javascript中实现这个的好方法?

我现在拥有的是非常完整的条件检查,如果 Z 则 A,一次一个字符。

【问题讨论】:

  • 所以您正在实施一个以 26 为基数的计数系统?
  • @MikeC 你怎么解决问题0,如果A = 1,Z = 26. Z + 1 != A. 如果A = 0 如何表示AAA?
  • 有趣的问题 - 很想在面试中使用它:)

标签: javascript algorithm


【解决方案1】:

这样做的一种方法是查看流中的最后一个字母,并尝试通过将其转换为字符代码来将其增加一个。如果它已经是 Z,将最后一个重置为 A,然后在第二个到最后一个字母上重复该过程。重复直到结束。

function increment(x) {
  if (!x) {
    return '';
  }

  // Convert the string into an array of characters
  let chars = x.split('');
  
  let i = chars.length - 1;
  for (; i >= 0; i--) {
    let oldChar = chars[i];
    if (oldChar === 'Z') {
      // If it's a Z, reset to A and process
      // the previous letter in the sequence
      chars[i] = 'A';
    } else {
      // Convert the character to a character code
      let code = chars[i].charCodeAt(0);
      // Increment that code and convert it back to a character
      let newChar = String.fromCharCode(code + 1);
      
      // Replace the existing letter
      chars[i] = newChar;
      break;
    }
  }

  // If we got all the way to the end, that means that all
  // of the letters were Z's that have now been converted
  // to A's. Append one more A to finish the incrementing
  if (i === -1) {
    chars.push('A');
  }

  // Join the array of characters together to form a string
  return chars.join('');
}

console.log(increment('A'));   // B
console.log(increment('Z'));   // AA
console.log(increment('AB'));  // AC
console.log(increment('ZZ'));  // AAA
console.log(increment('ZZA')); // ZZB

【讨论】:

    【解决方案2】:

    将它们转换为整数。这有点奇怪,因为需要跳过“前导零”:

    function decode(str) {
        var i = str.toUpperCase().charCodeAt(str.length-1) - 65; // A=0, B=1, …
        return str.length == 1 ? i : i+26*(1+decode(str.slice(0,-1)));
    }
    function encode(i) {
        var c = String.fromCharCode((i % 26) + 65);
        return i >= 26 ? encode(Math.floor(i / 26)-1)+c : c;
    }
    

    但是你的功能是微不足道的:

    function f(x) {
       return encode(1 + decode(x));
    }
    

    【讨论】:

      【解决方案3】:

      另一种编码/解码解决方案,命令式和带测试。

      const decode = n => {
        let r = [];
        let i = n;
        while (i) {
          r.push((i-1) % 26);
          i = Math.floor((i-1) / 26);
        }
        return r.reverse().map(c => String.fromCharCode(c + 65));
      };
      
      const encode = s => {
        const digits = s.split('').map(c => c.charCodeAt(0) - 65);
        let n = 0;
        while (digits.length) {
          let c = digits.shift() + 1;
          n *= 26;
          n += c;
        }
        return n;
      };
      
      const next = s => decode(encode(s) + 1).join('');
      
      const tests = [
        ['A','B'],
        ['Z', 'AA'],
        ['AA','AB'],
        ['BB','BC'],
        ['BC','BD'],
        ['ZZ', 'AAA'],
        ['ZYZ', 'ZZA'],
        ['ZZA', 'ZZB'],
      ]
      
      tests.map(parts => {
        if (next(parts[0]) !== parts[1]) {
          throw 'test failed for ' + parts[0];
        }
        console.log(parts[0], '->', next(parts[0]));
      });
      

      【讨论】:

        猜你喜欢
        • 2016-02-26
        • 2012-01-15
        • 1970-01-01
        • 2016-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-01
        相关资源
        最近更新 更多