如何在php下使用ord()和chr()实现char

时间:2016-03-16 18:58:54

标签: php string char chr ord

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())

获取下一个char
$next=chr((((ord($c) - ord('A')) + 1) % 26) + ord('A'));

我需要一种方法来使用++$charord()函数执行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

因为在$next char中没有积累,只是得到下一个。 那么如何仅使用chr( ord() )

在第3和第4列中获得相同的值

[编辑]

我将澄清我需要相同的for loop输出

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的{​​{1}}中:

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

要证明这一点,只需从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 运算符生成的:

++

这并不意味着在javascript移植中以编程方式使用(请参阅注释)。

2 个答案:

答案 0 :(得分:1)

要求:允许以与PHP相同的方式增加字符串(请参阅问题中的链接)。起初我想:多么不寻常?我仍然这么认为。

好的,我们需要在不使用PHP例程的情况下生成可以执行此操作的内容。

好的,有什么?

我认为这是一个&#39; base26&#39;数。我选择将其实现为:

  • 对范围为1的每个数字使用数组.26。
  • 转换数组中的数字,以使用数组查找显示字符。

Working demonstration at eval.in

为方便起见,我把它放在PHP类中:

我尝试让代码可以理解......

base26类:

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 ...

答案 1 :(得分:0)

正如我在笔记中观察到的那样,在达到/传递&#39; Z&#39;的值后,您的 $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"; } 变量将有效地变为2个字符串。我无法评论有关此问题的详细信息,但以下内容对您的请求可能不是太昂贵的通用解决方案:始终使用&#34; last&#34;字符串的字符。

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

https://eval.in/537739

=SUBTOTAL