php:将数字转换为字母,反之亦然

pil*_*ght 19 php string math reverse function

所以我有这个功能:

function toAlpha($data){
    $alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
    if($data <= 25){
      return $alphabet[$data];
    }
    elseif($data > 25){
      $dividend = ($data + 1);
      $alpha = '';
      $modulo;
      while ($dividend > 0){
        $modulo = ($dividend - 1) % 26;
        $alpha = $alphabet[$modulo] . $alpha;
        $dividend = floor((($dividend - $modulo) / 26));
      } 
      return $alpha;
    }
}
Run Code Online (Sandbox Code Playgroud)

给出一个数字将其转换为字符,它工作正常

但是我还想要一个这样的反向函数,给定这个函数的任何输出,返回输入的确切输入以产生该输出,我试过这个:

function toNum($data){
$alphabet =   array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
    $alpha_flip = array_flip($alphabet);
  if(strlen($data) == 1){
          return (isset($alpha_flip[$data]) ? $alpha_flip[$data] : FALSE);
        }
        else if(strlen($data) > 1){
          $num = 1;
          for($i = 0; $i < strlen($data); $i++){
            if(($i + 1) < strlen($data)){
              $num *= (26 * ($alpha_flip[$data[$i]] + 1));
            }
            else{
              $num += ($alpha_flip[$data[$i]] + 1);
            }
          }
          return ($num + 25);
        }
}
Run Code Online (Sandbox Code Playgroud)

但是它没有正常工作...... toAlpha(728)正在生产'aba'但是toNum('aba')正在生产1378而不是728 ......

我做错了什么?如何修复反向功能以使其正常工作?

提前致谢!

Cyr*_*ril 83

最简单的方法,在PHP> = 4.1.0

$alphabet = range('A', 'Z');

echo $alphabet[3]; // returns D

echo array_search('D', $alphabet); // returns 3
Run Code Online (Sandbox Code Playgroud)


Ham*_*ite 13

我完全不了解你在该功能中尝试使用的逻辑.你想要做的事情看起来很奇怪(为什么'''地图为零,而'aa'映射到26?),但这似乎有效.(您将需要使用更多测试用例,我只检查它为案例'aba'提供了正确的输出.)

function toNum($data) {
    $alphabet = array( 'a', 'b', 'c', 'd', 'e',
                       'f', 'g', 'h', 'i', 'j',
                       'k', 'l', 'm', 'n', 'o',
                       'p', 'q', 'r', 's', 't',
                       'u', 'v', 'w', 'x', 'y',
                       'z'
                       );
    $alpha_flip = array_flip($alphabet);
    $return_value = -1;
    $length = strlen($data);
    for ($i = 0; $i < $length; $i++) {
        $return_value +=
            ($alpha_flip[$data[$i]] + 1) * pow(26, ($length - $i - 1));
    }
    return $return_value;
}
Run Code Online (Sandbox Code Playgroud)

  • $ alphabet = range('a','z'); (24认同)
  • Excel这样做.也许@pillarOfLight试图通过电子表格来解决问题. (7认同)
  • 在以10为底的情况下,9的后继者不是00。那么为什么aa是z的后继者呢? (2认同)

use*_*873 10

PHP 的 base_convert 函数的注释中,Theriault 有一个非常聪明的解决方案

/**
* Converts an integer into the alphabet base (A-Z).
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function num2alpha($n) {
    $r = '';
    for ($i = 1; $n >= 0 && $i < 10; $i++) {
    $r = chr(0x41 + ($n % pow(26, $i) / pow(26, $i - 1))) . $r;
    $n -= pow(26, $i);
    }
    return $r;
}
/**
* Converts an alphabetic string into an integer.
*
* @param int $n This is the number to convert.
* @return string The converted number.
* @author Theriault
* 
*/
function alpha2num($a) {
    $r = 0;
    $l = strlen($a);
    for ($i = 0; $i < $l; $i++) {
    $r += pow(26, $i) * (ord($a[$l - $i - 1]) - 0x40);
    }
    return $r - 1;
}
Run Code Online (Sandbox Code Playgroud)


Mas*_*rge 5

您的问题来自您的地图。看这个:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<'z'; $i++) {
    $alpha[] = $i;
}
$alpha[26] = 'z';
Run Code Online (Sandbox Code Playgroud)

您可以根据需要将其运行得很高,并且服务器内存将允许。PHP是错误的,并且(至少在我的服务器上)使用了<=运算符:

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
    $alpha[] = $i;
}
Run Code Online (Sandbox Code Playgroud)

那么它将一直映射到[676] => string(2)“ yz”!您只需要玩。

我不想将字母映射到[0],所以只在其中放置了一个标题。显然,如果要0 => a,1 => b等,则可以省去。

一旦数组正确,该函数就变得微不足道了。


sar*_*pot 5

从数字到字母(A = 0,B = 1等):

function toAlpha($num){
    return chr(substr("000".($num+65),-3));
}
Run Code Online (Sandbox Code Playgroud)

您可以使用函数从字母到数字执行相同的操作ord()

用97更改65,可以获得小写值。


rvb*_*eto 5

使用西里尔的回答,我对一个包含多个字母的案例进行了一些详细说明。

function lettersToNumber($letters){
    $alphabet = range('A', 'Z');
    $number = 0;

    foreach(str_split(strrev($letters)) as $key=>$char){
        $number = $number + (array_search($char,$alphabet)+1)*pow(count($alphabet),$key);
    }
    return $number;
}
Run Code Online (Sandbox Code Playgroud)

该函数的一些结果显示如下:

lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83
Run Code Online (Sandbox Code Playgroud)