2017-10-17 139 views
1

我正在做一個類似Excel的web應用程序,其中的列「編號」爲a,b,c,...,aa,ab,...,az,ba ,...,zz,aaa,...。但是,如果我寫PHP:使用遞增的字符變量進行計數時的比較

$start = 'a'; 
$end = 'z'; 

while($start <= $end){ 
    echo $start++ . ", "; 
} 

(通知$開始< = $結束),它會去一個高達YZ,不只是AZ因爲

echo 'aa' <= 'z'; // true, but 
echo 'za' <= 'z'; // false. 

是有一個函數或一種方法來比較兩個變量,記住:

$a = "z"; echo ++$a; // aa 
$a = "zz"; echo ++$a; // aaa 

使

$a = "z"; $b = $a; $b++; // $b = aa 

AisLessThanB(a,b); // returns true 

等等?這意味着其中

一個<ž< AA < AZ < ZZ < AAA < ZZZ < AAAA

總是

編輯:喜歡的東西

$start = 'a'; 
$end = 'cv'; // 100 columns 

應該工作,因爲我們同列負荷工作。

謝謝!

+1

爲什麼'AA' <'Z' –

回答

0

試試這個:

// From https://stackoverflow.com/a/3580935/3088508 
function getLetterIndexInAlphabet ($letter) { 
    return ord($letter) - 96; 
} 

function convertStringToNumber ($inStr) { 
    $letters = array_reverse(str_split($inStr)); 
    $outNum = 0; 
    for ($i = count($letters) - 1; $i >= 0; $i--) { 
     $outNum += getLetterIndexInAlphabet($letters[$i]) * (pow(26, $i)); 
    } 
    return $outNum; 
} 

function AisLessThanB ($a, $b) { 
    $aInt = convertStringToNumber($a); 
    $bInt = convertStringToNumber($b); 
    return ($aInt < $bInt); 
} 

convertStringToNumber是這裏最複雜的功能,讓我們來看看它是如何工作的幾個值:

  • 'c'計算結果爲2,它是計算結果:
    1. 'c' = 3(字母索引)
  • 'ba'計算結果爲,其由下式計算53:
    1. 'b' = 52 =(2(指數在字母)×(26(基值)^ 1(列數)))。
    2. 'a' = 1(在字母索引)
  • 'bca'計算爲1431,其由下式計算:
    1. 'b' = 1352 =(2(指數在字母)×(26(基值)^ 2(列號)))。
    2. 'c' = 78 =(3(字母索引)×(26(基值)^ 1(列號)))。
    3. 'a' = 1(在字母索引)
  • 'bdca'計算爲37935,其由下式計算:
    1. 'b' = 35152 =(2(指數在字母)×(26(基值)^ 3(列號)))。
    2. 'd' = 2704 =(4(字母索引)×(26(基準值)^ 2(列號)))。
    3. 'c' = 78 =(3(字母索引)×(26(基值)^ 1(列號)))。
    4. 'a' = 1(在字母索引)

這裏的一些測試情況:

echo " a < z = " . ((AisLessThanB( 'a', 'z')) ? 'true' : 'false') . "\n"; 
echo " z < aa = " . ((AisLessThanB( 'z', 'aa')) ? 'true' : 'false') . "\n"; 
echo " aa < az = " . ((AisLessThanB( 'aa', 'az')) ? 'true' : 'false') . "\n"; 
echo " az < zz = " . ((AisLessThanB( 'az', 'zz')) ? 'true' : 'false') . "\n"; 
echo " zz < aaa = " . ((AisLessThanB( 'zz', 'aaa')) ? 'true' : 'false') . "\n"; 
echo " aaa < zzz = " . ((AisLessThanB('aaa', 'zzz')) ? 'true' : 'false') . "\n"; 
echo " zzz < aaaa = " . ((AisLessThanB('zzz', 'aaaa')) ? 'true' : 'false') . "\n"; 
echo "\n===================\n\n"; 
echo " z < a = " . ((AisLessThanB( 'z', 'a')) ? 'true' : 'false') . "\n"; 
echo " aa < z = " . ((AisLessThanB( 'aa', 'z')) ? 'true' : 'false') . "\n"; 
echo " az < aa = " . ((AisLessThanB( 'az', 'aa')) ? 'true' : 'false') . "\n"; 
echo " zz < az = " . ((AisLessThanB( 'zz', 'az')) ? 'true' : 'false') . "\n"; 
echo " aaa < zz = " . ((AisLessThanB('aaa', 'zz')) ? 'true' : 'false') . "\n"; 
echo " zzz < aaa = " . ((AisLessThanB('zzz', 'aaa')) ? 'true' : 'false') . "\n"; 
echo "aaaa < zzz = " . ((AisLessThanB('aaaa', 'zzz')) ? 'true' : 'false') . "\n"; 

他們輸出:

a < z = true 
    z < aa = true 
    aa < az = true 
    az < zz = true 
    zz < aaa = true 
aaa < zzz = true 
zzz < aaaa = true 

=================== 

    z < a = false 
    aa < z = false 
    az < aa = false 
    zz < az = false 
aaa < zz = false 
zzz < aaa = false 
aaaa < zzz = false 

eval.in demo

感謝您提出這樣一個有趣的問題!

+1

很好的回答!我只是將AisLessThanB的返回值更改爲$ aInt - $ bInt,所以我可以使用AisLessThanB($ a,$ b)vs <0,<= 0或== 0.謝謝! – alejosky

0

我不認爲這樣增加字符串是個好主意。實際上,增加一個char的ASCII值。在這種情況下字符串的比較是按字母順序排列的(https://stackoverflow.com/a/12888720/5346387),所以我猜它不會按照您的預期工作。

但是對於你的問題 - 我不認爲會有這樣的PHP本地函數。我建議創建一個從數字[0,1,2,3 ... 27,28 ..]的線性列表到您的字母代碼[a,b,c..aa,ab ...]的映射函數。我希望我幫助:)

0

如果比較字符之前比較字符串長度怎麼辦?

function aIsLessThanB($a, $b) { 

    if(strlen($a) == strlen($b)) { 
    $strlen = strlen($a); 

    for($i = 0; $i < $strlen; $i++) { 

     // pick single character at position $i 
     $charA = substr($a, $i, 1); 
     $charB = substr($b, $i, 1); 

     // convert ASCII to integer and compare 
     if(ord($charA) < ord($charB)) { 
     return true; 
     } elseif(ord($charA) > ord($charB)) { 
     return false; 
     } 
    } 

    } elseif(strlen($a) < strlen($b)) { 
    return true; 
    } else { 
    return false; 
    } 
} 
0

我不認爲有一個內置的方式來實現這一點,但我能想出這2種方法:

$start = 'a'; 
$end = 'z'; 

function sumDecimal($n) 
{ 
    return(ord($n)); 
} 

while($start <= $end) 
{ 
    $startArr = str_split($start); 
    $endArr = str_split($end); 
    $startVal = array_sum(array_map("sumDecimal", str_split($start))); 
    $endVal = array_sum(array_map("sumDecimal", str_split($end))); 
    if($startVal <= $endVal) 
    { 
     echo $start++ . ", "; 
    } 
    else 
    { 
     break; 
    } 
} 

這將分裂$start$end串到Array,然後將得到其所有字符ASCII value,並將其總結。只要$start的值小於或等於$end的值,它將迭代,否則它將停止。DEMO

當心:將治療以外的任何其他a...az...z不正確。例如它將評估azza相同。

或者

$start = 'a'; 
$end = 'z'; 

while($start <= $end) 
{ 
    if(strlen($start) <= strlen($end)) 
    { 
     echo $start++ . ", "; 
    } 
    else 
    { 
     break; 
    } 
} 

這將只要$start的長度小於或等於$end迭代。 DEMO

+0

感謝您的評論。您的代碼已經在第二次迭代中停止,當時$ start ='a'; $ end ='aa';我們的文件不得少於30列,所以這對我們來說不起作用。 – alejosky

相關問題