如何使用 ord() 和 chr() 在 php 下一个字符中实现
How to implement in php next char using ord() and chr()
在php
狂野的西部,
鉴于 Most efficient way to get next letter in the alphabet using PHP 是由应用于 char
(即一个大小的字符串)的预增量 ++
运算符制成的:
$str = 'a';
echo ++$str; // prints 'b'
$str = 'z';
echo ++$str; // prints 'aa'
而且
中有这种疯狂
for ($char='A'; $char<='Z'; $char++) {
echo $char;
}
将打印出来
ABCDEFGHIJKLMNOPQRSTUVWXYZAAABACADAEAFAGAHAIAJAKALAMANAOAPAQARASATAUAVAWAXAYAZBABBBCBDBEBFBGBHBIBJBKBLBMBNBOBPBQBRBSBTBUBVBWBXBYBZCACBCCCDCECFCGCHCICJCKCLCMCNCOCPCQCRCSCTCUCVCWCXCYCZDADBDCDDDEDFDGDHDIDJDKDLDMDNDODPDQDRDSDTDUDVDWDXDYDZEAEBECEDEEEFEGEHEIEJEKELEMENEOEPEQERESETEUEVEWEXEYEZFAFBFCFDFEFFFGFHFIFJFKFLFMFNFOFPFQFRFSFTFUFVFWFXFYFZGAGBGCGDGEGFGGGHGIGJGKGLGMGNGOGPGQGRGSGTGUGVGWGXGYGZHAHBHCHDHEHFHGHHHIHJHKHLHMHNHOHPHQHRHSHTHUHVHWHXHYHZIAIBICIDIEIFIGIHIIIJIKILIMINIOIPIQIRISITIUIVIWIXIYIZJAJBJCJDJEJFJGJHJIJJJKJLJMJNJOJPJQJRJSJTJUJVJWJXJYJZKAKBKCKDKEKFKGKHKIKJKKKLKMKNKOKPKQKRKSKTKUKVKWKXKYKZLALBLCLDLELFLGLHLILJLKLLLMLNLOLPLQLRLSLTLULVLWLXLYLZMAMBMCMDMEMFMGMHMIMJMKMLMMMNMOMPMQMRMSMTMUMVMWMXMYMZNANBNCNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZOAOBOCODOEOFOGOHOIOJOKOLOMONOOOPOQOROSOTOUOVOWOXOYOZPAPBPCPDPEPFPGPHPIPJPKPLPMPNPOPPPQPRPSPTPUPVPWPXPYPZQAQBQCQDQEQFQGQHQIQJQKQLQMQNQOQPQQQRQSQTQUQVQWQXQYQZRARBRCRDRERFRGRHRIRJRKRLRMRNRORPRQRRRSRTRURVRWRXRYRZSASBSCSDSESFSGSHSISJSKSLSMSNSOSPSQSRSSSTSUSVSWSXSYSZTATBTCTDTETFTGTHTITJTKTLTMTNTOTPTQTRTSTTTUTVTWTXTYTZUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUSUTUUUVUWUXUYUZVAVBVCVDVEVFVGVHVIVJVKVLVMVNVOVPVQVRVSVTVUVVVWVXVYVZWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZXAXBXCXDXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYSYTYUYVYWYXYYYZ
由于 after 'Z' comes 'AA', and 'AA' is smaller than 'Z'.
所以正确的方法是打印下一个字符
foreach (range('A', 'Z') as $char) {
echo $char;
}
将打印出来
ABCDEFGHIJKLMNOPQRSTUVWXYZ
假设我们可以用取模运算符得到下一个字符 chr(ord())
$next=chr((((ord($c) - ord('A')) + 1) % 26) + ord('A'));
我需要一种使用 ord()
和 chr()
函数来执行 ++$char
的方法,所以这样做
$cmax=ord('A');
$char='A';
foreach (range('A', 'z') as $c) {
++$char;
$next=chr((((ord($c) - $cmax) + 1) % 26) + $cmax);
echo ord($c)." ".$c." ".$next." ".$char."\n";
}
它将打印出:
65 A B B
66 B C C
67 C D D
68 D E E
69 E F F
70 F G G
71 G H H
72 H I I
73 I J J
74 J K K
75 K L L
76 L M M
77 M N N
78 N O O
79 O P P
80 P Q Q
81 Q R R
82 R S S
83 S T T
84 T U U
85 U V V
86 V W W
87 W X X
88 X Y Y
89 Y Z Z
90 Z A AA
91 [ B AB
92 \ C AC
93 ] D AD
94 ^ E AE
95 _ F AF
96 ` G AG
97 a H AH
98 b I AI
99 c J AJ
因为在 $next
中没有累积字符,只是获取下一个字符。
那么如何仅使用 chr( ord() )
在第 3 列和第 4 列中获得相同的值?
[编辑]
我要澄清一下,我需要这个 for 循环的相同输出
for ($char='A'; $char<='Z'; $char++) {
echo $char."\n";
}
就是这样
A
B
C
...
Y
Z
AA
AB
AC
AD
AE
AF
...
YW
YX
YY
YZ
但仅使用 ord()
和 chr()
以及模运算符。
现在最后一个字节(第一个字节)简单地通过模 %26
:
获得
$byte_two=chr( ( ((ord($code) - ord('A')) + 1) % 26) + ord('A') );
在 foreach
上给定 range('A', 'z')
:
foreach (range('A', 'z') as $code) {
$byte_one=chr( ( ((ord($code) - ord('A')) + 1) % 26) + ord('A') );
echo ord($code)."\t".$byte_one."\n";
}
将打印出与 ++$char
中相同字节位置的最后一个字节。所以我想我错过了 $byte_two
,这里的第一个字节。
[建议实施]
这是建议的实现之一,也是我能够按照建议使用查找 table 得出的最简单的实现:
function lookupNextChar($c)
{
static $lookup_table=null;
if ($lookup_table === null) {
$lookup_table=explode(",","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,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV,CW,CX,CY,CZ,DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,DO,DP,DQ,DR,DS,DT,DU,DV,DW,DX,DY,DZ,EA,EB,EC,ED,EE,EF,EG,EH,EI,EJ,EK,EL,EM,EN,EO,EP,EQ,ER,ES,ET,EU,EV,EW,EX,EY,EZ,FA,FB,FC,FD,FE,FF,FG,FH,FI,FJ,FK,FL,FM,FN,FO,FP,FQ,FR,FS,FT,FU,FV,FW,FX,FY,FZ,GA,GB,GC,GD,GE,GF,GG,GH,GI,GJ,GK,GL,GM,GN,GO,GP,GQ,GR,GS,GT,GU,GV,GW,GX,GY,GZ,HA,HB,HC,HD,HE,HF,HG,HH,HI,HJ,HK,HL,HM,HN,HO,HP,HQ,HR,HS,HT,HU,HV,HW,HX,HY,HZ,IA,IB,IC,ID,IE,IF,IG,IH,II,IJ,IK,IL,IM,IN,IO,IP,IQ,IR,IS,IT,IU,IV,IW,IX,IY,IZ,JA,JB,JC,JD,JE,JF,JG,JH,JI,JJ,JK,JL,JM,JN,JO,JP,JQ,JR,JS,JT,JU,JV,JW,JX,JY,JZ,KA,KB,KC,KD,KE,KF,KG,KH,KI,KJ,KK,KL,KM,KN,KO,KP,KQ,KR,KS,KT,KU,KV,KW,KX,KY,KZ,LA,LB,LC,LD,LE,LF,LG,LH,LI,LJ,LK,LL,LM,LN,LO,LP,LQ,LR,LS,LT,LU,LV,LW,LX,LY,LZ,MA,MB,MC,MD,ME,MF,MG,MH,MI,MJ,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV,MW,MX,MY,MZ,NA,NB,NC,ND,NE,NF,NG,NH,NI,NJ,NK,NL,NM,NN,NO,NP,NQ,NR,NS,NT,NU,NV,NW,NX,NY,NZ,OA,OB,OC,OD,OE,OF,OG,OH,OI,OJ,OK,OL,OM,ON,OO,OP,OQ,OR,OS,OT,OU,OV,OW,OX,OY,OZ,PA,PB,PC,PD,PE,PF,PG,PH,PI,PJ,PK,PL,PM,PN,PO,PP,PQ,PR,PS,PT,PU,PV,PW,PX,PY,PZ,QA,QB,QC,QD,QE,QF,QG,QH,QI,QJ,QK,QL,QM,QN,QO,QP,QQ,QR,QS,QT,QU,QV,QW,QX,QY,QZ,RA,RB,RC,RD,RE,RF,RG,RH,RI,RJ,RK,RL,RM,RN,RO,RP,RQ,RR,RS,RT,RU,RV,RW,RX,RY,RZ,SA,SB,SC,SD,SE,SF,SG,SH,SI,SJ,SK,SL,SM,SN,SO,SP,SQ,SR,SS,ST,SU,SV,SW,SX,SY,SZ,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,TS,TT,TU,TV,TW,TX,TY,TZ,UA,UB,UC,UD,UE,UF,UG,UH,UI,UJ,UK,UL,UM,UN,UO,UP,UQ,UR,US,UT,UU,UV,UW,UX,UY,UZ,VA,VB,VC,VD,VE,VF,VG,VH,VI,VJ,VK,VL,VM,VN,VO,VP,VQ,VR,VS,VT,VU,VV,VW,VX,VY,VZ,WA,WB,WC,WD,WE,WF,WG,WH,WI,WJ,WK,WL,WM,WN,WO,WP,WQ,WR,WS,WT,WU,WV,WW,WX,WY,WZ,XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ,XK,XL,XM,XN,XO,XP,XQ,XR,XS,XT,XU,XV,XW,XX,XY,XZ,YA,YB,YC,YD,YE,YF,YG,YH,YI,YJ,YK,YL,YM,YN,YO,YP,YQ,YR,YS,YT,YU,YV,YW,YX,YY,YZ");
echo implode($lookup_table,',')."\n";
echo count($lookup_table)."\n";
}
$idx=( ((ord($c) - ord('A')) + 1 ) % count($lookup_table));
return $lookup_table[ $idx ];
}
为了证明,只需从range('A','z')
中得到下一个$char
:
$sum=$n='A';
foreach (range('A','z') as $c) {
$n=lookupNextChar($c,$lookup_table);
++$sum;
echo "$c\t$n\t$sum\n";
}
然后我得到
A B B
B C C
C D D
D E E
E F F
F G G
.. .. ..
X Y Y
Y Z Z
Z AA AA
[ AB AB
\ AC AC
] AD AD
^ AE AE
.. .. ..
x CD BD
y DE BE
z EF BF
这是我想要实现的输出,即使使用不同的方式也是如此。
注意。当然,查找 table 是使用 ++
运算符生成的,然后:
$lookup_table=array();
for ($char='A'; $char<='Z'; $char++) {
array_push($lookup_table,$char);
}
这并不意味着在 javascript 移植中以编程方式使用(参见评论)。
正如我在笔记中观察到的,在 reach/pass 'Z' 的值之后,您的 $char
变量有效地变成了 2 个字符的字符串。我无法对此发表评论,但对于您的请求,以下可能不是太昂贵的通用解决方案:始终使用字符串的 "last" 字符。
$cmax=ord('A');
$char='A';
foreach (range('A', 'z') as $c) {
$next=chr((((ord($c) - $cmax) + 1) % 26) + $cmax);
++$char;
echo ord($c)." ".$c." ".$next." ".$char[strlen($char)-1]."\n";
}
65 A B B
66 B C C
67 C D D
68 D E E
69 E F F
70 F G G
71 G H H
72 H I I
73 I J J
74 J K K
75 K L L
76 L M M
77 M N N
78 N O O
79 O P P
80 P Q Q
81 Q R R
82 R S S
83 S T T
84 T U U
85 U V V
86 V W W
87 W X X
88 X Y Y
89 Y Z Z
90 Z A A
91 [ B B
92 \ C C
93 ] D D
94 ^ E E
95 _ F F
96 ` G G
97 a H H
98 b I I
99 c J J
100 d K K
101 e L L
102 f M M
103 g N N
104 h O O
105 i P P
106 j Q Q
107 k R R
108 l S S
109 m T T
110 n U U
111 o V V
112 p W W
113 q X X
114 r Y Y
115 s Z Z
116 t A A
117 u B B
118 v C C
119 w D D
120 x E E
121 y F F
122 z G G
要求:允许以与 PHP 相同的方式增加字符串(请参阅问题中的链接)。起初我想:多么不寻常?我仍然这么认为。
好的,我们需要制作一些无需使用 PHP 例程即可执行此操作的东西。
好的,有什么?
我认为它是一个 'base26' 数字。我选择将其实现为:
- 为范围为 1 .. 26 的每个数字使用一个数组。
- 使用数组查找将数组中的数字转换为显示字符。
Working demonstration at eval.in
为了方便,我放在了PHP class:
我尝试让代码易于理解...
base26 class:
class base26 { // it only does increment / addition
const
numberBase = 26;
// These are characters used where A => 1 and Z is 26
// These can be changed as you wish. They could be multibyte?
// 0 1 2 2
// 12345678901234567890123456
public static $displayChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
/**
* current number - least significant digit is digit[0]
*
* @var array $digit - integer with range 1 .. 26
*/
public $digit = array();
// initialize if nothing provided
public function __construct($letters = 'A')
{
$this->init($letters);
}
/**
* Convert letters to base26 and store in the $digit array
*
* @param string $letters
* @return void
*/
public function init($letters = 'A')
{
$this->digit = array();
$lsd = strlen($letters) - 1;
for ($idx = $lsd; $idx >= 0; $idx--) {
$this->digit[] = $this->charValue($letters[$idx]);
}
}
/**
* Increment the 'least significant digit' and then propagate the `carry`
* when it exceeds the number base limit.
*
* @param integer $int -- default to 1
* @return void
*/
public function inc($int = 1) // addition with carry - easy to understand
{
$curDigit = 0; // add to least significant digit
$carry = 0;
$this->digit[$curDigit] += $int;
while ($this->digit[$curDigit] > self::numberBase) {
$carry = 1; // next carry
$this->digit[$curDigit] %= self::numberBase; // reset digit
$curDigit++; // check next digit...
if (isset($this->digit[$curDigit])) {
$this->digit[$curDigit] += $carry;
}
else {
$this->digit[$curDigit] = $carry;
}
}
}
/**
* Convert a number to a character to display
*
* @param intger $int
*
* @return char
*/
public function toChar($int)
{
return self::$displayChars[$int - 1];
}
/**
* The value of the character in the number base range
*
* @param undefined $letter
* @return integer
*/
public function charValue($letter)
{
return stripos(self::$displayChars, $letter) + 1;
}
/**
* return the current number values as a string using the display characters
*
* @return string
*/
public function current()
{
$digitCount = count($this->digit);
$outStr = str_pad('A', count($this->digit));
$outIdx = $digitCount - 1;
for ($idx = 0; $idx < $digitCount; $idx++, $outIdx-- ) {
$outStr[$outIdx] = $this->toChar($this->digit[$idx]);
}
return $outStr;
}
}
示例:
// ---------------------------------------------
// show increment from Z -> AA
echo PHP_EOL;
$b26 = new base26('Z');
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
Output: Z|AA|
// ---------------------------------------------
// show increment from 'FY' -> FZ -> GA
echo PHP_EOL;
$b26->init('FY');
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
Output: FY|FZ|GA|
// ---------------------------------------------
// Show it does what PHP does...
echo PHP_EOL;
$b26 = new base26();
while ($b26->current() <= 'Z') {
echo $b26->current() .'|';
$b26->inc();
}
Output: 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|AA|AB|AC|AD|AE|AF|AG|AH|AI|AJ|AK|AL|AM|AN|AO ...
在php
狂野的西部,
鉴于 Most efficient way to get next letter in the alphabet using PHP 是由应用于 char
(即一个大小的字符串)的预增量 ++
运算符制成的:
$str = 'a';
echo ++$str; // prints 'b'
$str = 'z';
echo ++$str; // prints 'aa'
而且
中有这种疯狂 for ($char='A'; $char<='Z'; $char++) {
echo $char;
}
将打印出来
ABCDEFGHIJKLMNOPQRSTUVWXYZAAABACADAEAFAGAHAIAJAKALAMANAOAPAQARASATAUAVAWAXAYAZBABBBCBDBEBFBGBHBIBJBKBLBMBNBOBPBQBRBSBTBUBVBWBXBYBZCACBCCCDCECFCGCHCICJCKCLCMCNCOCPCQCRCSCTCUCVCWCXCYCZDADBDCDDDEDFDGDHDIDJDKDLDMDNDODPDQDRDSDTDUDVDWDXDYDZEAEBECEDEEEFEGEHEIEJEKELEMENEOEPEQERESETEUEVEWEXEYEZFAFBFCFDFEFFFGFHFIFJFKFLFMFNFOFPFQFRFSFTFUFVFWFXFYFZGAGBGCGDGEGFGGGHGIGJGKGLGMGNGOGPGQGRGSGTGUGVGWGXGYGZHAHBHCHDHEHFHGHHHIHJHKHLHMHNHOHPHQHRHSHTHUHVHWHXHYHZIAIBICIDIEIFIGIHIIIJIKILIMINIOIPIQIRISITIUIVIWIXIYIZJAJBJCJDJEJFJGJHJIJJJKJLJMJNJOJPJQJRJSJTJUJVJWJXJYJZKAKBKCKDKEKFKGKHKIKJKKKLKMKNKOKPKQKRKSKTKUKVKWKXKYKZLALBLCLDLELFLGLHLILJLKLLLMLNLOLPLQLRLSLTLULVLWLXLYLZMAMBMCMDMEMFMGMHMIMJMKMLMMMNMOMPMQMRMSMTMUMVMWMXMYMZNANBNCNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZOAOBOCODOEOFOGOHOIOJOKOLOMONOOOPOQOROSOTOUOVOWOXOYOZPAPBPCPDPEPFPGPHPIPJPKPLPMPNPOPPPQPRPSPTPUPVPWPXPYPZQAQBQCQDQEQFQGQHQIQJQKQLQMQNQOQPQQQRQSQTQUQVQWQXQYQZRARBRCRDRERFRGRHRIRJRKRLRMRNRORPRQRRRSRTRURVRWRXRYRZSASBSCSDSESFSGSHSISJSKSLSMSNSOSPSQSRSSSTSUSVSWSXSYSZTATBTCTDTETFTGTHTITJTKTLTMTNTOTPTQTRTSTTTUTVTWTXTYTZUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUSUTUUUVUWUXUYUZVAVBVCVDVEVFVGVHVIVJVKVLVMVNVOVPVQVRVSVTVUVVVWVXVYVZWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZXAXBXCXDXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYSYTYUYVYWYXYYYZ
由于 after 'Z' comes 'AA', and 'AA' is smaller than 'Z'.
所以正确的方法是打印下一个字符
foreach (range('A', 'Z') as $char) {
echo $char;
}
将打印出来
ABCDEFGHIJKLMNOPQRSTUVWXYZ
假设我们可以用取模运算符得到下一个字符 chr(ord())
$next=chr((((ord($c) - ord('A')) + 1) % 26) + ord('A'));
我需要一种使用 ord()
和 chr()
函数来执行 ++$char
的方法,所以这样做
$cmax=ord('A');
$char='A';
foreach (range('A', 'z') as $c) {
++$char;
$next=chr((((ord($c) - $cmax) + 1) % 26) + $cmax);
echo ord($c)." ".$c." ".$next." ".$char."\n";
}
它将打印出:
65 A B B
66 B C C
67 C D D
68 D E E
69 E F F
70 F G G
71 G H H
72 H I I
73 I J J
74 J K K
75 K L L
76 L M M
77 M N N
78 N O O
79 O P P
80 P Q Q
81 Q R R
82 R S S
83 S T T
84 T U U
85 U V V
86 V W W
87 W X X
88 X Y Y
89 Y Z Z
90 Z A AA
91 [ B AB
92 \ C AC
93 ] D AD
94 ^ E AE
95 _ F AF
96 ` G AG
97 a H AH
98 b I AI
99 c J AJ
因为在 $next
中没有累积字符,只是获取下一个字符。
那么如何仅使用 chr( ord() )
在第 3 列和第 4 列中获得相同的值?
[编辑]
我要澄清一下,我需要这个 for 循环的相同输出
for ($char='A'; $char<='Z'; $char++) {
echo $char."\n";
}
就是这样
A
B
C
...
Y
Z
AA
AB
AC
AD
AE
AF
...
YW
YX
YY
YZ
但仅使用 ord()
和 chr()
以及模运算符。
现在最后一个字节(第一个字节)简单地通过模 %26
:
$byte_two=chr( ( ((ord($code) - ord('A')) + 1) % 26) + ord('A') );
在 foreach
上给定 range('A', 'z')
:
foreach (range('A', 'z') as $code) {
$byte_one=chr( ( ((ord($code) - ord('A')) + 1) % 26) + ord('A') );
echo ord($code)."\t".$byte_one."\n";
}
将打印出与 ++$char
中相同字节位置的最后一个字节。所以我想我错过了 $byte_two
,这里的第一个字节。
[建议实施]
这是建议的实现之一,也是我能够按照建议使用查找 table 得出的最简单的实现:
function lookupNextChar($c)
{
static $lookup_table=null;
if ($lookup_table === null) {
$lookup_table=explode(",","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,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV,CW,CX,CY,CZ,DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,DO,DP,DQ,DR,DS,DT,DU,DV,DW,DX,DY,DZ,EA,EB,EC,ED,EE,EF,EG,EH,EI,EJ,EK,EL,EM,EN,EO,EP,EQ,ER,ES,ET,EU,EV,EW,EX,EY,EZ,FA,FB,FC,FD,FE,FF,FG,FH,FI,FJ,FK,FL,FM,FN,FO,FP,FQ,FR,FS,FT,FU,FV,FW,FX,FY,FZ,GA,GB,GC,GD,GE,GF,GG,GH,GI,GJ,GK,GL,GM,GN,GO,GP,GQ,GR,GS,GT,GU,GV,GW,GX,GY,GZ,HA,HB,HC,HD,HE,HF,HG,HH,HI,HJ,HK,HL,HM,HN,HO,HP,HQ,HR,HS,HT,HU,HV,HW,HX,HY,HZ,IA,IB,IC,ID,IE,IF,IG,IH,II,IJ,IK,IL,IM,IN,IO,IP,IQ,IR,IS,IT,IU,IV,IW,IX,IY,IZ,JA,JB,JC,JD,JE,JF,JG,JH,JI,JJ,JK,JL,JM,JN,JO,JP,JQ,JR,JS,JT,JU,JV,JW,JX,JY,JZ,KA,KB,KC,KD,KE,KF,KG,KH,KI,KJ,KK,KL,KM,KN,KO,KP,KQ,KR,KS,KT,KU,KV,KW,KX,KY,KZ,LA,LB,LC,LD,LE,LF,LG,LH,LI,LJ,LK,LL,LM,LN,LO,LP,LQ,LR,LS,LT,LU,LV,LW,LX,LY,LZ,MA,MB,MC,MD,ME,MF,MG,MH,MI,MJ,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV,MW,MX,MY,MZ,NA,NB,NC,ND,NE,NF,NG,NH,NI,NJ,NK,NL,NM,NN,NO,NP,NQ,NR,NS,NT,NU,NV,NW,NX,NY,NZ,OA,OB,OC,OD,OE,OF,OG,OH,OI,OJ,OK,OL,OM,ON,OO,OP,OQ,OR,OS,OT,OU,OV,OW,OX,OY,OZ,PA,PB,PC,PD,PE,PF,PG,PH,PI,PJ,PK,PL,PM,PN,PO,PP,PQ,PR,PS,PT,PU,PV,PW,PX,PY,PZ,QA,QB,QC,QD,QE,QF,QG,QH,QI,QJ,QK,QL,QM,QN,QO,QP,QQ,QR,QS,QT,QU,QV,QW,QX,QY,QZ,RA,RB,RC,RD,RE,RF,RG,RH,RI,RJ,RK,RL,RM,RN,RO,RP,RQ,RR,RS,RT,RU,RV,RW,RX,RY,RZ,SA,SB,SC,SD,SE,SF,SG,SH,SI,SJ,SK,SL,SM,SN,SO,SP,SQ,SR,SS,ST,SU,SV,SW,SX,SY,SZ,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,TS,TT,TU,TV,TW,TX,TY,TZ,UA,UB,UC,UD,UE,UF,UG,UH,UI,UJ,UK,UL,UM,UN,UO,UP,UQ,UR,US,UT,UU,UV,UW,UX,UY,UZ,VA,VB,VC,VD,VE,VF,VG,VH,VI,VJ,VK,VL,VM,VN,VO,VP,VQ,VR,VS,VT,VU,VV,VW,VX,VY,VZ,WA,WB,WC,WD,WE,WF,WG,WH,WI,WJ,WK,WL,WM,WN,WO,WP,WQ,WR,WS,WT,WU,WV,WW,WX,WY,WZ,XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ,XK,XL,XM,XN,XO,XP,XQ,XR,XS,XT,XU,XV,XW,XX,XY,XZ,YA,YB,YC,YD,YE,YF,YG,YH,YI,YJ,YK,YL,YM,YN,YO,YP,YQ,YR,YS,YT,YU,YV,YW,YX,YY,YZ");
echo implode($lookup_table,',')."\n";
echo count($lookup_table)."\n";
}
$idx=( ((ord($c) - ord('A')) + 1 ) % count($lookup_table));
return $lookup_table[ $idx ];
}
为了证明,只需从range('A','z')
中得到下一个$char
:
$sum=$n='A';
foreach (range('A','z') as $c) {
$n=lookupNextChar($c,$lookup_table);
++$sum;
echo "$c\t$n\t$sum\n";
}
然后我得到
A B B
B C C
C D D
D E E
E F F
F G G
.. .. ..
X Y Y
Y Z Z
Z AA AA
[ AB AB
\ AC AC
] AD AD
^ AE AE
.. .. ..
x CD BD
y DE BE
z EF BF
这是我想要实现的输出,即使使用不同的方式也是如此。
注意。当然,查找 table 是使用 ++
运算符生成的,然后:
$lookup_table=array();
for ($char='A'; $char<='Z'; $char++) {
array_push($lookup_table,$char);
}
这并不意味着在 javascript 移植中以编程方式使用(参见评论)。
正如我在笔记中观察到的,在 reach/pass 'Z' 的值之后,您的 $char
变量有效地变成了 2 个字符的字符串。我无法对此发表评论,但对于您的请求,以下可能不是太昂贵的通用解决方案:始终使用字符串的 "last" 字符。
$cmax=ord('A');
$char='A';
foreach (range('A', 'z') as $c) {
$next=chr((((ord($c) - $cmax) + 1) % 26) + $cmax);
++$char;
echo ord($c)." ".$c." ".$next." ".$char[strlen($char)-1]."\n";
}
65 A B B
66 B C C
67 C D D
68 D E E
69 E F F
70 F G G
71 G H H
72 H I I
73 I J J
74 J K K
75 K L L
76 L M M
77 M N N
78 N O O
79 O P P
80 P Q Q
81 Q R R
82 R S S
83 S T T
84 T U U
85 U V V
86 V W W
87 W X X
88 X Y Y
89 Y Z Z
90 Z A A
91 [ B B
92 \ C C
93 ] D D
94 ^ E E
95 _ F F
96 ` G G
97 a H H
98 b I I
99 c J J
100 d K K
101 e L L
102 f M M
103 g N N
104 h O O
105 i P P
106 j Q Q
107 k R R
108 l S S
109 m T T
110 n U U
111 o V V
112 p W W
113 q X X
114 r Y Y
115 s Z Z
116 t A A
117 u B B
118 v C C
119 w D D
120 x E E
121 y F F
122 z G G
要求:允许以与 PHP 相同的方式增加字符串(请参阅问题中的链接)。起初我想:多么不寻常?我仍然这么认为。
好的,我们需要制作一些无需使用 PHP 例程即可执行此操作的东西。
好的,有什么?
我认为它是一个 'base26' 数字。我选择将其实现为:
- 为范围为 1 .. 26 的每个数字使用一个数组。
- 使用数组查找将数组中的数字转换为显示字符。
Working demonstration at eval.in
为了方便,我放在了PHP class:
我尝试让代码易于理解...
base26 class:
class base26 { // it only does increment / addition
const
numberBase = 26;
// These are characters used where A => 1 and Z is 26
// These can be changed as you wish. They could be multibyte?
// 0 1 2 2
// 12345678901234567890123456
public static $displayChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
/**
* current number - least significant digit is digit[0]
*
* @var array $digit - integer with range 1 .. 26
*/
public $digit = array();
// initialize if nothing provided
public function __construct($letters = 'A')
{
$this->init($letters);
}
/**
* Convert letters to base26 and store in the $digit array
*
* @param string $letters
* @return void
*/
public function init($letters = 'A')
{
$this->digit = array();
$lsd = strlen($letters) - 1;
for ($idx = $lsd; $idx >= 0; $idx--) {
$this->digit[] = $this->charValue($letters[$idx]);
}
}
/**
* Increment the 'least significant digit' and then propagate the `carry`
* when it exceeds the number base limit.
*
* @param integer $int -- default to 1
* @return void
*/
public function inc($int = 1) // addition with carry - easy to understand
{
$curDigit = 0; // add to least significant digit
$carry = 0;
$this->digit[$curDigit] += $int;
while ($this->digit[$curDigit] > self::numberBase) {
$carry = 1; // next carry
$this->digit[$curDigit] %= self::numberBase; // reset digit
$curDigit++; // check next digit...
if (isset($this->digit[$curDigit])) {
$this->digit[$curDigit] += $carry;
}
else {
$this->digit[$curDigit] = $carry;
}
}
}
/**
* Convert a number to a character to display
*
* @param intger $int
*
* @return char
*/
public function toChar($int)
{
return self::$displayChars[$int - 1];
}
/**
* The value of the character in the number base range
*
* @param undefined $letter
* @return integer
*/
public function charValue($letter)
{
return stripos(self::$displayChars, $letter) + 1;
}
/**
* return the current number values as a string using the display characters
*
* @return string
*/
public function current()
{
$digitCount = count($this->digit);
$outStr = str_pad('A', count($this->digit));
$outIdx = $digitCount - 1;
for ($idx = 0; $idx < $digitCount; $idx++, $outIdx-- ) {
$outStr[$outIdx] = $this->toChar($this->digit[$idx]);
}
return $outStr;
}
}
示例:
// ---------------------------------------------
// show increment from Z -> AA
echo PHP_EOL;
$b26 = new base26('Z');
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
Output: Z|AA|
// ---------------------------------------------
// show increment from 'FY' -> FZ -> GA
echo PHP_EOL;
$b26->init('FY');
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
$b26->inc();
echo $b26->current() .'|';
Output: FY|FZ|GA|
// ---------------------------------------------
// Show it does what PHP does...
echo PHP_EOL;
$b26 = new base26();
while ($b26->current() <= 'Z') {
echo $b26->current() .'|';
$b26->inc();
}
Output: 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|AA|AB|AC|AD|AE|AF|AG|AH|AI|AJ|AK|AL|AM|AN|AO ...