PHP:使用递增的字符变量进行计数时的比较
我正在做一个类似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
应该工作,因为我们同列负荷工作。
谢谢!
试试这个:
// 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,它是计算结果:-
'c'
= 3(字母索引)
-
-
'ba'
计算结果为,其由下式计算53:-
'b'
= 52 =(2(指数在字母)×(26(基值)^ 1(列数)))。 -
'a'
= 1(在字母索引)
-
-
'bca'
计算为1431,其由下式计算:-
'b'
= 1352 =(2(指数在字母)×(26(基值)^ 2(列号)))。 -
'c'
= 78 =(3(字母索引)×(26(基值)^ 1(列号)))。 -
'a'
= 1(在字母索引)
-
-
'bdca'
计算为37935,其由下式计算:-
'b'
= 35152 =(2(指数在字母)×(26(基值)^ 3(列号)))。 -
'd'
= 2704 =(4(字母索引)×(26(基准值)^ 2(列号)))。 -
'c'
= 78 =(3(字母索引)×(26(基值)^ 1(列号)))。 -
'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
感谢您提出这样一个有趣的问题!
很好的回答!我只是将AisLessThanB的返回值更改为$ aInt - $ bInt,所以我可以使用AisLessThanB($ a,$ b)vs alejosky
我不认为这样增加字符串是个好主意。实际上,增加一个char的ASCII值。在这种情况下字符串的比较是按字母顺序排列的(https://stackoverflow.com/a/12888720/5346387),所以我猜它不会按照您的预期工作。
但是对于你的问题 - 我不认为会有这样的PHP本地函数。我建议创建一个从数字[0,1,2,3 ... 27,28 ..]的线性列表到您的字母代码[a,b,c..aa,ab ...]的映射函数。我希望我帮助:)
如果比较字符之前比较字符串长度怎么办?
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;
}
}
我不认为有一个内置的方式来实现这一点,但我能想出这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...a
或z...z
不正确。例如它将评估az
和za
相同。
或者
$start = 'a';
$end = 'z';
while($start <= $end)
{
if(strlen($start) <= strlen($end))
{
echo $start++ . ", ";
}
else
{
break;
}
}
这将只要$start
的长度小于或等于$end
迭代。 DEMO
感谢您的评论。您的代码已经在第二次迭代中停止,当时$ start ='a'; $ end ='aa';我们的文件不得少于30列,所以这对我们来说不起作用。 – alejosky
为什么'AA'