Как я могу сделать «число» со строкой в ​​PHP? - PullRequest
0 голосов
/ 05 февраля 2011

Вместо использования символов [0..9] используйте символы [0..9A..Z]

Вместо использования системы base-10 используйте систему base-64

Я хочу сделать функцию, как в этом примере:

next ('ABC') return 'ACA' - это следующая строка с 3 единицами

Это похоже на то, что у нас есть числаот 0 до 9 и функция возвращает следующий номер

next2 (135), возвращает 136 - это следующий номер с 3 цифрами

Мы используем систему base-10 для чисел, которые я хочуиспользовать номерные знаки, что означает систему base-36, и получить следующий так называемый номер

Ответы [ 6 ]

2 голосов
/ 05 февраля 2011

Вот функция, которая производит следующее значение в вашей алфавитной системе счисления base-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

Обратите внимание, что результатом является «CA», так как «ACA» совпадает с написанием «06» вbase-10 ... мы обычно не пишем начальные нули, поэтому вы не пишете ведущие "A".

Поэтому я добавил параметр pad, который позволяет вам указать, какое количество цифр вы хотите заполнить.к.С $pad=3 вы получаете «ACA» как следующий от «ABC».

1 голос
/ 05 февраля 2011

как то так

<?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'));
0 голосов
/ 05 февраля 2011

Чтобы получить следующий номер в base36, используйте:

function next_base36($n) {
    $n = base_convert($n, 36, 10);
    return base_convert($n + 1, 10, 36);
}
0 голосов
/ 05 февраля 2011

Согласно вашему комментарию к ответу Ксавье Барбоза, если вы хотите использовать все буквы from a to z, вы можете сделать:

$str = 'ajz';
echo ++$str,"\n";

это напечатает: aka

0 голосов
/ 05 февраля 2011

Эти функции ручного преобразования базы не страдают от неточностей встроенных.

<?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;
    }
?>
0 голосов
/ 05 февраля 2011

Один из способов, которым я мог бы сейчас воспользоваться, - это преобразовать символы в base26, а затем добавить 1 к числу и преобразовать его обратно, надеюсь, вы поняли идею. Next2 должен сделать то же самое, но с base10, который по умолчанию, так что я бы просто +1 к самому числу. Будем рады видеть другие реализации на этом.

Редактировать: Не заметил, что у вас был А в конце. глупо мне от меня, чтобы сделать это. тогда это будет base3 вместо 26.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...