PHP: преобразование числа в алфавит и наоборот - PullRequest
19 голосов
/ 05 октября 2011

Итак, у меня есть эта функция:

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

с указанным числом преобразует его в символ, и он отлично работает

но тогда я также хочу использовать обратную функцию, которая при любом выходе этой функции возвращает точный ввод, который был введен для получения этого вывода, и я попробовал это:

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

но это не работает должным образом ... toAlpha (728) производит 'aba', но toNum ('aba') производит 1378, а не 728 ...

что я сделал не так? как исправить функцию реверса, чтобы она работала правильно?

спасибо заранее!

Ответы [ 9 ]

74 голосов
/ 25 октября 2015

Кратчайший путь в PHP> = 4.1.0

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

echo $alphabet[3]; // returns D

echo array_search('D', $alphabet); // returns 3
13 голосов
/ 05 октября 2011

Я совсем не понимаю логику, которую вы пытаетесь использовать в этой функции. То, что вы пытаетесь сделать, кажется очень странным (почему «а» отображается на ноль, а «аа» отображается на 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;
}
5 голосов
/ 10 мая 2016

От цифры к алфавиту (с A = 0, B = 1 и т. Д.):

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

Вы можете сделать то же самое с алфавита на номер с помощью функции ord().

Изменяя 65 на 97, вы можете получить значения в нижнем регистре.

4 голосов
/ 04 октября 2013

Ваши проблемы связаны с вашей картой. Посмотрите на это:

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

Вы можете запустить это так высоко, как вы хотите, и ваша память сервера позволит. PHP глючит, и (по крайней мере, на моем сервере), если вы используете оператор <=: </p>

$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
    $alpha[] = $i;
}

тогда он будет отображаться до [676] => string (2) "yz"! Вы просто должны играть с этим.

Я не хотел отображать букву в [0], поэтому я просто добавил туда заголовок. Очевидно, вы можете оставить это, если хотите 0 => a, 1 => b и т. Д.

Если массив верен, функция тривиальна.

1 голос
/ 18 марта 2019

Используя ответ Кирилла, я немного уточнил случай с несколькими буквами.

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

Ниже приведены несколько результатов для функции:

lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83
1 голос
/ 24 ноября 2017
// to convert number to alphacode
// for ex 1402 to bax

function number_to_alpha($num, $code) {<br> $alphabets = 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');</p> <pre><code>$division = floor($num / 26); $remainder = $num % 26; if($remainder == 0) { $division = $division - 1; $code .= 'z'; } else $code .= $alphabets[$remainder]; if($division > 26) return number_to_alpha($division, $code); else $code .= $alphabets[$division]; return strrev($code);

}

// to convert alphacode to number
// for ex  bax to 1402

function alpha_to_number($code) { $alphabets = 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');</p> <pre><code>$sumval = 0; $code = strtolower(trim($code)); $arr = str_split($code); $arr_length = count($arr); for($i = 0, $j = $arr_length-1; $i < $arr_length; $i++, $j--) { $arr_value = array_search($arr[$i], $alphabets); $sumval = $sumval + ($arr_value * pow(26, $j)); } return $sumval;

}

1 голос
/ 11 февраля 2017

Я взял «исправленный» оригинал, удалил код отладки и другой ненужный код, изменил его, чтобы он работал с любым количеством символов.Например, греческий имеет только 24 символа.

function toAlpha($number, $alphabet)
    {

        $count = count($alphabet);
        if ($number <= $count) {
            return $alphabet[$number - 1];
        }
        $alpha = '';
        while ($number > 0) {
            $modulo = ($number - 1) % $count;
            $alpha  = $alphabet[$modulo] . $alpha;
            $number = floor((($number - $modulo) / $count));
        }
        return $alpha;
    }

    toAlpha(45,range('a','z'));

А вот несколько примеров диапазонов:

// lower greek
$range = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'];
// upper greek 
$range = ['Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', 'Π', 'Ρ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω'];
// georgian 
$range = ['ჵ' => 10000, 'ჰ' => 9000, 'ჯ' => 8000, 'ჴ' => 7000, 'ხ' => 6000, 'ჭ' => 5000, 'წ' => 4000, 'ძ' => 3000, 'ც' => 2000, 'ჩ' => 1000, 'შ' => 900, 'ყ' => 800, 'ღ' => 700, 'ქ' => 600, 'ფ' => 500, 'ჳ' => 400, 'ტ' => 300, 'ს' => 200, 'რ' => 100, 'ჟ' => 90, 'პ' => 80, 'ო' => 70, 'ჲ' => 60, 'ნ' => 50, 'მ' => 40, 'ლ' => 30, 'კ' => 20, 'ი' => 10, 'თ' => 9, 'ჱ' => 8, 'ზ' => 7, 'ვ' => 6, 'ე' => 5, 'დ' => 4, 'გ' => 3, 'ბ' => 2, 'ა' => 1];
0 голосов
/ 14 октября 2014

Вот исправление к оригинальной функции Альфа.Это не работает для Альфы (27)

function toAlpha($n,$case = 'upper'){
    $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');
    $n = $n-1;
    Util::error_log('N'.$n);
    if($n <= 26){
        $alpha =  $alphabet[$n-1];
    } elseif($n > 26) {
        $dividend   = ($n);
        $alpha      = '';
        $modulo;
        while($dividend > 0){
            $modulo     = ($dividend - 1) % 26;
            $alpha      = $alphabet[$modulo].$alpha;
            $dividend   = floor((($dividend - $modulo) / 26));
        }
    }

    if($case=='lower'){
        $alpha = strtolower($alpha);
    }
    Util::error_log("**************".$alpha);
    return $alpha;

}
0 голосов
/ 28 сентября 2014
function toNum($str) {
  $num = 0;
  for ($i = 0; $i < strlen($str); $i++) {
    $num += ord($str[$i]);
    $num *= 26;
  }
  return $num;
}

function toStr($num) {
  $str = '';
  while ($num > 0) {
    $str = chr($num % 26) . $str;
    $num = (int) ($num / 26);
  }
  return $str;
} 
...