day12 HJ14 字符串排序(java)

135 阅读2分钟

题目来源: HJ14 字符串排序

题目描述:

  • 描述: 给定 n 个字符串,请对 n 个字符串按照字典序排列。
    数据范围: 1n1000 1≤n≤1000   ,字符串长度满足 1len100 1≤len≤100 
  • 输入描述: 输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
  • 输出描述: 数据输出n行,输出结果为按照字典序排列的字符串。
示例1:
输入:
9
cap
to
cat
card
two
too
up
boat
boot

输出:
boat
boot
cap
card
cat
to
too
two
up

思路:暴力破解

将所有单词放入字符串数组中,将每个单词进行比较后,将字典中位置靠前的单词进行输出,若字典中靠前的单词在字符串数组的位置靠后,则先进行位置互换,将靠前的单词在字符串数组的位置前移

具体实现:

import java.util.Scanner;

public class day12 {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String[] strings = new String[n];
        for(int i = 0;i < n;i++) {
            strings[i] = scanner.next();
        }
        for(int i = 0;i < n;i ++){
            for(int j = i + 1;j < n;j ++){
                if(MySwap(strings[i],strings[j])){ 
                    String temp = strings[i];
                    strings[i] = strings[j];
                    strings[j] = temp;
                }
            }
            System.out.println(strings[i]);
        }
    }

    public static boolean MySwap(String a,String b) {
        for(int i = 0;i<Math.min(a.length(),b.length());i++){ 
            if((a.charAt(i) - b.charAt(i)) < 0){
                return false;
            }else if((a.charAt(i) - b.charAt(i)) > 0){
                return true;
            }
        }
        if(a.length() >= b.length()){
            return true;
        }else{
            return false;
        }
    }
}

思路杂记

1.将单词放入字符串数组的操作,要使用next()方法,如果使用nextLine()方法,由于该方法会读取空格,会出现没有读到最后一个单词,因为在第一个intInt()读取后,剩下的回车也会被nextLine()读取到。

2.在使用MySwap()的方法时,一开始的操作是如果if语句是TRUE,则输出string[j],如果if语句是FALSE,则输出string[i],

for(int i = 0;i < n;i ++){
    for(int j = i + 1;j < n;j ++){
        if(MySwap(strings[i],strings[j])){ 
           System.out.println(strings[j]);         
        }
    }
    System.out.println(strings[i]);
}

但这是有问题的,比如输入三个单词codacode,那么输出的结果就是a cod a code:

  • 因为第一次cod与a比较时,if语句是TRUE,所以输出此时的string[j],此时j为1,即a,但是当里层的for循环第一次结束时,会接着输出此时的string[i],此时i为0,即cod;
  • 进行第二轮for循环时,a与code进行比较,if语句是FALSE,则直接输出string[i],此时i为1,输出a

3.对于MySwap()的解释:

  首先,我们得明白,如果MySwap的结果是TRUE,则会进行交换,反之,不进行交换

  • for循环中,是将两个单词的每个字母从前到后进行比较,a.charAt(i) - b.charAt(i)的结果若>0,说明前者在字典靠后的位置,那么就需要交换,则需要MySwap的结果为TRUE
  • 如果for循环并没有得出结论,说明两个单词在Math.min(a.length(),b.length())的基础上,是一样的,那么此时进行长度比较,length值大的,在字典里的位置靠后,所以a.length() >= b.length()时,需要进行交换,则需要MySwap的结果为TRUE

思路二 非暴力破解,用sort()

import java.util.*;

public class Main {
    public static void main(String[] args) 
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String[] strings = new String[n];
        for (int i = 0; i < n; i++) {
            strings[i] = in.next();
        }
        Arrays.sort(strings);
        for (String str : strings) {
            System.out.println(str);
        }
    }
}

思路杂记二

1.对于for循环的写法for (String str : strings),这种写法是增强for循环,可以理解为

for(int i = 0;i < strings.length(); i++){ 
    String str = strings[i]; //当成数组的写法
} 

编译器会认为:

  • 创建名称为str 的String变量;
  • 将strings的第一个元素赋给str;
  • 执行重复的内容;
  • 赋值给下一个元素str;
  • 重复执行至所有的元素都被运行为止
  • 优点: 这种写法让我们代码看起来更加的简洁
  • 缺点:
    1.只能顺次遍历所有元素,无法实现较为复杂的循环
    2.对于数组,不能方便的访问下标值;
    3.对于集合,与使用Interator相比,不能方便的删除集合中的内容(在内部也是调用Interator).
    4.除了简单遍历并读取其中的内容外,不建议使用增强的for循环