简体   繁体   English

算法错误

[英]Error in algorithm

I have a script: 我有一个脚本:

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

It works fine, however the result is strange... it looks like that: 它工作正常,但是结果很奇怪……看起来像这样:

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

but 26 should be qq, 676 should be qqq, 677 = qwq, 678 = qqe etc. 但是26应该是qq,676应该是qqq,677 = qwq,678 = qqe等。

why it's starting from w instead of q (except for 0)? 为什么从w而不是q(0除外)开始?

After a long time of looking on your algorithm, I finally get what you wanted ^^ 经过长时间的研究,我终于得到了你想要的东西^^

Firstly, PHP has many builtin methods that would help you a lot. 首先,PHP具有许多内置方法,这些方法可以为您带来很大帮助。 If I am not wrong, the following part of your code is only to convert $src to an integer. 如果我没看错,那么代码的以下部分只是将$src转换$src整数。

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

Not only that you "cast" it to a string in a strange way before calling the function, you also "cast" it back to an integer even stranger. 在调用函数之前,不仅要以一种奇怪的方式将其“转换”成字符串,而且还要将其“转换”成一个整数甚至是陌生人。 You should have a look on php's intval method. 您应该看看php的intval方法。 And the reason that it always begins with w is simply that the second loop only continues if 而且它总是以w开头的原因仅仅是第二个循环仅在

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

which means that in the next step it will still be $digitVal > 1 , so the index is minimum 1, which corresponds to w . 这意味着在下一步中,它仍然是$digitVal > 1 ,因此索引最小为1,对应于w Actually, this makes sense in a way even though I don't know what exactly you want to accomplish (change the base of your number to 26?), because 0 exists as well, but there is no number such as 009 or something similar. 实际上,即使我不知道您到底要完成什么(将数字的基数更改为26?),从某种意义上讲还是有道理的,因为也存在0,但是没有数字(例如009或类似的数字) 。 You then just write 9 and it's the same in your system (you only write p instead of qqp). 然后,您只需编写9,并且在您的系统中它是相同的(您只写p而不是qqp)。

However, you should really learn some tricks in PHP to make your life easier. 但是,您应该真正学习PHP中的一些技巧,以使您的生活更轻松。 Have a look on this tutorial. 看一下教程。

q represents 0 . q代表0 And obviously the script you've found does a base conversion. 很显然,您找到的脚本进行了基本转换。 To differentiate 0 from 26 it needs to represent the values differently. 为了区分0和26,它需要以不同的方式表示值。

Because q is already 0 it cannot use qq for 26, because that would be tantamount to 00 . 因为q已经为0,所以它不能使用qq表示26,因为那等于00 It needs the first letter to represent a 1, so it uses wq . 它需要第一个字母表示1,因此使用wq

I think you're trying to say that 677 should equal qqw, no? 我想您是想说677应该等于qqw,不是吗?

In any event, you could do something much easier to (this is pseudo php, obviously) 无论如何,您可以做得更轻松(显然,这是伪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];
 }

Sorry about the Math.Max (I wrote this in C# and tried to pseudo convert it). 对不起Math.Max(我用C#编写了此文件,并试图对其进行伪转换)。 the reason for the Math.Max is that when the $src value is a perfect square, cube, quart, etc. the expression evaluates to -1. Math.Max的原因是,当$ src值为完美的正方形,立方体,夸脱等时,表达式的计算结果为-1。 Also note that due to the definition of your series, there are 26 values that are not possible in the given range 0-676: they consist of the mq, mw,...mm values. 还要注意,由于您的系列的定义,在给定范围0-676内不可能有26个值:它们由mq,mw,... mm值组成。

If you change 如果你改变

$wet /= $dstBase;

to

$wet = $wet / $dstBase - 1;

your code will give the correct result. 您的代码将给出正确的结果。 However, as Soren noted, using PHP functionality you can accomplish things much easier. 但是,正如Soren所指出的那样,使用PHP功能可以使事情轻松得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM