[英]How can I make a “number” with string in PHP?
Instead of using the [0..9] symbols use the [0..9A..Z] symbols 代替使用[0..9]符号,使用[0..9A..Z]符号
Instead of using the base-10 system use the base-64 system 不要使用base-10系统,而要使用base-64系统
I want to make a function like in this example: 我想制作一个类似于此示例的函数:
next('ABC') return 'ACA' - this is the next string with 3 units next('ABC')返回'ACA'-这是具有3个单位的下一个字符串
It is like we have numbers from 0 to 9 and the function return the next number 就像我们有一个从0到9的数字,该函数返回下一个数字
next2(135) return 136 - this is the next number with 3 digits next2(135)返回136-这是3位数字的下一个数字
We use a base-10 system for numbers an I want to use numbersletters that means a base-36 system, and get the next so called number 我们使用以10为底的系统来计算数字,我想使用以数字表示的以36为底的系统,然后得到下一个所谓的数字
Here's a function that produces the next value in your base-3 alphabetic number system: 这是一个在基数3的字母数字系统中产生下一个值的函数:
function nextval($input, $pad = 1) {
$map = array(0 => 'A', 1 => 'B', 2 => 'C');
//convert letters to numbers
$num = '';
for ($i = 0; $i < strlen($input); $i++) {
$num .= array_search($input{$i}, $map);
}
//convert the number to base 10, then add 1 to it
$base10 = base_convert($num, 3, 10);
$base10++;
//convert back to base 3
$base3 = base_convert($base10, 10, 3);
//swap the digits back to letters
$num = '';
for ($i = 0; $i < strlen($base3); $i++) {
$num .= $map[$base3{$i}];
}
//pad with leading A's
while (strlen($num) < $pad) {
$num = 'A' . $num;
}
return $num;
}
echo nextval('ABC', 3); //ACA
Note that the result is "CA" as "ACA" is the same as writing "06" in base-10... we don't usually write leading zeros so you wouldn't write leading "A"s. 请注意,结果为“ CA”,因为“ ACA”与在base-10中写入“ 06”相同...我们通常不会写入前导零,因此您不会写入前导“ A”。
I therefore added a pad parameter that lets you specify what number of digits you want to pad to. 因此,我添加了一个pad参数,该参数可让您指定要填充的位数。 With
$pad=3
, you get "ACA" as next from "ABC". 使用
$pad=3
,您将从“ ABC”获得“ ACA”。
Something like this 像这样
<?php
function toNext($input) {
$conv = strtr(strtolower($input), array(
'a' => '0',
'b' => '1',
'c' => '2' ));
$conv = base_convert($conv, 3, 10);
$conv++;
$output = base_convert($conv, 10, 3);
$output = sprintf("%03d", $output);
$output = strtr((string) $output, array(
'0' => 'a',
'1' => 'b',
'2' => 'c' ));
return strtoupper($output);
}
var_dump(toNext('ABC'));
var_dump(toNext('ABA'));
One way I could think of right now is converting the characters to base26 and then adding 1 to the number and converting it back, I hope you get the idea. 我现在想到的一种方法是将字符转换为base26,然后将数字加1并将其转换回,希望您能理解。 Next2 should do a same but with base10 which is default so I that would just be a +1 to the number itself.
Next2应该做同样的事情,但是默认是base10,所以我只是数字本身的+1。 Looking forward to see other implementations on this one.
期待在此基础上看到其他实现。
Edit: Didn't notice you had A at the end. 编辑:没注意到您最后有A。 silly me of me to do that.
我很愚蠢地做到这一点。 that would be base3 then instead of 26.
那将是base3,而不是26。
These manual base conversion functions don't suffer from the inaccuracies of the built-in ones. 这些手动的基本转换功能不会受到内置函数的错误的影响。
<?php
function next($str)
{
$baseDec = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
$baseAln = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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');
return base_conv((string) ((int) base_conv($str, $baseAln, $baseDec) + 1), $baseDec, $baseAln);
}
function base_conv_str($valStr, $baseToStr, $baseFromStr)
{
$baseTo = str_split($baseToStr);
$baseFrom = str_split($baseFromStr);
return base_arr_to_str(base_conv_arr(base_str_to_arr((string) $valStr, $baseFrom), count($baseTo), count($baseFrom)), $baseTo);
}
function base_conv($valStr, &$baseTo, &$baseFrom)
{
return base_arr_to_str(base_conv_arr(base_str_to_arr((string) $valStr, $baseFrom), count($baseTo), count($baseFrom)), $baseTo);
}
function base_conv_arr($val, $baseToDigits, $baseFromDigits)
{
$valDigits = count($val);
$result = array();
do
{
$divide = 0;
$newlen = 0;
for ($i = 0; $i < $valDigits; ++$i)
{
$divide = $divide * $baseFromDigits + $val[$i];
if ($divide >= $baseToDigits)
{
$val[$newlen ++] = (int) ($divide / $baseToDigits);
$divide = $divide % $baseToDigits;
}
else if ($newlen > 0)
{
$val[$newlen ++] = 0;
}
}
$valDigits = $newlen;
array_unshift($result, $divide);
}
while ($newlen != 0);
return $result;
}
function base_arr_to_str($arr, &$base)
{
$str = '';
foreach ($arr as $digit)
{
$str .= $base[$digit];
}
return $str;
}
function base_str_to_arr($str, &$base)
{
$arr = array();
while ($str === '0' || !empty($str))
{
foreach ($base as $index => $digit)
{
if (mb_substr($str, 0, $digitLen = mb_strlen($digit)) === $digit)
{
$arr[] = $index;
$str = mb_substr($str, $digitLen);
continue 2;
}
}
throw new Exception();
}
return $arr;
}
?>
According to your comment to Xavier Barbosa's answer, if you want to use all letters from a to z
you can do: 根据您对Xavier Barbosa答案的评论,如果要使用
from a to z
所有字母from a to z
可以执行以下操作:
$str = 'ajz';
echo ++$str,"\n";
this will print : aka
这将打印:
aka
To get the next number in base36 use: 要获得base36中的下一个数字,请使用:
function next_base36($n) {
$n = base_convert($n, 36, 10);
return base_convert($n + 1, 10, 36);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.