Мне задали этот вопрос в недавнем интервью.
Строка содержит 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 пробела, а на выходе отображается только один пробел. Сложность этого права O (N).
Есть идеи?
Я уверен, что есть много способов сделать это. Вы можете сделать это с помощью регулярных выражений ..
$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);
Я думаю, что ваше решение довольно хорошо, но если вы занимаетесь микрооптимизацией, вы можете внести некоторые незначительные изменения. Следующее выполняется быстрее, чем описанные выше решения с регулярными выражениями (тест производительности 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;
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