通过给定的A-Z生成A-Z的良好算法

时间:2017-03-23 21:19:06

标签: javascript algorithm

我不知道如何最好地解决我的问题,这就是问题所在:

有一个函数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,一次是char。

3 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是查看流中的最后一个字母,并尝试通过将其转换为字符代码将其增加一。如果它已经是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




答案 1 :(得分:1)

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

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));
}

答案 2 :(得分:1)

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

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]));
});