英文单词排序 PTA (JAVA)

目录

  • 题目描述:
  • 前言:
  • 1.利用冒泡排序解题(AC):
  • 2.利用sort函数解题(AC):
  • 3.利用快速排序解题(报错):
  • 4.利用数组下标与字符串长度解(AC 且 推荐):

题目描述:

本题要求编写程序,输入若干英文单词,对这些单词按长度从小到大排序后输出。如果长度相同,按照输入的顺序不变。

输入格式:

输入为若干英文单词,每行一个,以#作为输入结束标志。其中英文单词总数不超过20个,英文单词为长度小于10的仅由小写英文字母组成的字符串。

输出格式:

输出为排序后的结果,每个单词后面都额外输出一个空格。

输入样例:

blue
red
yellow
green
purple
#

输出样例:

red blue green yellow purple


前言:

一般碰到这个题,第一想法可能就是用排序函数去解决这道题,但是如果存粹使用排序的话还是会有一些漏洞,这个漏洞会在本篇利用快速排序解题中详细说明。


1.利用冒泡排序解题(AC):

解题:

利用冒泡排序的排序方式,只是交换规则上改用比较两个字符串的长度,前者长度大于后者长度则交换,否则不交换。

代码:

import java.util.*;

public class Main {
 
 public static String a[] = new String [20];
 
 public static void main(String[] args) {
   Scanner sc = new Scanner(System.in);
   for(int i = 0; i < 20; i ++) a[i] = "";
   String s = sc.nextLine();
   int i = 0;
   while(!s.equals("#")) {
        a[i] = s;
        i ++;
        s = sc.nextLine();
   }
      Array_mp(a);
      for(int k = 0; k < a.length; k ++)
          if(a[k].length() != 0)
          System.out.print(a[k] + " ");
    }
 
 public static void Array_mp(String a[]) {
        for(int i = 0; i < a.length - 1; i ++) {
           for(int j = 0; j < a.length - i - 1; j ++) {
              String temp = "";
              if(a[j].length() > a[j + 1].length()) {
                 temp = a[j + 1];
                 a[j + 1] = a[j];
                 a[j] = temp;
              }
           }
        }
 }
}

2.利用sort函数解题(AC):

解题:

java自带sort函数运用的是 “综合排序” 大致排序规则是:

sort()是根据需要排序的数组的长度进行区分的:

首先先判断需要排序的数据量是否大于60。
小于60:
使用插入排序,插入排序是稳定的。
大于60的数据量会根据数据类型选择排序方式:
基本类型:使用快速排序。「因为基本类型不需要考虑稳定性」 Object类型:使用归并排序「因为归并排序具有稳定性」

上述问题参考自:详述Java中sort排序函数

由于本题单词数量不超过20个所以sort使用的是插入排序
所以解题方法也非常清晰,重构一下函数的判断规则即可(忘记重构方式可以看我写的:sort 函数排序规则的重写 JAVA):

代码:

import java.util.*;

public class Main {
 
 public static String a[] = new String [20];
 
 public static void main(String[] args) {
   Scanner sc = new Scanner(System.in);
   for(int i = 0; i < 20; i ++) a[i] = "";
   String s = sc.nextLine();
   int i = 0;
   while(!s.equals("#")) {
        a[i] = s;
        i ++;
        s = sc.nextLine();
   }
       Arrays.sort(a, 0, a.length, new Comparator<String>() {
       public int compare(String a, String b) {
            return a.length() - b.length();
       }
      });
      for(int k = 0; k < 20; k ++) if(a[k].length() != 0) System.out.print(a[k] + " ");
    }
}

本题排序的是String类,所以不能用简写版的重构方法。

注意:c++的sort函数与java的sort函数并不一样!


3.利用快速排序解题(报错):

解题:

由于快排的性质,它并不能保证两个相同长度的字符串的先后顺序

例如:

a
bd
c
e
#

利用快排可能得到(选取基准为a):

a e c bd

正解:

a c e bd

由于bd长度大于c的长度,所以以快排的交换规则bd和c会交换。

忘记快排怎么写的可以看我写的:快速排序算法原理 Quicksort —— 图解(精讲) JAVA

幸运的是冒泡排序规则不会破坏这种先后顺序,所以冒泡排序不会错。

至于快排运行的代码就不放出来了,显示结果是有一个测试点不通过,血压飙升。

为什么纯粹用排序算法有漏洞?

归根结底是因为,排序只能判断两个字符串的长度是否一样,但没办法判断他俩谁先被输入。因为快排无法保证这种先后顺序所以快排会错,而冒泡碰巧能不会破坏这种先后顺序所以险胜快排。

解决方法:

根据数组下标的大小加入一些判定规则,以保证相同字符串的先后顺序的维护。

但是加入上述判别方式后又会使代码变得更加繁琐,那么有没有更优雅的方式呢?

答案就在第4部分。


4.利用数组下标与字符串长度解(AC 且 推荐):

解题思路:

让我们越过上述用排序解题的鸿沟,重新审视本题。

本题要求将英文单词按长度递增输出长度相同的按先后顺序输出

这里我们不妨联想一下,一个数组的下标从前往后肯定也是递增的,如果将单词长度与数组下标对应上,那是否也是一种解决本题的方式?

例如:
设立一个 String 类数组 a[ ]

单词blue的长度为4,那么将输入的blue赋给数组下标为4的数组元素即:a[4] = blue;

同理 yellow 长度为5,那么a[5] = yellow;

最后将数组由前往后输出即可。

但是别忘了还有一个问题,如果再输入一个长度也为4的单词abcd又该怎么办?

解决方法也很简单:放在 blue 的后面即可:

即: a[4] = a[4] + abcd

这样就很容易就解决了相同长度单词先后顺序的问题。

最后细节的在两个单词间加上空格,本题就解决了!

代码:

import java.util.*;

public class Main {

 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a[] = new String[10];
        for(int i = 0; i < 10; i ++) a[i] = "";//初始化。
        String s = sc.nextLine();
        while(!s.equals("#")) {
             if(a[s.length()].length() > 0) a[s.length()] = a[s.length()] + s + " ";
             else a[s.length()] = s + " ";
             s = sc.nextLine();
        }
        for(int i = 0; i < 10; i ++) System.out.print(a[i]);
 }

}

你可能感兴趣的:(java,算法,排序算法)