Ошибка в алгоритме - PullRequest
       3

Ошибка в алгоритме

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

У меня есть скрипт:

function convert($src, $srcAlphabet = '0123456789', $dstAlphabet =
    'qwertyuiopasdfghjklzxcvbnm')
{
    $srcBase = strlen($srcAlphabet);
    $dstBase = strlen($dstAlphabet);

    $wet = $src;
    $val = 0;
    $mlt = 1;

    while($l = strlen($wet))
    {
        $digit = $wet[$l - 1];
        $val += $mlt * strpos($srcAlphabet, $digit);
        $wet = substr($wet, 0, $l - 1);
        $mlt *= $srcBase;
    }

    $wet = $val;
    $dst = '';

    while($wet >= $dstBase)
    {
        $digitVal = $wet % $dstBase;
        $digit = $dstAlphabet[$digitVal];
        $dst = $digit . $dst;
        $wet /= $dstBase;
    }

    $digit = $dstAlphabet[$wet];
    $dst = $digit . $dst;

    return $dst;
}

for($i = 0; $i < 10000; $i++)
{
    echo $i . ' = ' . convert(substr(' ' . $i, 1)) . '<br>';
}

Работает нормально, но результат странный ... выглядит так:

0 = q
1 = w
2 = e
3 = r
4 = t
5 = y
6 = u
7 = i
8 = o
9 = p
10 = a
11 = s
12 = d
13 = f
14 = g
15 = h
16 = j
17 = k
18 = l
19 = z
20 = x
21 = c
22 = v
23 = b
24 = n
25 = m
26 = wq
...
...
676 = wqq
677 = wqw
678 = wqe
...

но 26 должно быть qq, 676 должно быть qqq, 677 = qwq, 678 = qqe и т. Д.

почему он начинается с w вместо q (кроме 0)?

Ответы [ 4 ]

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

q представляет 0. И, очевидно, скрипт, который вы нашли, выполняет базовое преобразование. Чтобы отличить 0 от 26, необходимо по-разному представлять значения.

Поскольку q уже равен 0, он не может использовать qq для 26, потому что это равносильно 00. Ему нужна первая буква для обозначения 1, поэтому она использует wq.

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

После долгого изучения вашего алгоритма я наконец-то получил то, что вы хотели ^^

Во-первых, в PHP есть много встроенных методов, которые вам очень помогут.Если я не ошибаюсь, следующая часть вашего кода предназначена только для преобразования $src в целое число.

while($l = strlen($wet))
{
    $digit = $wet[$l - 1];
    $val += $mlt * strpos($srcAlphabet, $digit);
    $wet = substr($wet, 0, $l - 1);
    $mlt *= $srcBase;
}

Мало того, что вы странным образом «приводите» его к строке перед вызовомфункция, вы также "приведете" его к целому числу, даже более странному.Вы должны взглянуть на php intval метод.И причина того, что он всегда начинается с w, заключается в том, что второй цикл продолжается только если

$digitVal = $wet % $dstBase >= $dstBase

, что означает, что на следующем шаге он все равно будет $digitVal > 1, поэтому индекс равен минимум 1, чтосоответствует w.На самом деле, это имеет смысл, даже если я не знаю, чего именно вы хотите достичь (измените базу своего числа на 26?), Потому что 0 также существует, но нет такого числа, как 009 или что-то подобное,Затем вы просто пишете 9, и это то же самое в вашей системе (вы пишете только p вместо qqp).

Однако вы должны действительно изучить некоторые приемы в PHP, чтобы сделать вашу жизнь проще.Взгляните на этот учебник.

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

Я думаю, вы пытаетесь сказать, что 677 должно равняться qqw, нет?

В любом случае, вы могли бы сделать что-то намного проще (это псевдо php, очевидно)

function convert($src, $srcAlphabet = '0123456789', $dstAlphabet =
    'qwertyuiopasdfghjklzxcvbnm')
{

  $lenAlphabet = strlen($dstAlphabet);
  $tempSrc = $src;

  $result = '';
  while($tempSrc / $lenAlphabet > 0){                
             $tempSrc = $tempSrc / $lenAlphabet;
             $result .= $dstAlphabet[Math.Max(0,($tempSrc % $lenAlphabet) - 1)];

        }      
  return $result . $dstAlphabet[$src % $lenAlphabet];
 }

Извините за Math.Max ​​(я написал это на C # и попытался псевдо конвертировать).причина Math.Max ​​заключается в том, что когда значение $ src является идеальным квадратом, кубом, квартом и т. д., выражение оценивается как -1.Также обратите внимание, что из-за определения вашей серии, есть 26 значений, которые не возможны в данном диапазоне 0-676: они состоят из значений mq, mw, ... mm.

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

Если вы измените

$wet /= $dstBase;

на

$wet = $wet / $dstBase - 1;

, ваш код даст правильный результат.Однако, как отметил Сорен, используя функциональность PHP, вы можете гораздо проще.

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