program story

PHP에서 숫자와 같은 문자를 증가시키는 방법은 무엇입니까?

inputbox 2020. 12. 27. 10:49
반응형

PHP에서 숫자와 같은 문자를 증가시키는 방법은 무엇입니까?


3 문자를 받아 증가시키고 새로 증가 된 문자를 문자열로 반환하는 함수를 작성하고 싶습니다.

단일 문자를 다음 문자로 늘리는 방법을 알고 있지만 두 번째 문자를 늘린 다음 중지 한 다음 첫 번째 문자를 다시 늘려 순차적으로 늘릴 때를 어떻게 알 수 있습니까?

따라서 AAA가 전달되면 AAB를 반환합니다. AAZ가 전달되면 ABA (하드 부분)를 반환합니다.

논리에 대한 도움과 사용하는 데 유용한 PHP 기능에 감사드립니다.

더 좋은 점은 일부는 이미이 작업을 수행했거나이 작업을 수행 할 수있는 클래스가 있습니까 ??

도움을 주셔서 감사합니다.


문자 / 문자열 증가는 PHP에서 작동합니다 (감소는 작동하지 않음).

$x = 'AAZ';
$x++;
echo $x;

++ 연산자로 할 수 있습니다.

$i = 'aaz';
$i++;
print $i;

아바

그러나이 구현에는 몇 가지 이상한 점이 있습니다.

for($i = 'a'; $i < 'z'; $i++) print "$i ";

에서 a까지의 문자가 인쇄됩니다 y.

for($i = 'a'; $i <= 'z'; $i++) print "$i ";

이것은에서 a까지의 lette를 인쇄 z하고으로 계속 aa되고 끝납니다 yz.


PHP RFC : Strict operator directive ( 현재 논의 중 ) 에서 제안한대로 :

문자열에 증가 함수를 사용하면 strict_operators가 활성화 된 경우 TypeError가 발생합니다.

RFC가 병합되는지 여부에 관계없이 PHP는 조만간 연산자 엄격 성을 추가하는 방향으로 갈 것입니다. 따라서 strings를 증가시키지 않아야합니다 .

az / AZ 범위

문자가 범위 az / AZ (z / Z를 초과하지 않음)에 유지된다는 것을 알고있는 경우 문자를 ASCII 코드로 변환하고 증분하고 다시 문자로 변환하는 솔루션을 사용할 수 있습니다.

사용 ord()chr():

$letter = 'A';
$letterAscii = ord($letter);
$letterAscii++;
$letter = chr($letterAscii); // 'B'
  1. ord() 문자를 ASCII 숫자 표현으로 변환합니다.
  2. 그 숫자 표현이 증가합니다
  3. chr()숫자를 사용 하면 문자로 다시 변환됩니다.

댓글에서 발견했듯이 조심하세요. 에서, 그래서이 반복의 ASCII 표 Z(ASCII 90)가 이동하지 않습니다 AA, 그러나에 [(ASCII 91).

z / Z를 넘어서

당신은 더 나아가 감히과 희망이 경우 z이되었다 aa, 이것은 내가 생각 해낸 것입니다 :

final class NextLetter
{
    private const ASCII_UPPER_CASE_BOUNDARIES = [65, 91];
    private const ASCII_LOWER_CASE_BOUNDARIES = [97, 123];

    public static function get(string $previous) : string
    {
        $letters = str_split($previous);
        $output = '';
        $increase = true;

        while (! empty($letters)) {
            $letter = array_pop($letters);

            if ($increase) {
                $letterAscii = ord($letter);
                $letterAscii++;
                if ($letterAscii === self::ASCII_UPPER_CASE_BOUNDARIES[1]) {
                    $letterAscii = self::ASCII_UPPER_CASE_BOUNDARIES[0];
                    $increase = true;
                } elseif ($letterAscii === self::ASCII_LOWER_CASE_BOUNDARIES[1]) {
                    $letterAscii = self::ASCII_LOWER_CASE_BOUNDARIES[0];
                    $increase = true;
                } else {
                    $increase = false;
                }

                $letter = chr($letterAscii);
                if ($increase && empty($letters)) {
                    $letter .= $letter;
                }
            }

            $output = $letter . $output;
        }

        return $output;
    }
}

추가로 작업하려는 경우에도 100 % 보장을 제공합니다. 원래 문자열 증가에 대해 테스트합니다 ++.

    /**
     * @dataProvider letterProvider
     */
    public function testIncrementLetter(string $givenLetter) : void
    {
        $expectedValue = $givenLetter;

        self::assertSame(++$expectedValue, NextLetter::get($givenLetter));
    }

    /** 
     * @return iterable<string>
     */
    public function letterProvider() : iterable
    {
        yield ['A'];
        yield ['a'];
        yield ['z'];
        yield ['Z'];
        yield ['aaz'];
        yield ['aaZ'];
        yield ['abz'];
        yield ['abZ'];
    }

숫자 표현 문제를보고 있습니다. 이것은 base24 (또는 알파벳에있는 많은 숫자)입니다. 베이스 b를 호출합시다.

알파벳의 각 문자에 숫자를 할당합니다 (A = 1, B = 2, C = 3).

Next, figure out your input "number": The representation "ABC" means A*b^2 + B*b^1 + C*b^0 Use this formula to find the number (int). Increment it.

Next, convert it back to your number system: Divide by b^2 to get third digit, the remainder (modulo) by b^1 for second digit, the remainder (modulo) by `b^0^ for last digit.

This might help: How to convert from base10 to any other base.


I have these methods in c# that you could probably convert to php and modify to suit your needs, I'm not sure Hexavigesimal is the exact name for these though...

#region Hexavigesimal (Excel Column Name to Number)
public static int FromHexavigesimal(this string s)
{
    int i = 0;
    s = s.Reverse();
    for (int p = s.Length - 1; p >= 0; p--)
    {
        char c = s[p];
        i += c.toInt() * (int)Math.Pow(26, p);
    }

    return i;
}

public static string ToHexavigesimal(this int i)
{
    StringBuilder s = new StringBuilder();

    while (i > 26)
    {
        int r = i % 26;
        if (r == 0)
        {
            i -= 26;
            s.Insert(0, 'Z');
        }
        else
        {
            s.Insert(0, r.toChar());
        }

        i = i / 26;
    }

    return s.Insert(0, i.toChar()).ToString();
}

public static string Increment(this string s, int offset)
{
    return (s.FromHexavigesimal() + offset).ToHexavigesimal();
}

private static char toChar(this int i)
{
    return (char)(i + 64);
}

private static int toInt(this char c)
{
    return (int)c - 64;
}
#endregion

EDIT

I see by the other answers that in PHP you can use ++ instead, nice!


You could use the ASCII codes for alpha numerics. From there you increment and decrement to get the previous/next character.

You could split your string in single characters and then apply the transformations on these characters.

Just some thoughts to get you started.


 <?php 
$values[] = 'B';
$values[] = 'A';
$values[] = 'Z';
foreach($values as $value ){
  if($value == 'Z'){ 
       $value = '-1';
    }
$op = ++$value;
echo $op;
}
?>

ReferenceURL : https://stackoverflow.com/questions/3567180/how-to-increment-letters-like-numbers-in-php

반응형