pil*_*ght 19 php string math reverse function
所以我有这个功能:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
给出一个数字将其转换为字符,它工作正常
但是我还想要一个这样的反向函数,给定这个函数的任何输出,返回输入的确切输入以产生该输出,我试过这个:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是它没有正常工作...... toAlpha(728)正在生产'aba'但是toNum('aba')正在生产1378而不是728 ......
我做错了什么?如何修复反向功能以使其正常工作?
提前致谢!
Cyr*_*ril 83
最简单的方法,在PHP> = 4.1.0
$alphabet = range('A', 'Z');
echo $alphabet[3]; // returns D
echo array_search('D', $alphabet); // returns 3
Run Code Online (Sandbox Code Playgroud)
Ham*_*ite 13
我完全不了解你在该功能中尝试使用的逻辑.你想要做的事情看起来很奇怪(为什么'''地图为零,而'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;
}
Run Code Online (Sandbox Code Playgroud)
use*_*873 10
在PHP 的 base_convert 函数的注释中,Theriault 有一个非常聪明的解决方案
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
您的问题来自您的地图。看这个:
$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<'z'; $i++) {
$alpha[] = $i;
}
$alpha[26] = 'z';
Run Code Online (Sandbox Code Playgroud)
您可以根据需要将其运行得很高,并且服务器内存将允许。PHP是错误的,并且(至少在我的服务器上)使用了<=运算符:
$alpha[0] = 'Alphabet';
for ($i = 'a'; $i<='z'; $i++) {
$alpha[] = $i;
}
Run Code Online (Sandbox Code Playgroud)
那么它将一直映射到[676] => string(2)“ yz”!您只需要玩。
我不想将字母映射到[0],所以只在其中放置了一个标题。显然,如果要0 => a,1 => b等,则可以省去。
一旦数组正确,该函数就变得微不足道了。
从数字到字母(A = 0,B = 1等):
function toAlpha($num){
return chr(substr("000".($num+65),-3));
}
Run Code Online (Sandbox Code Playgroud)
您可以使用函数从字母到数字执行相同的操作ord()。
用97更改65,可以获得小写值。
使用西里尔的回答,我对一个包含多个字母的案例进行了一些详细说明。
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;
}
Run Code Online (Sandbox Code Playgroud)
该函数的一些结果显示如下:
lettersToNumber("A"); //returns 1
lettersToNumber("E"); //returns 5
lettersToNumber("Z"); //returns 26
lettersToNumber("AB"); //returns 28
lettersToNumber("AP"); //returns 42
lettersToNumber("CE"); //returns 83
Run Code Online (Sandbox Code Playgroud)