Scramble Sort
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
In this problem you will be given a series of lists containing both words and numbers. The goal is to sort these lists in such a way that all words are in alphabetical order and all numbers are in numerical order. Furthermore, if the nth element in the list is a number it must remain a number, and if it is a word it must remain a word.
译文:这个问题中,你会得到一系列包含单词和数字的列表。我们的目标是以这样一种方式对这些列表进行排序,以便所有单词按字母顺序排列,所有数字按数字顺序排列。此外,如果列表中的第n个元素是数字,它必须保留一个数字,如果它是一个单词,它必须保持一个单词。
Output:
For each list in the input, output the scramble sorted list, separating each element of the list with a comma followed by a space, and ending the list with a period.
译文:对于输入中的每个列表,输出争用排序列表,用逗号分隔列表中的每个元素,后跟一个空格,并以句点结束列表。
Sample Input:
0.
banana, strawberry, OrAnGe.
Banana, StRaWbErRy, orange.
10, 8, 6, 4, 2, 0.
x, 30, -20, z, 1000, 1, Y.
50, 7, kitten, puppy, 2, orangutan, 52, -100, bird, worm, 7, beetle.
.
Sample Output:
0.
banana, OrAnGe, strawberry.
Banana, orange, StRaWbErRy.
0, 2, 4, 6, 8, 10.
x, -20, 1, Y, 30, 1000, z.
-100, 2, beetle, bird, 7, kitten, 7, 50, orangutan, puppy, 52, worm.
解题思路:字符串+排序。做这道题整整花了4个小时,(流下了没技术的眼泪QAQ)。回归正题,题目已经说得很清楚了,对一串字符串中的单词和数值分别进行排序,然后输出它们的字典序,但是要求原本是单词的位置现在输出还是单词,原来是数值的位置现在还是输出数值,注意输出每个子字符串后面有逗号和空格,当然句尾结束是点字符。刚开始想用C++解决,后来发现处理一些细节上比较繁琐(怪我没学精,打脸==+),于是用java一次AC了它。思路是这样子,先读取一整串字符串中以逗号分隔的子字符串的个数,用一个布尔数组来标记每个子字符串的位置是否是数值,是的话为true,否则(单词的话)为false,然后将单词保存在单词数组中,将数值保存在数值数组中;接下来进行排序,但是不能用Arrays.sort()排序两个数组,理由:①单词数组排序是忽略字母大小的,所以不能直接用库函数,而是采用s1.compareToIgnoreCase(s2)方法(返回值为int,如果s1>s2,返回对应字符ASCII的差值大于0;s1==s2,返回0;s1<s2,返回小于0的ASCII差值)来进行排序,这里都采用选择排序;②对数值数组的排序,刚开始直接用库函数进行排序,后面发现是错的,于是自己再写了一个选择排序,排序完剩下就更简单了,直接输出。写完这个担心输入的字符串长度很长,可能导致其中同一类型的数据过多,这样排序耗时会变长,但提交后显示128ms,说明选择排序可以过,而不必写快排!!!
AC代码:
1 import java.util.Scanner;
2 public class Main {
3 public static void main(String[] args) {
4 Scanner scan=new Scanner(System.in);
5 String str1=scan.nextLine();//读入字符串
6 while(!str1.equals(".")){
7 String str2=str1.substring(0, str1.length()-1);
8 String []str3=str2.split(", ");
9 int len=str3.length;
10 boolean []isdight=new boolean[len];//判断该位置上是数字的话为真值,其余默认假值
11 int []num=new int[len];//至少申请这么长的长度
12 String []word=new String[len];//用两个数组来分别保存单词和数字
13 int indexOfword1=0,indexOfnum1=0;
14 for(int i=0;i<len;++i){
15 if(Character.isLetter(str3[i].charAt(0))){
16 isdight[i]=false;
17 word[indexOfword1++]=str3[i];//如果第一个是字母的话就直接赋值给word数组
18 }
19 else{
20 isdight[i]=true;
21 num[indexOfnum1++]=Integer.parseInt(str3[i]);//否则转换成数值给num数组
22 }
23 }
24 //字符串单词排序代码
25 for(int i=0;i<indexOfword1-1;++i){
26 int k=i;
27 for(int j=i+1;j<indexOfword1;++j){
28 if(word[k].compareToIgnoreCase(word[j])>0)//升序排列
29 k=j;
30 }
31 if(k!=i){
32 String tmp=word[i];
33 word[i]=word[k];
34 word[k]=tmp;
35 }
36 }
37 //数值排序
38 for(int i=0;i<indexOfnum1-1;++i){
39 int k=i;
40 for(int j=i+1;j<indexOfnum1;++j)
41 if(num[k]>num[j])k=j;
42 if(k!=i){
43 int tmp=num[i];
44 num[i]=num[k];
45 num[k]=tmp;
46 }
47 }
48 //输出
49 int indexOfword2=0,indexOfnum2=0;
50 for(int i=0;i<len-1;++i){
51 if(isdight[i])System.out.print(num[indexOfnum2++]+", ");
52 else System.out.print(word[indexOfword2++]+", ");
53 }
54 if(isdight[len-1])System.out.println(num[indexOfnum2]+".");
55 else System.out.println(word[indexOfword2]+".");
56 str1=scan.nextLine();//读入下一个字符串
57 }
58 }
59 }