php 排序字符串中的字符,优先顺序依次为小写、大写、数字和符号

f0ofjuux  于 2023-04-28  发布在  PHP
关注(0)|答案(2)|浏览(144)

我是PHP的新手,正在尝试解决涉及排序的编程问题。我想解决这个问题,其中输入和输出如下。
排序前:6Ata7~58jh&*(*HLy^)&a[yjJ>8]G8,$9<Y;B:%^
排序后:jhytaayjYBJGAHL8968758~&*(*^)&[>],$<;:%^
我需要帮助理解如何根据标题中提到的顺序状态进行排序,以及如何从上述输入和输出中获得相同的结果。下面是我正在编写的代码:

function reverseString($string){
    $stringlen = strlen($string) - 1;
    $split_str = str_split($string, 1);

    $array = array();

    for($i = 0; $i <= $stringlen; $i++){
        array_push($array, $split_str[$i]);
    }

    rsort($array, SORT_STRING | SORT_NUMERIC | SORT_FLAG_CASE | SORT_NATURAL);

    return $array;
}

if(isset($_POST['input']) && !empty($_POST['input'])){
    echo '<pre>';
    echo 'Before sort: ';
    print_r($_POST['input']);
    echo '<br>--------------------<br>';
    echo 'After sort:' ;
    print_r(reverseString($_POST['input'])); 
    echo '</pre>';
}
zzwlnbp8

zzwlnbp81#

一种选择是使用lambda函数对字符串字符数组进行排序。我们可以在数组上使用usort(),辅助函数get_rank()返回一个值,从1到4,这取决于字符是小写、大写、数字还是其他字符(包括符号)。

function get_rank($letter) {
    if (ctype_lower($letter)) {
        return 1;
    }
    else if (ctype_upper($letter)) {
        return 2;
    }
    else if (is_numeric($letter)) {
        return 3;    
    }
    else {
        return 4;
    }
}

$input = "6Ata7~58jh&*(*HLy^)&a[yjJ>8]G8,$9<Y;B:%^";
echo $input . "\n";
$letters = str_split($input);
usort($letters, function($a, $b) {
    return get_rank($a) > get_rank($b);
});
$output = implode("", $letters);
echo $output;

这将打印:

6Ata7~58jh&*(*HLy^)&a[yjJ>8]G8,$9<Y;B:%^
ajyjhatyYBAGJHL9886875,%:;~<$&)&]*>(*^[^

请注意,您没有指定任何用于在小写字母、符号等组中排序的逻辑。上述逻辑可以被修改以包括这一点。

xt0899hw

xt0899hw2#

PHP没有任何本机函数可以按字符对字符串进行排序,因此在实现排序算法之前必须拆分字符串。
一种技术是在preg_match_all()调用中使用特定排序的可选捕获组,然后使用其结果对拆分数组进行排序。(Like this answer)。这样做的另一个好处是在每个字符类别中以升序方式进行排序。
代码:(Demo

preg_match_all('/([a-z])|([A-Z])|(\d)|(.)/', $chars, $m, PREG_SET_ORDER);
$array = str_split($chars);
array_multisort($m, $array);
echo implode($array);

要保留字符在各自类别中的原始顺序,请利用查找数组来确定遇到字符的优先级。(Like this answer
代码:(Demo

$lookup = array_fill_keys(range('a', 'z'), 0) + array_fill_keys(range('A', 'Z'), 1) + array_fill_keys(range(0, 9), 2);
$array = str_split($chars);
usort($array, fn($a, $b) => ($lookup[$a] ?? 3) <=> ($lookup[$b] ?? 3));
echo implode($array);

相关问题