【问题标题】:string manipulation uppercase and lowercase in PHPPHP中的字符串操作大写和小写
【发布时间】:2015-11-08 16:31:12
【问题描述】:

我在最近的一次采访中被问到这个问题。 字符串包含 a-z、A-Z 和空格。对字符串进行排序,使所有小写字母都在开头,空格在中间,大写字母在结尾。小写和大写之间的原始顺序需要保持不变。这就是我想出的:

$str = "wElComE to CaLiFOrNiA";

$lowercase ="";
$uppercase="";
$spaces="";

for ($i=0 ; $i <= strlen($str)-1 ; $i++)
{
    if ($str[$i] <= 'z' && $str[$i] >= 'a'  )
    {
        $lowercase .=$str[$i];
    }

    else if (($str[$i] <= 'Z' && $str[$i] >= 'A'))
    {
        $uppercase .=$str[$i];
    }
    else
    {
        $spaces.=$str[$i];
    }
}
echo $lowercase.$spaces.$uppercase;

input: wElComE to CaLiFOrNiA
output: wlomtoairi ECECLFONA

我想知道是否有更好的方法来做到这一点?并且输入字符串有2个空格,输出只显示1个空格。这个复杂度是 O(N) 对的。

有什么想法吗?

【问题讨论】:

  • 如果您查看 html 输出,则会优化空间。查看 html 源代码以查看所有空格。
  • 有趣,我不知道为什么 html 会优化空间。我正在打印输出字符串,如果字符串中有空格,它应该正确显示吗?
  • 因此你应该使用:echo "&lt;pre&gt;".$lowercase.$spaces.$uppercase."&lt;/pre&gt;";
  • 是的,编辑了原帖
  • O(N) right 是什么意思?

标签: php string string-matching


【解决方案1】:
function sortString($string)
{
    $string_chars = str_split($string);

    $output = ['', '', ''];

    foreach ($string_chars as $char) {
       $output[$char === ' ' ? 1 : ($char === ucfirst($char) ? 2 : 0)] .= $char;
    }

    return implode('', $output);
}

echo sortString("wElComE to CaLiFOrNiA");

wlomtoairi ECECLFONA

【讨论】:

    【解决方案2】:

    我认为您的解决方案相当不错,但是如果您进行微优化,您可以进行一些小的更改。以下至少在我的系统上比上面的正则表达式解决方案(基准运行 10000 次)要快:

    $str = "wElComE to CaLiFOrNiA";
    $lowercase = "";
    $uppercase = "";
    $spaces    = "";
    
    $end = strlen($str); // Calculate length just once
    for ($i = 0; $i < $end; $i++) {
        $c = $str[$i]; // Get $str[$i] once
    
        // We know there are only A-Z, a-z and space chars so we
        // only need a greater-than check ('a' > 'A' > ' ')
        if ($c >= 'a') {
            $lowercase .= $c;
        } else if ($c >= 'A') {
            $uppercase .= $c;
        } else
            $spaces .= $c;
    }
    echo $lowercase . $spaces . $uppercase, PHP_EOL;
    

    【讨论】:

    • 感谢优化:)
    【解决方案3】:

    我相信有很多方法可以做到这一点。你可以用正则表达式来做到这一点..

    $str = "wElComE to CaLiFOrNiA";
    preg_match_all('~([a-z])~', $str, $lowercase);
    preg_match_all('~([A-Z])~', $str, $uppercase);
    preg_match_all('~(\h)~', $str, $spaces);
    echo implode('', $lowercase[1]) . implode('', $spaces[1]) . implode('', $uppercase[1]);
    

    输出:

    wlomtoairi  ECECLFONA
    

    当您说better 时,您指的是性能、可读性还是其他方面?

    第二种正则表达式方法:

    $str = "wElComE to CaLiFOrNiA";
    echo preg_replace('~[^a-z]~', '', $str) . preg_replace('~[^\h]~', '', $str) . preg_replace('~[^A-Z]~', '', $str);
    

    【讨论】:

    • 感谢您的解决方案。我正在寻找更好的表现。我们可以优化它。 ?目前是 O(n)
    • Regex 需要0.00049 秒才能运行,循环需要0.000143 秒才能运行。 eval.in/417178
    • 嗯,在 eval 上运行基准测试每次都会带回不同的时间。不过 preg_replace 恢复得更快了。
    • 感谢您的帮助! :)
    猜你喜欢
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2019-11-22
    • 2016-07-14
    • 2020-09-16
    • 2016-01-25
    • 2011-01-16
    相关资源
    最近更新 更多