1 題目重述
題目描述:輸入n個(gè)字符串,降序排列后,按照{(diào)x,y,z}格式輸出
例如:
????輸入:3
????輸入:AK,AS,AC
????輸出:{AC,AK,AS}
2 題目分析
2.1題目梳理
題目中的關(guān)鍵字:輸入,字符串,降序排列,格式輸出
今天的題目需要我們獲取兩個(gè)類型內(nèi)容,一個(gè)是整型,一個(gè)是字符串。
于是我們分別采用 Scanner 類的 nextInt() 方法和 next() 方法對兩個(gè)內(nèi)容進(jìn)行獲取,并分別保存在整型 n 和字符串 str 中。
下面我們就要思考如何實(shí)現(xiàn)數(shù)組的降序排列。我們需要將數(shù)組中的每一個(gè)元素兩兩進(jìn)行比較,誰大誰就排在前面。我們可以采用**冒泡排序**算法對字符串?dāng)?shù)組進(jìn)行排序。
最后,我們需要思考如何按照指定格式輸出字符串。我們可以采用System.out.print() 方法對字符串進(jìn)行字符串首尾指定字符的拼接工作,同時(shí)通過 for 循環(huán)遍歷每一個(gè)元素,并在元素后加上指定的字符。
這個(gè)過程聽起來十分復(fù)雜,那么有沒有更好的實(shí)現(xiàn)方法呢?有的。Java 為我們提供了 StringJoiner 類的 joiner.add() 方法,可以對字符串按照一定格式進(jìn)行拼接。我們可以通過創(chuàng)建 StringJoiner 類的對象來調(diào)用 StringJoiner 類的有參構(gòu)造方法,以此來達(dá)到我們的需要。
2.2 實(shí)現(xiàn)思路
2.2.1 輸入
采用 Scanner 類的 nextInt() 方法,獲取一個(gè)整數(shù) n 。
采用 Scanner 類的 next() 方法,獲取一個(gè)字符串 str 。
2.2.2 對原字符串按照指定字符串“,”進(jìn)行分割
采用 String 類的split()方法,將原字符串按照指定字符串進(jìn)行分割,返回切割后的字符串?dāng)?shù)組。
2.2.3 判斷字符串元素個(gè)數(shù)與輸入個(gè)數(shù) n 是否一致
先采用 if 語句進(jìn)行字符串元素個(gè)數(shù)的判斷,如果小于輸入個(gè)數(shù) n ,那么我們題目的條件就無法達(dá)成,為了避免這種情況,我們就需要對字符串元素個(gè)數(shù)與輸入個(gè)數(shù) n 是否一致這一問題進(jìn)行判斷。
此時(shí),在字符串元素個(gè)數(shù)小于輸入個(gè)數(shù) n 的情況下,我們就需要返回 “輸入有誤!” ,同時(shí)退出JVM虛擬機(jī),使得程序結(jié)束。
同樣,為了避免輸入字符串元素個(gè)數(shù)大于輸入個(gè)數(shù) n 。同時(shí)有效地保證,輸入的字符串個(gè)數(shù)與輸入個(gè)數(shù) n 的一致性。我們采用 System.arraycopy() 方法,將數(shù)組按照指定要求進(jìn)行復(fù)制。這樣做的目的是,保證字符串元素個(gè)數(shù)與輸入個(gè)數(shù) n 一致。
2.2.4 倒序排列
思路:采用冒泡排序法的倒序排列方式對原字符串?dāng)?shù)組進(jìn)行倒序排列。
冒泡排序算法是一種非常常用的算法,在這里和大家針對本題進(jìn)行敘述。
冒泡排序算法:
```handlebars
BUBBLE-SORT(A)
1. for i <--- 1
2. do for j <--- length[A] downto i+1
3. do if A[j] < A[j+1]
4. then exchange A[j] <---> A[j+1]
```
分析:
本題中,我們首先要知道比幾輪,其次要知道每輪比較多少次。
第一個(gè)元素和第二個(gè)元素比較,再和第三個(gè)元素比較,以此類推... ...,直到第一個(gè)元素和第 n 個(gè)元素比較;
第二個(gè)元素和第三個(gè)元素比較,再和第四個(gè)元素比較,以此類推... ...,直到第二個(gè)元素和第 n 個(gè)元素比較;
以此類推 ... ...
直到,第 n-1 個(gè)元素和第 n 個(gè)元素進(jìn)行比較。
我們用 n 代表元素個(gè)數(shù),用 i 代表比較的輪數(shù),用 k 代表每輪比較的次數(shù)。
我們發(fā)現(xiàn)共需要比較 n-1 輪,同時(shí)每輪比較 n-1-i 次。
由此,我們需要進(jìn)行雙重循環(huán),外層循環(huán)控制比較的輪數(shù),內(nèi)層循環(huán)控制每輪比較的次數(shù)。同時(shí),我們需要采用 String 類的 compareTo() 方法進(jìn)行相鄰元素大小的判斷,滿足要求保持位置不變,否則交換兩個(gè)元素位置。
2.2.5 按指定格式輸出
這里為大家提供了兩種思路,供大家參考。
思路1:通過 for(){...} 循環(huán)遍歷,直接拼接。
這種輸出方式不需要我們多想,就你需要什么形式,我輸出什么形式。但是在拼接的時(shí)候需要采用 for 循環(huán)對字符串進(jìn)行遍歷,同時(shí)我們發(fā)現(xiàn)輸出格式中最后一個(gè)元素的后面沒有 “,” ,因而,我們需要采用 if判斷語句判斷元素是否為最后一個(gè)元素,如果不是,拼接 “,” ,否則不拼接。
值得注意的是這里的輸出采用的是 System.out.print("") 輸出形式,只輸出不換行。
思路2:采用 StringJoiner 類的 joiner.add() 方法,對字符串按照一定格式進(jìn)行拼接。
我們思考,如果元素少采用第一種思路也沒有什么問題,但是如果元素多了呢?或者元素要求復(fù)雜了呢?有沒有一種更好的實(shí)現(xiàn)思路?
幸運(yùn)的是,java 為我們提供了一個(gè)這樣的類型 StringJoiner 類。我們可以通過創(chuàng)建 StringJoiner 類的對象來調(diào)用 StringJoiner 類的有參構(gòu)造方法。
????采用 StringJoiner joiner=new StringJoiner(delimiter, prefix, suffix) ;的形式。
????功能:對字符串按一定要求進(jìn)行連接。
????傳入:字符串之間的間隔符,字符串最前面字符,字符串最后面字符
????返回:連接后的字符串
3 代碼實(shí)現(xiàn)
3.1 方式1:
按指定格式輸出:通過? System.out.print("") 和 for(){...} 循環(huán)遍歷,直接拼接。
3.1.1 代碼語句:
```bash
public static void main(String[] args) {
// 1 獲取輸入的元素個(gè)數(shù)和輸入的字符串
Scanner input = new Scanner(System.in);
// 1.1 獲取輸入的字符串的元素個(gè)數(shù)
System.out.println("請輸入字符串元素個(gè)數(shù):");
int n = input.nextInt();
// 1.2 獲取輸入的字符串
System.out.println("請輸入字符串:");
String str = input.next();
System.out.println("輸入為:" + str);
// 2 對輸入的字符串進(jìn)行切割
// String 類的split()方法
// 功能:按照指定字符串對原字符串進(jìn)行切割
// 傳入:原字符串
// 返回:切割后的字符串?dāng)?shù)組
String[] strArray = str.split(",");
// 3 判斷實(shí)際輸入的字符串元素個(gè)數(shù)與輸入的元素個(gè)數(shù)n是否一致
int len = strArray.length;
// 3.1 若實(shí)際輸入字符串元素個(gè)數(shù)小于輸入元素個(gè)數(shù)n
if (len < n) {
System.out.println("輸入有誤!");
System.exit(0);// 退出JVM虛擬機(jī)
}
// 3.2 若實(shí)際輸入字符串元素個(gè)數(shù)大于等于輸入元素個(gè)數(shù)n
// 復(fù)制數(shù)組,使得實(shí)際輸入字符串元素個(gè)數(shù)等于輸入元素個(gè)數(shù)n
// 方法:System.arraycopy()
// 功能:將數(shù)組按照指定要求進(jìn)行復(fù)制
// 返回:復(fù)制后的新數(shù)組
// 傳入:原數(shù)組名,原數(shù)組復(fù)制起始位置的下標(biāo),新數(shù)組名,新數(shù)組復(fù)制起始位置的下標(biāo),復(fù)制元素的個(gè)數(shù)
String[] array = new String[n];
System.arraycopy(strArray, 0, array, 0, len);
// 4 對字符串中元素進(jìn)行降序排列
// 冒泡排序
// 比較:strNumber1.compareTo(strNumber2)方法
// 功能:用于進(jìn)行字符串間的比較
// 形式:(字符串1).compareTo(字符串2)
// 傳入:待比較的兩個(gè)字符串
// 返回:int類型
// 返回值>0,字符串1>字符串2
// 返回值=0,字符串1=字符串2
// 返回值<0,字符串1<字符串2
for (int i = 0; i < n - 1; i++) {
for (int k = 0; k < n - 1 - i; k++) {
if (array[k].compareTo(array[k + 1]) < 0) {
String temp = array[k];
array[k] = array[k + 1];
array[k + 1] = temp;
}
}
}
// 5 按指定格式輸出
// 方法1:通過 for 循環(huán)進(jìn)行遍歷,直接拼接
System.out.println("輸出為:");
System.out.print("{");
for (int i = 0; i < n; i++) {
System.out.print(array[i]);
if (i != n - 1) {
System.out.print(",");
}
}
System.out.print("}");
System.out.println();
}
```
3.1.2 代碼結(jié)果:
```bash
請輸入字符串元素個(gè)數(shù):
3
請輸入字符串:
AK,AS,AC
輸入為:AK,AS,AC
輸出為:
{AS,AK,AC}
```
3.2 方式2:
按指定格式輸出:采用 StringJoiner 類的 joiner.add() 方法,對字符串按照一定格式進(jìn)行拼接。
3.2.1 代碼語句:
```bash
public static void main(String[] args) {
// 1 獲取輸入的元素個(gè)數(shù)和輸入的字符串
Scanner input = new Scanner(System.in);
// 1.1 獲取輸入的字符串的元素個(gè)數(shù)
System.out.println("請輸入字符串元素個(gè)數(shù):");
int n = input.nextInt();
// 1.2 獲取輸入的字符串
System.out.println("請輸入字符串:");
String str = input.next();
System.out.println("輸入為:" + str);
// 2 對輸入的字符串進(jìn)行切割
// String 類的split()方法
// 功能:按照指定字符串對原字符串進(jìn)行切割
// 傳入:原字符串
// 返回:切割后的字符串?dāng)?shù)組
String[] strArray = str.split(",");
// 3 判斷實(shí)際輸入的字符串元素個(gè)數(shù)與輸入的元素個(gè)數(shù)n是否一致
int len = strArray.length;
// 3.1 若實(shí)際輸入字符串元素個(gè)數(shù)小于輸入元素個(gè)數(shù)n
if (len < n) {
System.out.println("輸入有誤!");
System.exit(0);// 退出JVM虛擬機(jī)
}
// 3.2 若實(shí)際輸入字符串元素個(gè)數(shù)大于等于輸入元素個(gè)數(shù)n
// 復(fù)制數(shù)組,使得實(shí)際輸入字符串元素個(gè)數(shù)等于輸入元素個(gè)數(shù)n
// 方法:System.arraycopy()
// 功能:將數(shù)組按照指定要求進(jìn)行復(fù)制
// 返回:復(fù)制后的新數(shù)組
// 傳入:原數(shù)組名,原數(shù)組復(fù)制起始位置的下標(biāo),新數(shù)組名,新數(shù)組復(fù)制起始位置的下標(biāo),復(fù)制元素的個(gè)數(shù)
String[] array = new String[n];
System.arraycopy(strArray, 0, array, 0, len);
// 4 對字符串中元素進(jìn)行降序排列
// 冒泡排序
// 比較:strNumber1.compareTo(strNumber2)方法
// 功能:用于進(jìn)行字符串間的比較
// 形式:(字符串1).compareTo(字符串2)
// 傳入:待比較的兩個(gè)字符串
// 返回:int類型
// 返回值>0,字符串1>字符串2
// 返回值=0,字符串1=字符串2
// 返回值<0,字符串1<字符串2
for (int i = 0; i < n - 1; i++) {
for (int k = 0; k < n - 1 - i; k++) {
if (array[k].compareTo(array[k + 1]) < 0) {
String temp = array[k];
array[k] = array[k + 1];
array[k + 1] = temp;
}
}
}
// 5 按指定格式輸出
// 方法2:StringJoiner
// 格式:StringJoiner joiner=new StringJoiner(delimiter, prefix, suffix) ;
// 功能:對字符串按一定要求進(jìn)行連接
// 傳入:字符串之間的間隔符,字符串最前面字符,字符串最后面字符
// 返回:連接后的字符串
StringJoiner joiner = new StringJoiner(",", "{", "}");// 分別傳入:分隔符,前綴,后綴
for (String temp : array) {
joiner.add(temp);
}
System.out.println("輸出為:" + joiner.toString());
}
```
3.2.2 代碼結(jié)果:
```bash
請輸入字符串元素個(gè)數(shù):
3
請輸入字符串:
AK,AS,AC
輸入為:AK,AS,AC
輸出為:{AS,AK,AC}
```
3.3 方式3:
如果你的程序中需要多次進(jìn)行進(jìn)行降序排列或者是需要按照指定格式輸出,那么我們就可以將冒泡排序和按照指定格式進(jìn)行輸出寫成兩個(gè)方法,在主函數(shù)中調(diào)用即可。本題中,我將冒泡排序(倒序排列)和按照指定格式輸出分別寫成了兩個(gè)方法 bubbleSort() 和 format() 供大家參考。
3.3.1 代碼語句:
```bash
public static void main(String[] args) {
// 1.輸入n
Scanner input = new Scanner(System.in);
System.out.println("請輸入字符串個(gè)數(shù):");
int n = input.nextInt();
// 2.輸入字符串
System.out.println("請輸入字符串:");
String str = input.next();
// 3.分割字符串,轉(zhuǎn)為數(shù)組
String[] temp = str.split(",");
// 4.判斷輸入個(gè)數(shù)是否有誤
// 4.1 輸入個(gè)數(shù)小于n
if (temp.length < n) {
System.out.println("輸入有誤!");
System.exit(0);
}
// 5.復(fù)制數(shù)組(輸入個(gè)數(shù)≥n)
String[] array = new String[n];
System.arraycopy(temp, 0, array, 0, n);
System.out.println("排序前:" + Arrays.toString(array));
// 6.調(diào)用冒泡排序方法
array = bubbleSort(array, n);
// 7.調(diào)用方法并輸出
System.out.println("排序后:" + format(array));
}
/*
* 冒泡排序(降序)
*/
public static String[] bubbleSort(String[] array, int n) {
for (int i = 0; i < n - 1; i++) {
for (int k = 0; k < n - i - 1; k++) {
if (array[k].compareTo(array[k + 1]) < 0) {
String temp = array[k];
array[k] = array[k + 1];
array[k + 1] = temp;
}
}
}
return array;
}
/*
* 參數(shù)array: 需要轉(zhuǎn)換的原數(shù)組
* 返回:指定格式的String類型的字符串
*/
public static String format(String[] array) {
// 輸出指定格式
StringJoiner joiner = new StringJoiner(",", "{", "}"); // 分隔符,前綴,后綴
for (String str : array) {
joiner.add(str); // 添加字符串
}
return String.valueOf(joiner);
}
```
3.3.2 代碼結(jié)果:
```bash
請輸入字符串個(gè)數(shù):
3
請輸入字符串:
AK,AS,AC
排序前:[AK, AS, AC]
排序后:{AS,AK,AC}
```