如何將一段單詞倒序輸出?把“Hello Java Hello China”變成“China Hello Java Hello”?
看起來好像很簡單,只需要把字符串先分割成單詞,然后加入一個StringBuilder或者StringBuffer中,最后再使用toString方法即可,現(xiàn)在來實現(xiàn)一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/** * @author Frank * @create 2017/11/24 * @description */ public class Test { public static void main(String[] args) { String src = "Hello Java Hello China" ; //需要處理的字符串 String[] arr = src.split( " " ); //按空格分割 int length = arr.length; //計算數(shù)組長度 StringBuilder sb = new StringBuilder(src.length()); //新建一個StringBuilder對象 for ( int i=length- 1 ;i>= 1 ;i--){ sb.append(arr[i]+ " " ); //將字符串依次加入StringBuilder中 } sb.append(arr[ 0 ]); //最后一個單詞不加空格 System.out.println(sb.toString()); //輸出 } } |
China Hello Java Hello
好的,現(xiàn)在就完美的解決了問題。
但事實上,通常并不是全用空格分隔開來的,而是有逗號,句號,引號等,那么這該如何處理呢?
那就只能一個字符一個字符判斷了,用charAt()來判斷字符是否為逗號句號或者引號,空格,如果是的話就知道到了分隔點了,如果不是的話就加入一個臨時的StringBuilder對象,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/** * @author Frank * @create 2017/11/24 * @description */ public class Test2 { public static void main(String[] args) { String src = "Hello Java,Hello China." ; //需要處理的字符串 StringBuilder tmp = new StringBuilder( 20 ); //定義一個StringBuilder對象 StringBuilder goal = new StringBuilder(src.length()); //定義一個StringBuilder對象來存放最終要輸出的信息 char c; //定義一個字符變量 for ( int i=src.length()- 1 ;i>= 0 ;i--){ c = src.charAt(i); //從后往前取字符 if (c == ' ' || c == ',' || c == '.' ){ //判斷是否為分隔字符 goal.append(tmp); //如果是的話就把tmp加入到goal中來 goal.append(c); //在把分隔字符也一起加入 tmp.delete( 0 ,tmp.length()); //清空tmp } else { tmp.insert( 0 ,c); //如果不是分隔字符,說明單詞未完整,繼續(xù)加入tmp中 } } if (!tmp.equals( "" )){ goal.append(tmp); //如果tmp中還有內(nèi)容,在添加到goal中 } System.out.println(goal.toString()); //輸出 } } |
輸出如下:
.China Hello,Java Hello
好像沒什么問題了?! ?/p>
現(xiàn)在難度進一步升級,如果有一個20M的字符串,“Hello_,_China_..._Bye.”(...代表中間省略的部分),單詞之間用空格隔開,現(xiàn)在需要把所有單詞全部顛倒順序,要求效率不能太低。不看這個20M的話,好像沒什么難度,關(guān)鍵就在于這個20M,肯定不能像第一種方式用split分割,那樣的話會創(chuàng)建一個很大的字符串?dāng)?shù)組,浪費很多空間。
所以這里采用第二種方式。
我們先隨機生成一個字符串,然后再使用第二種方式進行處理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/** * @author Frank * @create 2017/11/24 * @description */ public class Test3 { public static void main(String[] args) { long time = 0 ; StringBuilder sb = new StringBuilder(); //先生成一個比較大的字符串 for ( int i= 0 ;i< 10000000 ;i++){ sb.append(i+ " " ); } System.out.println( "字符串長度:" +sb.length()); //開始計算時間 time = System.currentTimeMillis(); StringBuilder tmp = new StringBuilder( 20 ); //定義一個StringBuilder對象存放臨時數(shù)據(jù) StringBuilder goal = new StringBuilder(sb.length()); //定義一個StringBuilder對象來存放最終要輸出的信息 char c; //定義一個字符變量 for ( int i=sb.length()- 1 ;i>= 0 ;i--){ c = sb.charAt(i); //從后往前取字符 if (c == ' ' ){ //判斷是否為分隔字符 goal.append(tmp); //如果是的話就把tmp加入到goal中來 goal.append(c); //在把分隔字符也一起加入 tmp.delete( 0 ,tmp.length()); //清空tmp } else { tmp.insert( 0 ,c); //如果不是分隔字符,說明單詞未完整,繼續(xù)加入tmp中 } } if (!tmp.equals( "" )){ goal.append(tmp); //如果tmp中還有內(nèi)容,在添加到goal中 } System.out.println(System.currentTimeMillis()-time); //輸出運行時間 } } |
輸出如下:
字符串長度:78888890
608
608毫秒,速度還ok,生成字符串還是要花挺多時間的,因為一直要進行內(nèi)存復(fù)制,如果在循環(huán)次數(shù)后再加一個0,就會內(nèi)存不足了。。。。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com.frank.string.test1.Test3.main(Test3.java:14)
至此,本篇問題討論完畢,如果有更好更快的方法,歡迎留言交流討論。
原文鏈接:https://cloud.tencent.com/developer/article/1016618