【Java】單詞倒序輸出


  如何將一段單詞倒序輸出?把“Hello Java Hello China”變成“China Hello Java Hello”?

  看起來好像很簡單,只需要把字符串先分割成單詞,然后加入一個StringBuilder或者StringBuffer中,最后再使用toString方法即可,現在來實現一下:

/**
 * @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;//計算數組長度
        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());//輸出
    }
}

  因為是使用單線程,所以用StringBuilder的效率會高於StringBuffer,輸出如下:

China Hello Java Hello

  好的,現在就完美的解決了問題。

  但事實上,通常並不是全用空格分隔開來的,而是有逗號,句號,引號等,那么這該如何處理呢?

  那就只能一個字符一個字符判斷了,用charAt()來判斷字符是否為逗號句號或者引號,空格,如果是的話就知道到了分隔點了,如果不是的話就加入一個臨時的StringBuilder對象,代碼如下:

/**
 * @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);//如果不是分隔字符,說明單詞未完整,繼續加入tmp中
            }
        }
        if (!tmp.equals("")){
            goal.append(tmp);//如果tmp中還有內容,在添加到goal中
        }
        System.out.println(goal.toString());//輸出
    }
}

  輸出如下:

.China Hello,Java Hello

  好像沒什么問題了。  

  現在難度進一步升級,如果有一個20M的字符串,“Hello_,_China_..._Bye.”(...代表中間省略的部分),單詞之間用空格隔開,現在需要把所有單詞全部顛倒順序,要求效率不能太低。不看這個20M的話,好像沒什么難度,關鍵就在於這個20M,肯定不能像第一種方式用split分割,那樣的話會創建一個很大的字符串數組,浪費很多空間。

  所以這里采用第二種方式。

  我們先隨機生成一個字符串,然后再使用第二種方式進行處理:

/**
 * @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對象存放臨時數據
        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);//如果不是分隔字符,說明單詞未完整,繼續加入tmp中
            }
        }
        if (!tmp.equals("")){
            goal.append(tmp);//如果tmp中還有內容,在添加到goal中
        }
        System.out.println(System.currentTimeMillis()-time);//輸出運行時間
    }
}

  輸出如下:

字符串長度:78888890
608

  608毫秒,速度還ok,生成字符串還是要花挺多時間的,因為一直要進行內存復制,如果在循環次數后再加一個0,就會內存不足了。。。。

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)

  至此,本篇問題討論完畢,如果有更好更快的方法,歡迎留言交流討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM