一、真题描述
给定 n 个字符串,请你对这 n 个字符串按照以下规则从小到大排序。
对于任意两个字符串 s 和 t ,在排序后应当满足:
- 若 s是 t 的一个前缀,则 s 在排序后的下标小于等于 t 的在排序后的下标。
- 若存在整数 i ,使得 s 的前 i−1 个字符和 t 的前 i−1个字符相同,且 s 和 t 的第 i个字符不同,则比较第 i 个字符的大小关系(字符的大小关系顺序由输入数据给出)。若 s 的第 i个字符小于等于 t 的第 i 个字符,则 s 在排序后的下标小于等于 的在排序后的下标。
容易发现,上述排序方法的排序结果是唯一的。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
输入输出描述:
示例1:
输入例子:abcdefghijklmnopqrstuvwxyz
3aaa
aac
aaaa
输出例子:
aaa
aaaa
aac
示例2:
输入例子:zyxwvutsrqponmlkjihgfedcba
3aaa
aac
aaaa
输出例子:
aac
aaa
aaaa
二、解题思路&代码实现
解题思路:
代码实现:
java:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String order = in.nextLine();
int n = in.nextInt();
in.nextLine(); // Consume the newline after the integer
List<String> list = new ArrayList<>();
for (int i = 0; i < n; ++i) {
list.add(in.nextLine());
}
// Create a map to store the priority of each character
Map<Character, Integer> priority = new HashMap<>();
for (int i = 0; i < order.length(); ++i) {
priority.put(order.charAt(i), i);
}
// Sort the list using the custom comparator
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int len = Math.min(s1.length(), s2.length());
for (int i = 0; i < len; ++i) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
int p1 = priority.get(c1);
int p2 = priority.get(c2);
return (p1 < p2) ? -1 : 1;
}
}
// Compare lengths if one is a prefix of the other
return Integer.compare(s1.length(), s2.length());
}
});
// Output the sorted list
for (String s : list) {
System.out.println(s);
}
}
}
java 另一种实现方案:
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String letters = in.next();
char[] lettersArray = letters.toCharArray();
int[] letterWeight = new int[1024];
for(int j = 0; j < lettersArray.length; j++) {
int charValue = lettersArray[j];
letterWeight[charValue] = j;
}
int n = in.nextInt();
int i = 0;
String[] strArray = new String[n];
while(i < n) {
strArray[i] = in.next();
i++;
}
Arrays.sort(strArray, new Comparator<String>() {
public int compare(String a, String b) {
int ret = 0;
int len = Math.min(a.length(), b.length());
for (int i = 0; i < len; i++) {
int v1 = letterWeight[a.charAt(i)];
int v2 = letterWeight[b.charAt(i)];
ret = v1 - v2;
if (ret != 0) {
return ret;
}
}
return a.length() - b.length();
}
});
for (String item : strArray) {
System.out.println(item);
}
}
}
php :
<?php
function customSort($order, $strings) {
$priority = array_flip(str_split($order)); // char => index as priority
usort($strings, function($a, $b) use ($priority) {
$len = min(strlen($a), strlen($b));
for ($i = 0; $i < $len; $i++) {
if ($a[$i] != $b[$i]) {
return $priority[$a[$i]] <=> $priority[$b[$i]];
}
}
// If one is prefix of another, the shorter string comes first
return strlen($a) <=> strlen($b);
});
return $strings;
}
// Input handling
$order = trim(fgets(STDIN));
$n = intval(trim(fgets(STDIN)));
$strings = [];
for ($i = 0; $i < $n; $i++) {
$strings[] = trim(fgets(STDIN));
}
// Sort and output
$result = customSort($order, $strings);
foreach ($result as $str) {
echo $str . PHP_EOL;
}
?>
golang:
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
type StringWithOrder struct {
s string
priority map[byte]int
}
func (sw *StringWithOrder) compare(a, b string) int {
minLen := len(a)
if len(b) < minLen {
minLen = len(b)
}
for i := 0; i < minLen; i++ {
if a[i] != b[i] {
return sw.priority[a[i]] - sw.priority[b[i]]
}
}
return len(a) - len(b)
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Read order
scanner.Scan()
order := scanner.Text()
// Build priority map
priority := make(map[byte]int)
for i := 0; i < len(order); i++ {
priority[order[i]] = i
}
// Read number of strings
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
// Read strings
strings := make([]string, n)
for i := 0; i < n; i++ {
scanner.Scan()
strings[i] = scanner.Text()
}
// Define custom sort
sort.Slice(strings, func(i, j int) bool {
a := strings[i]
b := strings[j]
sw := &StringWithOrder{priority: priority}
return sw.compare(a, b) < 0
})
// Output result
for _, s := range strings {
fmt.Println(s)
}
}