将整数转换为字母,反之亦然(例如 0 =“A”、26 =“AA”、27 =“AB”)
所以我有这个函数:
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...
我做错了什么?如何修复反向功能使其正常工作?
So I have this 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;
}
}
which given a number converts it into character and it works fine
but then I also want a reverse function of this that given any output of this function, return the exact input that was put in to produce that output and I tried this:
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);
}
}
but it's not working properly...toAlpha(728) is producing 'aba' but toNum('aba') is producing 1378 rather than 728...
What did I do wrong? How can I fix the reverse function so that it works properly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
最短的方法,在 PHP >= 4.1.0
Shortest way, in PHP >= 4.1.0
我完全不明白你试图在该函数中使用的逻辑。你想要做的事情看起来很奇怪(为什么'a'映射到零而'aa'映射到26?),但这似乎有效。 (您将需要使用更多测试用例,我只检查它是否为案例“aba”提供了正确的输出。)
I don't understand at all the logic you're trying to use in that function. What you're trying to do seems very strange (why does 'a' map to zero and yet 'aa' maps to 26?), but this appears to work. (You will want to use some more test cases, I only checked that it gives the correct output for the case 'aba'.)
Theriault 在 PHPs base_convert 函数 的评论中有一个非常聪明的解决方案
There is a very clever solution by Theriault in the comments of PHPs base_convert function
从数字到字母(A=0、B=1 等):
您可以使用函数
ord()
从字母到数字执行相同的操作。将65改为97,即可得到小写值。
From number to alphabet (with A=0, B=1, etc...):
You can do the same from alphabet to number with the function
ord()
.Changing 65 with 97, you can obtain the lowercase values.
你的问题来自你的地图。看看这个:
您可以在服务器内存允许的情况下运行任意高的值。 PHP 是有缺陷的,并且(至少在我的服务器上)如果您使用 <= 运算符:
那么它将一直映射到 [676]==>字符串(2)“yz”!你只需要玩它。
我不想将字母映射到 [0],所以我只是在其中放置了一个标题。显然,如果您想要 0=>a、1=>b 等,则可以将其省略。
一旦数组正确,该函数就很简单了。
Your problems comes from your map. Look at this:
You can run this as high as you want and your server memory will allow. The PHP is buggy, and (at least on my server) if you use the <= operator:
then it will map all the way to [676]=> string(2) "yz"! You just have to play with it.
I didn't want to map a letter to [0] so I just put a title in there. Obviously you can leave it out if you want 0=>a, 1=>b, etc.
Once the array is correct, the function is trivial.
使用西里尔的回答,我对一个包含多个字母的案例进行了一些详细说明。
下面显示了该函数的一些结果:
Using Cyril's answer, I elaborated a bit for a case with more than one letter.
A few results for the function are displayed bellow:
我采用了“更正”的原始代码,删除了调试代码和其他不必要的代码,对其进行了修改,以便它可以处理任意数量的字符。例如,希腊语只有 24 个字符。
以下是范围的一些示例:
I took the 'corrected' original, removed the debug code, and other unnecessary code, modified it so it will work with any number of characters. For example, Greek only has 24 characters.
And here are some examples of ranges:
这是一个可以使用非常高的列值(超过两个字母)的实现。电子表格将使用
0
或1
作为第一个值,因此请务必将第二个参数$indexStart
指定为1(如果您使用的是 Excel);或者
0
(默认值)(如果使用 Google Sheets)。letterToColumnNumber()
此外,如果您希望将坐标引用(例如
A1:B2
)转换为坐标数组(例如[[0,0], [1,1]]
),我们可以将此letterToColumnNumber
函数与以下函数结合使用来实现:rangeStringToRangeArray()
如果您希望反转任一过程,以下两个函数结合在一起将实现该结果:
columnNumberToLetter()
rangeArrayToRangeString()
当您与 Google Sheets API 集成时,此类代码非常有用。例如,如果您想获取所有冻结行和列的引用,这些行和列以整数而不是单元格引用的形式提供。
请注意,我在这些函数中包含了完全零错误检查,因此您会想要这样做。
Here is an implementation that can use very high column values (more than two letters). Spreadsheets will use either
0
or1
as the first value, so be sure to specify the second parameter$indexStart
as1
if you are using Excel, or0
(the default) if using Google Sheets.letterToColumnNumber()
Additionally, if you wish to convert a coordinate reference (such as
A1:B2
) into a coordinate array (like[[0,0],[1,1]]
), we can use thisletterToColumnNumber
function with the following function to achieve that:rangeStringToRangeArray()
If you wish to reverse either process, the following two functions together will achieve that result:
columnNumberToLetter()
rangeArrayToRangeString()
This kind of code can be useful when you're integrating with Google Sheets API. E.g., if you want to get a reference for all the frozen rows and columns, which are provided as integers instead of a cell reference.
Please note that I have included exactly ZERO error checking in these functions, so you'll want to do that.
这是对原始函数 toAlpha 的修复。它不适用于 toAlpha(27)
Here is a fix to original function toAlpha. It is not working for toAlpha(27)
我这样做是为了在 int 参数之前使用修复字符长度
A = 0 ,Z = 25
}
i do this stuff to use fix char lenght before int parameter
A = 0 ,Z = 25
}
如果数字从 1 开始:
If the numbers start at 1: