簡體   English   中英

算法錯誤

[英]Error in algorithm

我有一個腳本:

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除外)開始?

經過長時間的研究,我終於得到了你想要的東西^^

首先,PHP具有許多內置方法,這些方法可以為您帶來很大幫助。 如果我沒看錯,那么代碼的以下部分只是將$src轉換$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中的一些技巧,以使您的生活更輕松。 看一下教程。

q代表0 很顯然,您找到的腳本進行了基本轉換。 為了區分0和26,它需要以不同的方式表示值。

因為q已經為0,所以它不能使用qq表示26,因為那等於00 它需要第一個字母表示1,因此使用wq

我想您是想說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。 還要注意,由於您的系列的定義,在給定范圍0-676內不可能有26個值:它們由mq,mw,... mm值組成。

如果你改變

$wet /= $dstBase;

$wet = $wet / $dstBase - 1;

您的代碼將給出正確的結果。 但是,正如Soren所指出的那樣,使用PHP功能可以使事情輕松得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM