2013-01-16 10 views
6

Come posso scrivere una funzione che mi dà il numero del carattere che viene passato ad essoPHP funzione per ottenere carattere Numero

Ad esempio, se il nome funciton è GetCharacterNumber e passo B ad esso allora dovrebbe dare mi 2

GetCharacterNumber("A") // should print 1 
GetCharacterNumber("C") // should print 3 
GetCharacterNumber("Z") // should print 26 
GetCharacterNumber("AA") // should print 27 
GetCharacterNumber("AA") // should print 27 
GetCharacterNumber("AC") // should print 29 

E 'anche possibile per raggiungere questo obiettivo?

+0

È un ordine personalizzato? Hai un tavolo con tutti i valori possibili? – Deleteman

+0

Vuoi che restituisca valori per "AAA", "AAHJSNDJS" ecc.? –

+0

Cosa restituire 'BA'? – h2ooooooo

risposta

3

Non è molto efficiente, ma ottiene il lavoro fatto:

function get_character_number($end) 
{ 
    $count = 1; 
    $char = 'A'; 
    $end = strtoupper($end); 
    while ($char !== $end) { 
     $count++; 
     $char++; 
    } 
    return $count; 
} 

echo get_character_number('AA'); // 27 

demo

Questo funziona perché quando si ha qualcosa come $char = 'A' e fai $char++, cambierà a 'B', poi 'C' , 'D', ... 'Z', 'AA', 'AB' e così via.

Si noti che questo diventerà il più lento il più lungo è $end. Non lo consiglierei per qualcosa che vada oltre "ZZZZ" (475254 iterazioni) o se hai bisogno di molte ricerche del genere.

Un più performante alternativa sarebbe

function get_character_number($string) { 
    $number = 0; 
    $string = strtoupper($string); 
    $dictionary = array_combine(range('A', 'Z'), range(1, 26)); 
    for ($pos = 0; isset($string[$pos]); $pos++) { 
     $number += $dictionary[$string[$pos]] + $pos * 26 - $pos; 
    } 
    return $number; 
} 

echo get_character_number(''), PHP_EOL; // 0 
echo get_character_number('Z'), PHP_EOL; // 26 
echo get_character_number('AA'), PHP_EOL; // 27 

demo

+0

Questo è fantastico .. non posso ringraziarti sufficiente – skos

+0

@Sachyn La versione con [ord] (http://stackoverflow.com/a/14358603/956397) è più veloce e più pulita. – PiTheNumber

+0

Per una soluzione più ottimale verifica la mia risposta, ad esempio ha funzionato per 'ZZASDAASDAA', il risultato è stato generato in 0,0001 secondi. –

11

C'è una funzione denominata ord che fornisce il numero ASCII del carattere.

fornisce il risultato corretto per un carattere. Per stringhe più lunghe, puoi utilizzare un ciclo.

<?php 
    function GetCharacterNumber($str) { 
     $num = 0; 
     for ($i = 0; $i < strlen($str); $i++) { 
      $num = 26 * $num + ord($str[$i]) - 64; 
     } 
     return $num; 
    } 
    GetCharacterNumber("A"); //1 
    GetCharacterNumber("C"); //3 
    GetCharacterNumber("Z"); //26 
    GetCharacterNumber("AA"); //27 
    GetCharacterNumber("AC"); //29 
    GetCharacterNumber("BA"); //53 
?> 
+0

Ho corretto il mio ciclo – Dutow

+1

per AA, genrate (((0 * 26) +1) * 26) +1, che è la risposta corretta. Per BA, è (((0 * 26) +2) * 26) +1, che è anche corretto, penso. Quindi le doppie lettere sono corrette. Per "AAA", calcola 26 * 27 + 1, che dovrebbe anche essere corretto (26 per le singole lettere, 26 * 26 per le doppie lettere, e questo è il primo codice di tre lettere) – Dutow

1

Ecco il codice completo che fa ciò che vuoi.

Testato e funziona perfettamente per gli esempi che hai fornito.

define('BASE', 26); 

function singleOrd($chr) { 
    if (strlen($chr) == 1) { 
     return (ord($chr)-64); 
    } else{ 
     return 0; 
    } 
} 


function multiOrd($string) { 
    if (strlen($string) == 0) { 
     return 0; 
    } elseif (strlen($string) == 1) { 
     return singleOrd($string); 
    } else{ 
     $sum = 0; 
     for($i = strlen($string) - 1; $i >= 0; $i--) { 
      $sum += singleOrd($string[$i]) * pow(BASE, $i); 
     } 
    } 
    return $sum; 
} 
3

Gamma di uso e strpos:

$letter = 'z'; 
$alphabet = range('a', 'z'); 
$position = strpos($alphabet, $letter); 

Per le lettere doppie (ad esempio zz) si sarebbe probabilmente necessario creare il proprio alfabeto utilizzando una funzione personalizzata:

$alphabet = range('a', 'z'); 
$dictionary = range('a','z'); 
foreach($alphabet AS $a1){ 
    foreach($alphabet AS $a2) { 
     $dictionary[] = $a1 . $a2; 
    } 
} 

Quindi utilizzare $ dizionario al posto di $ alfabeto.

0

penso ord dovrebbe essere un modo più efficiente per avere il tuo numero:

$string = strtolower($string); 
$result = 0; 
$length = strlen($string); 
foreach($string as $key=>$value){ 
    $result = ($length -$key - 1)*(ord($value)-ord(a)+1); 
} 

e il risultato sarebbe contenere ciò che si vuole .

Problemi correlati