0

phpワイルド ワイルド ウェストでは、PHP を使用してアルファベットの次の文字を取得する最も効率的な方法は、a (つまり、1 つのサイズの文字列)++に適用されるプレインクリメント演算子によって行われます。char

$str = 'a';
echo ++$str; // prints 'b'

$str = 'z';
echo ++$str; // prints 'aa' 

そして、この狂気があること

  for ($char='A'; $char<='Z'; $char++) {
    echo $char;
  }

それが印刷されます

ABCDEFGHIJKLMNOPQRSTUVWXYZAAABACADAEAFAGAHAIAJAKALAMANAOAPAQARASATAUAVAWAXAYAZBABBBCBDBEBFBGBHBIBJBKBLBMBNBOBPBQBRBSBTBUBVBWBXBYBZCACBCCCDCECFCGCHCICJCKCLCMCNCOCPCQCRCSCTCUCVCWCXCYCZDADBDCDDDEDFDGDHDIDJDKDLDMDNDODPDQDRDSDTDUDVDWDXDYDZEAEBECEDEEEFEGEHEIEJEKELEMENEOEPEQERESETEUEVEWEXEYEZFAFBFCFDFEFFFGFHFIFJFKFLFMFNFOFPFQFRFSFTFUFVFWFXFYFZGAGBGCGDGEGFGGGHGIGJGKGLGMGNGOGPGQGRGSGTGUGVGWGXGYGZHAHBHCHDHEHFHGHHHIHJHKHLHMHNHOHPHQHRHSHTHUHVHWHXHYHZIAIBICIDIEIFIGIHIIIJIKILIMINIOIPIQIRISITIUIVIWIXIYIZJAJBJCJDJEJFJGJHJIJJJKJLJMJNJOJPJQJRJSJTJUJVJWJXJYJZKAKBKCKDKEKFKGKHKIKJKKKLKMKNKOKPKQKRKSKTKUKVKWKXKYKZLALBLCLDLELFLGLHLILJLKLLLMLNLOLPLQLRLSLTLULVLWLXLYLZMAMBMCMDMEMFMGMHMIMJMKMLMMMNMOMPMQMRMSMTMUMVMWMXMYMZNANBNCNDNENFNGNHNINJNKNLNMNNNONPNQNRNSNTNUNVNWNXNYNZOAOBOCODOEOFOGOHOIOJOKOLOMONOOOPOQOROSOTOUOVOWOXOYOZPAPBPCPDPEPFPGPHPIPJPKPLPMPNPOPPPQPRPSPTPUPVPWPXPYPZQAQBQCQDQEQFQGQHQIQJQKQLQMQNQOQPQQQRQSQTQUQVQWQXQYQZRARBRCRDRERFRGRHRIRJRKRLRMRNRORPRQRRRSRTRURVRWRXRYRZSASBSCSDSESFSGSHSISJSKSLSMSNSOSPSQSRSSSTSUSVSWSXSYSZTATBTCTDTETFTGTHTITJTKTLTMTNTOTPTQTRTSTTTUTVTWTXTYTZUAUBUCUDUEUFUGUHUIUJUKULUMUNUOUPUQURUSUTUUUVUWUXUYUZVAVBVCVDVEVFVGVHVIVJVKVLVMVNVOVPVQVRVSVTVUVVVWVXVYVZWAWBWCWDWEWFWGWHWIWJWKWLWMWNWOWPWQWRWSWTWUWVWWWXWYWZXAXBXCXDXEXFXGXHXIXJXKXLXMXNXOXPXQXRXSXTXUXVXWXXXYXZYAYBYCYDYEYFYGYHYIYJYKYLYMYNYOYPYQYRYSYTYUYVYWYXYYYZ

'Z' の後には 'AA'が続き、'AA' は 'Z' より小さいためです。

したがって、正しい方法は次の文字を出力することです

foreach (range('A', 'Z') as $char) {
    echo $char;
  }

それが印刷されます

ABCDEFGHIJKLMNOPQRSTUVWXYZ

モジュロ演算子で次の文字を取得できると仮定し、chr(ord())

$next=chr((((ord($c) - ord('A')) + 1) % 26) + ord('A'));

関数と関数++$charを使用する方法が必要です。ord()chr()

  $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

in $nextchar は蓄積されていないため、次のものを取得するだけです。では、のみを使用して 3 列目と 4 列目で同じ値を取得するにはどうすればよいchr( ord() )でしょうか。

[編集]

この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()ただし、 andchr()および modulo 演算子のみを使用します。最後のバイト (最初のバイト) は modulo によって単純に取得され%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だから、ここの最初のバイトが欠けていると思います。

[推奨される実装]

これは提案された実装の 1 つであり、提案されたルックアップ テーブルを使用して得られた最も単純なものは次のとおりです。

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 ];
  }

それを証明するには、$charから次のものを取得するだけですrange('A','z'):

  $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

それは、別の方法を使用しても、出力として達成したかったことです。

ノート。もちろん、ルックアップ テーブルは次の++演算子を使用して生成されました。

$lookup_table=array();
for ($char='A'; $char<='Z'; $char++) {
 array_push($lookup_table,$char);
}

これは、JavaScript の移植でプログラムによって使用されることを意味するものではありません (コメントを参照)。

4

2 に答える 2