webentwicklung-frage-antwort-db.com.de

php: Zahl in Alphabet umwandeln und umgekehrt

Ich habe also diese Funktion:

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

welche gegebene Zahl wandelt sie in Zeichen um und es funktioniert gut

aber ich möchte auch eine umgekehrte Funktion davon, dass bei jeder Ausgabe dieser Funktion die genaue Eingabe zurückgegeben wird, die in diese Ausgabe eingegeben wurde, und ich habe Folgendes versucht:

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

aber es funktioniert nicht richtig ... toAlpha (728) produziert 'aba', aber toNum ('aba') produziert 1378 anstatt 728.

was habe ich falsch gemacht? Wie kann ich die Umkehrfunktion korrigieren, damit sie richtig funktioniert?

danke im Voraus!

19
pillarOfLight

Ich verstehe überhaupt nicht die Logik, die Sie in dieser Funktion verwenden wollen. Was Sie zu tun versuchen, scheint sehr seltsam zu sein (warum wird "a" eine Karte zu Null und doch "aa" zu 26?). (Sie möchten einige weitere Testfälle verwenden. Ich habe nur überprüft, ob die richtige Ausgabe für den Fall 'aba' erfolgt.)

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

Kürzester Weg in PHP> = 4.1.0

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

echo $alphabet[3]; // returns D

echo array_search('D', $alphabet); // returns 3
68
Cyril

Von der Zahl zum Alphabet (mit A = 0, B = 1 usw.):

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

Mit der Funktion ord() können Sie von Alphabet zu Nummer dasselbe tun.

Wenn Sie mit 97 65 ändern, erhalten Sie die Kleinbuchstaben.

4
sara_thepot

Ihre Probleme kommen von Ihrer Karte. Schau dir das an:

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

Sie können dies so hoch ausführen, wie Sie möchten, und der Serverspeicher lässt zu. Das PHP ist fehlerhaft und (zumindest auf meinem Server), wenn Sie den Operator <= verwenden:

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

dann wird der gesamte Weg auf [676] => string (2) "yz" abgebildet! Sie müssen nur damit spielen. 

Ich wollte keinen Brief [0] zuordnen, also habe ich einfach einen Titel dort eingefügt. Natürlich können Sie es weglassen, wenn Sie 0 => a, 1 => b usw. möchten.

Sobald das Array korrekt ist, ist die Funktion trivial.

4
Mason Barge

Unter Verwendung von Cyrils Antwort habe ich ein wenig für einen Fall mit mehr als einem Buchstaben ausgearbeitet.

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

Einige Ergebnisse für die Funktion werden unten angezeigt:

lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83
2
rvbarreto

Ich habe das "korrigierte" Original genommen, den Debug-Code und anderen nicht benötigten Code entfernt und so modifiziert, dass er mit einer beliebigen Anzahl von Zeichen funktioniert. Beispielsweise hat Griechisch nur 24 Zeichen.

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

Und hier sind einige Beispiele für Bereiche:

// 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];
1
Dr. Sassafras
// to convert number to alphacode
// for ex 1402 to bax

function number_to_alpha($num, $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');

$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);
 </ pre> 

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

$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;
 </ pre> 

} </ code>

1
Praveen

Es gibt eine sehr clevere Lösung von Theriault in den Kommentaren von PHPs base_convert-Funktion

/**
* 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;
}
0
user414873

Hier ist ein Fix für die ursprüngliche Funktion von Alpha. Es funktioniert nicht für toAlpha (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
Santosh Pradhan