2013-01-16 15 views
6

我如何编写一个函数,给我传递给它PHP函数来获取字符数

例如字符的数量,如果该功能可按名称为GetCharacterNumber和我通过B到它,然后它应该给我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 

它甚至有可能实现这一目标吗?

+0

这是自定义订单吗?你有一张桌子有所有可能的价值吗? – Deleteman

+0

你想让它返回“AAA”,“AAHJSNDJS”等的值吗? –

+0

'BA'应该返回什么? – h2ooooooo

回答

3

效率不高,但能够完成任务:

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

这工作,因为当你有像$char = 'A'$char++,它会变成“B”,然后“C” ,'D',...'Z','AA','AB'等。

请注意,这会变得越慢,$end就越长。除了'ZZZZ'(475254迭代)之外,我不会推荐这么做,或者你需要很多查找。

一种性能更好的替代方法是

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

这太棒了..不能谢谢你足够 – skos

+0

@Sachyn带[ord]的版本(http://stackoverflow.com/a/14358603/956397)更快更干净。 – PiTheNumber

+0

为了更好的解决方案检查我的答案,例如它对'ZZASDAASDAA'有效,结果在0.0001秒内生成。 –

11

有一个叫做ord的函数,它给出了字符的ASCII码。

ord($chr) - ord('A') + 1 

为您提供了一个字符的正确结果。对于更长的字符串,您可以使用循环。

<?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

我纠正了我的循环 – Dutow

+1

AA,它生成((0 * 26)+1)* 26)+1,这是正确的答案。对于BA来说,它是(((0 * 26)+2)* 26)+1,我认为这也是正确的。所以双字母是正确的。对于“AAA”,它计算26 * 27 + 1,这也应该是正确的(26为单个字母变化,26 * 26为双字母,这是前三个字母代码) – Dutow

1

这是完整的代码,可以做你想做的。

经过测试,完美适用于您提供的示例。

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

使用范围和strpos:

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

对于双字母(例如ZZ)你可能会需要使用自定义功能来创建自己的字母:

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

然后使用$字典代替$字母。

0

我觉得ORD应该是有你的电话号码更有效的方式:

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

和结果将包含你想要什么。