日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 英文字符串排序_英文字符串排序算法

發布時間:2023/12/1 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 英文字符串排序_英文字符串排序算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

編程工作偶爾會遇到一些不常見問題需要處理,學編程處理問題也難免需要熟悉一些算法

以前學習的時候就遇到過一個看似簡單的排序算法問題,當時的解決辦法是我沒有用過的,在此記錄一下''

問題 - 英文字符串排序

如下幾個英文單詞或者字母

apple,car, a,family,sky,application,app,baby,back,background,bad,bbbbb,bee,cafe ,cake,care

排序后的結果是

/**

a

app

apple

application

baby

back

background

bad

bbbbb

bee

cafe

cake

car

care

family

sky

**/

規則邏輯

通過結果可知

a 與 app a排前面 (開頭字母相同,短的排在前面)

back 與 backgroud back排在前面 (開頭字母相同,短的排在前面)

application 與 baby application 排在前面(開頭字母不同,從a-z依次排序)

設計實現

a=1 b=2 c=3 d=4 e=5 f=6 g=7 h=8 i=9 j=10

k=11 l=12 m=13 n=14 o=15 p=16 q=17 r=18 s=19 t=20

u=21 v=22 w=23 x=24 y=25 z=26

a代表的是 1

b代表的是 2

z 代表 26 就可以實現初步排序

但是 bbbbb與 bee 兩個單詞要實現 bee 在前,邏輯該怎么寫呢

起初想法是,字母依次比較,bbbbb 與 bee比較的第二個字母的時候, b 與 e 分別代表 2 和 5 所以bbbbb排前面,問題是一個一個字母比較看起來很麻煩,10個單詞,10個都要比較

有以下解決方案,都有用到遞歸

方法一 通過單詞獲取權重進行排序(當初使用方法)

?bbbbb => b =2 b=2 b=2 b=2 b=2

?bee => b = 2 e =5 e = 5

權重數 Px

Px(bbbbb) = 2 + 2 * 27^-1 + 2 * 27^-2 + 2 * 27^-3 + 2 * 27^-4 = 2.079

Px(bee) = 2 + 5 * 27^-1 + 5 * 27^-2 = 2.192

通過這個計算方式可以獲得權重值

Px(bbbbb) < Px(bee)

所以 bbbbb 排在 baby 前面

權重數27

這里為什么是 27 不是26 是考慮到一種情況,會導致排序失敗

比如 az 與 b比較

Px(az) = 1 + 26 * 26^-1 = 2

Px(b) = 2

Px(az) = Px(b) 顯然是錯的 將26 改為 27 就可避免這個錯誤

優點

不管是任何單詞,一千個也好,得出每個字符串對應的權重值,就能做到排序

代碼實現

更新與2020-01-09,后面做了優化,區分字母大小寫,權重改為53

public static void main(String[] args) {

String[] noP = {"Baby","apple", "car", "A", "family", "B","b", "Sky", "application", "app", "baby", "back", "background",

"bad", "bbbbb", "bee", "cafe", "cake", "care" };

String[] nopTop = sortByWeights(noP);

for (String string : nopTop) {

System.out.print(string + ",");

}

System.out.println();

System.out.println("----------------------");

for (String string : nopTop) {

System.out.println("weights:\t" + getStrWeights(string,0) + "\t" + string);

}

}

/**

* for 權重排序

*

*/

public static String[] sortByWeights(String[] disorder) {

double[] weightsArr = new double[disorder.length];

HashMap recordMap = new HashMap<>();

// 計算每個字符串的權重值

for (int i=0; i

weightsArr[i] = getStrWeights(disorder[i],0);

recordMap.put(weightsArr[i],i);//保存權重值對應的字符串所在數組位置

}

// 將獲取的權重值排序

Arrays.sort(weightsArr);

String[] sorderStr = new String[disorder.length];

int orderIndex = 0;

for (int i=0; i

// 拿出排好序的索引

orderIndex = recordMap.get(weightsArr[i]);

sorderStr[i] = disorder[orderIndex];

}

return sorderStr;

}

// 權重數值

private final static double weightsNum = 53;

/**

* for 計算字符串的權重值算法

* @param deep

* @param str

* @return weights

*/

public static double getStrWeights(String str,int deep) {

int c = str.charAt(deep);

boolean isUppercase = true;

if(c >= 97) {

c = c - 32;

isUppercase = false;

}

c = c - 64; // A,a -> 1; B,b -> 2

int molecular = c*2;

if(isUppercase) molecular--; //if(B) -> 3;if(b) -> 4; for end [Baby,baby]

// 這里考慮了大小寫 如果字母是B 權重=3/53 小寫b 權重=4/53 使小大小寫也能排序

double weights = molecular/ (Math.pow(weightsNum, deep));

return ++deep >= str.length() ? weights : weights + getStrWeights(str,deep); //遞歸到字符串末尾

}

運行main方法,控制臺輸出結果

A,app,apple,application,B,Baby,b,baby,back,background,bad,bbbbb,bee,cafe,cake,car,care,family,Sky,

----------------------

weights:1.0A

weights:2.6151655393378426app

weights:2.615328013590046apple

weights:2.615329041941876application

weights:3.0B

weights:3.0394956910738395Baby

weights:4.0b

weights:4.0394956910738395baby

weights:4.040019613506452back

weights:4.0400214752701284background

weights:4.0405838376646495bad

weights:4.076923067174232bbbbb

weights:4.192239231043076bee

weights:6.042075001511314cafe

weights:6.045634987271372cake

weights:6.050551797792809car

weights:6.050618967335452care

weights:12.047115878410484family

weights:37.43289426842293Sky

缺點

考慮到前一種算法的計算,如果單詞長度超過20或者更長,會導致計算量很大的問題

如果有一百個單詞,比較計算很有必要,如果只有兩個單詞

bbbbbbbbbbbbbbbb 與 bar 比較 用權重法不合適,因為只有兩個單詞沒比較計算這么多,就能得出排序結論,下面就講講另一種排序算法

方法二 逐個字母計算排序

下面說一下新思路,逐個比較

apple,car, a,family,sky,application,app,baby,back,background,bad,bbbbb,bee,cafe ,cake,care

還是上面的單詞

首先獲取每個字符串的第一個字母

第一個字母為 a 的 全部取出

apple a application app

比較他們的第二個字母 a 沒有第二個字母,自然排在最前面,依次類推,使用遞歸即可完成排序

因為臨時想到的一種排序方法,用到了TreeSet HashMap ArrayList 工具類,感覺還可以后期優化。

代碼如下:

package javabasis.algorithm;

import java.util.ArrayList;

import java.util.List;

import java.util.Set;

import java.util.TreeMap;

/**

* 字段排序算法

*

* @author Narule

*

*/

public class StringAlgorithm {

/**

* 逐個字母比較排序

*

* @param disorder

* @return orderly

*/

public static String[] nopTop(String[] disorder) {

int index = 0;

int end = disorder.length;

String[] orderly = new String[end]; // 新建排序后的數組

TreeMap> treeMap = new TreeMap<>(); // 排序工具類,key是按照大小排序的

List list = null;

// 收集字符串首字母信息

for (String str : disorder) {

char cTag = str.charAt(0);

list = treeMap.get(cTag);

if (list == null) {

list = new ArrayList<>(1);

}

list.add(str);

treeMap.put(cTag, list);

}

// 通過收集的首字母信息給字符串排序

Set keySet = treeMap.keySet();

for (char cTag : keySet) {

list = treeMap.get(cTag);

if (list != null && list.size() > 0) {

if (list.size() < 2) { // 如果只有一個字符串,不需要遞歸

for (String string : list) {

orderly[index] = string;

index++;

}

} else { // 如果有兩個以上字符串,開頭字母相同,可能需要遞歸排序

ArrayList arrayList = new ArrayList<>(0);

for (String string : list) {

if (string.length() > 1) { // 字符串長度大于2的,需要添加到list,準備下一次遞歸排序用到

arrayList.add(string.substring(1));

} else {

orderly[index] = string;

index++;

}

}

if (arrayList.size() > 1) {

String[] array = new String[arrayList.size()];

int i = 0;

for (String string : arrayList) {

array[i] = string;

i++;

}

array = nopTop(array); // 還需要遞歸排序 back background -> ack ackground

for (String string : array) {

orderly[index] = cTag + string;

index++;

}

} else if (arrayList.size() == 1) {

orderly[index] = cTag + arrayList.get(0);

index++;

}

}

}

}

treeMap.clear();

return orderly; // 排序后的字符串數組

}

public static void main(String[] args) {

String[] noP = { "apple", "car", "a", "family", "sky", "application", "app", "baby", "back", "background",

"bad", "bbbbb", "bee", "cafe", "cake", "care" };

String[] nopTop = nopTop(noP);

for (String string : nopTop) {

System.out.println(string);

}

}

}

此方法用到TreeMap,這是Java工具類,自帶排序效果,對此有疑問可以查看java源代碼,或介紹文檔

優點

沒有很大的計算量

缺點

使用TreeMap ArrayList 對象,遞歸過多也會出現內存損耗過大或者溢出的情況

未完,后期待優化

總結

以上是生活随笔為你收集整理的java 英文字符串排序_英文字符串排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。