所以我有这个功能:
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 ......
我做错了什么?如何修复反向功能以使其正常工作?
提前致谢!
我完全不了解你在该功能中尝试使用的逻辑。你想要做的事情看起来很奇怪(为什么'''地图为零但是'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;
}
最简单的方法,在PHP> = 4.1.0
$alphabet = range('A', 'Z');
echo $alphabet[3]; // returns D
echo array_search('D', $alphabet); // returns 3
你的问题来自你的地图。看这个:
$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<'z'; $i++) {
$alpha[] = $i;
}
$alpha[26] = 'z';
您可以根据需要运行它,服务器内存将允许。 PHP是错误的,并且(至少在我的服务器上)如果你使用<=运算符:
$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
$alpha[] = $i;
}
然后它会一直映射到[676] => string(2)“yz”!你只需要玩它。
我不想给[0]写一封信,所以我只是在那里写了一个标题。如果你想要0 => a,1 => b等,显然你可以把它留下来。
一旦数组正确,该函数是微不足道的。
从数字到字母(A = 0,B = 1等):
function toAlpha($num){
return chr(substr("000".($num+65),-3));
}
您可以使用ord()
函数从字母到数字执行相同的操作。
使用97更改65,您可以获得小写值。
我拿了'更正'原件,删除了调试代码,以及其他不必要的代码,修改它以便它可以使用任意数量的字符。例如,希腊语只有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];
使用西里尔的答案,我详细阐述了一个包含多个字母的案例。
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
将数字转换为alphacode
例如:1402到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);
}
将alphacode转换为数字
例如:bax到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;
}
这是对原始函数toAlpha的修复。它不适合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;
}
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;
}