當前位置:首頁 » 操作系統 » 相似混排演算法

相似混排演算法

發布時間: 2023-03-12 01:20:13

Ⅰ android聯系人排序用了什麼演算法

今天用了整整一下午去搗鼓這塊,為什麼模擬器上可以按拼音排序,中英文混排,及按字母搜索聯系人,但到了開發板(平台是根據android2.2改過的)上就怎麼不行了呢,雖然現在還沒有解決,但也是知道了問題所在,離解決之路也就不遠了
好吧,現在就解釋下android2.2是怎麼按拼音排序的。

首先我們來看下android.2自帶通訊錄的資料庫文件contacts2.db的raw_contacts表。用sqlitedbviewer工具打開後可以看到有這么一個欄位:sort_key(sort_key_alt與之相似,只不過是英文環境下有個按given name還是first name排序的問題)。

正常狀況下,我們新建一個聯系人的話,如果是英文,則sort_key與display_name欄位顯示相同,如果輸入姓名是中文,如「你好」,sort_key則會顯示「ni 你 hao 好」,這樣開發者既可以根據此欄位按拼音排序,中英文混排,以及按拼音搜索聯系人拉。

現在就說下,android是如何將中文名的聯系人轉化為拼音存到sort_key裡面的:

view plain to clipboardprint?
if (displayNameStyle == FullNameStyle.CHINESE ||
displayNameStyle == FullNameStyle.CJK) {
sortKeyPrimary = sortKeyAlternative =
ContactLocaleUtils.getIntanc).getSortKe(displayNamePrimary, displayNameStyle);}
if (displayNameStyle == FullNameStyle.CHINESE ||
displayNameStyle == FullNameStyle.CJK) { sortKeyPrimary =
sortKeyAlternative =
ContactLocaleUtils.getIntanc).getSortKe(displayNamePrimary,
displayNameStyle);}
這段代碼是運行在contactsprovi2.java的updateRawContactDisplayName()方法裡面,這段代碼我們用到了ContactLocaleUtils.java這個類,所以我們進入它以後最顯眼的就是ChineseContactUtils這個ContactLocaleUtils的子類,它重寫了ContactLocaleUtils的getSortKey()方法,如下:

view plain to clipboardprint?
public String getSortKey(String displayName) {

ArrayList tokens = HanziToPinyin.getInstance().get(displayName);

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

StringBuilder sb = new StringBuilder();

for (Token token : tokens) {

// Put Chinese character's pinyin, then proceed with the

// character itself.

if (Token.PINYIN == token.type) {

if (sb.length() > 0) {

sb.append(' ');

}

sb.append(token.target);

sb.append(' ');

sb.append(token.source);

} else {

if (sb.length() > 0) {

sb.append(' ');

}

sb.append(token.source);

}

}

return sb.toString();

}

return super.getSortKey(displayName);

}
public
String getSortKey(String displayName) {
ArrayList tokens =
HanziToPinyin.getInstance().get(displayName); if (tokens !=
null && tokens.size() > 0) { StringBuilder
sb = new StringBuilder(); for (Token token : tokens) {
// Put Chinese character's pinyin, then proceed
with the // character itself.
if (Token.PINYIN == token.type) { if
(sb.length() > 0) { sb.append(' ');
} sb.append(token.target);
sb.append(' ');
sb.append(token.source); } else {
if (sb.length() > 0) {
sb.append(' '); }
sb.append(token.source); } }
return sb.toString(); } return
super.getSortKey(displayName); }
首先我們看 ArrayList tokens = HanziToPinyin.getInstance().get(displayName);,因為其他的無非就是插入格式的問題,我們暫時不用看。

android如何將漢字轉為拼音的?這就用到了HanziToPinyin這個類,好吧,我們先看下HanziToPinyin的getInstance()方法:

view plain to clipboardprint?
public static HanziToPinyin getInstance() {

synchronized(HanziToPinyin.class) {

if (sInstance != null) {

return sInstance;

}

// Check if zh_CN collation data is available

final Locale locale[] = Collator.getAvailableLocales();

for (int i = 0; i < locale.length; i++) {

if (locale[i].equals(Locale.CHINA)) {

sInstance = new HanziToPinyin(true);

return sInstance;

}

}

Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");

sInstance = new HanziToPinyin(false);

return sInstance;

}

}
public static HanziToPinyin getInstance() {
synchronized(HanziToPinyin.class) { if (sInstance != null) {
return sInstance; } // Check
if zh_CN collation data is available final Locale locale[]
= Collator.getAvailableLocales(); for (int i = 0; i <
locale.length; i++) { if
(locale[i].equals(Locale.CHINA)) { sInstance = new
HanziToPinyin(true); return sInstance;
} } Log.w(TAG, "There is no Chinese
collator, HanziToPinyin is disabled"); sInstance = new
HanziToPinyin(false); return sInstance; } }
現在說下我的開發板為什麼不能轉拼音;就是因為final Locale locale[] = Collator.getAvailableLocales()的Locale沒有一項equals(Locale.CHINA),所以到時候解決了這項,聯系人的按拼音排序也就解決了,如果大家不想用系統自帶的,自己可以下載個pinyin4j.jar包自己實現吧。

好吧,繼續:

看方法名也只到,這個方法返回一個HanziToPinyin實例,我仔細研究了HanziToPinyin的構造方法,無論純如的布爾值是false還是true都不影響,返回的都一樣,只不過這個方法的Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");可以提示是否支持漢字轉拼音,如果不能,android就會將displayname原封不動的插入sort_key裡面,如果能,就是剛才我說的 如「你好」,sort_key則會顯示「ni 你 hao 好」,這種形式,具體的如何轉拼音就是get()方法拉,直接插代碼:

view plain to clipboardprint?
public ArrayList get(final String input) {
ArrayList tokens = new ArrayList();
if (!mHasChinaCollator || TextUtils.isEmpty(input)) {
// return empty tokens.
return tokens;
}
final int inputLength = input.length();
final StringBuilder sb = new StringBuilder();
int tokenType = Token.LATIN;
// Go through the input, create a new token when
// a. Token type changed
// b. Get the Pinyin of current charater.
// c. current character is space.
for (int i = 0; i < inputLength; i++) {
final char character = input.charAt(i);
if (character == ' ') {
if (sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
} else if (character < 256) {
if (tokenType != Token.LATIN && sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
tokenType = Token.LATIN;
sb.append(character);
} else if (character < FIRST_UNIHAN) {
if (tokenType != Token.UNKNOWN && sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
tokenType = Token.UNKNOWN;
sb.append(character);
} else {
Token t = getToken(character);
if (t.type == Token.PINYIN) {
if (sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
tokens.add(t);
tokenType = Token.PINYIN;
} else {
if (tokenType != t.type && sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
tokenType = t.type;
sb.append(character);
}
}
}
if (sb.length() > 0) {
addToken(sb, tokens, tokenType);
}
return tokens;
}

熱點內容
sql獲取小時 發布:2025-08-22 22:10:58 瀏覽:670
大同網通dns伺服器地址 發布:2025-08-22 22:02:22 瀏覽:591
javarsa的是 發布:2025-08-22 21:51:58 瀏覽:712
ftp解析域名解析 發布:2025-08-22 21:48:30 瀏覽:538
與佛論道加密 發布:2025-08-22 21:41:42 瀏覽:345
cs架構語言 發布:2025-08-22 21:34:35 瀏覽:883
安防監控存儲 發布:2025-08-22 21:20:38 瀏覽:800
java高級培訓哪裡好 發布:2025-08-22 21:16:56 瀏覽:170
套杯演算法 發布:2025-08-22 21:15:20 瀏覽:253
unrealengine源碼 發布:2025-08-22 21:02:13 瀏覽:96