我正在研究預測性文本解決方案,並根據特定字符串的輸入從Trie中檢索所有單詞,即「at」將提供所有以「at」作爲前綴。我現在面臨的問題是,我們也應該按下移動電話上的這兩個按鈕,即按鈕2和按鈕8,以返回所有其他可能性,這也可以使用「au,av,bt,bu ,bv,ct,cu,cv「(其中大多數不會有任何實際的字詞)從多個字符生成排列
任何人都可以提出一個解決方案,我會如何去做這個計算不同的排列? (目前,我提示用戶輸入前綴(不使用GUI現在)
我正在研究預測性文本解決方案,並根據特定字符串的輸入從Trie中檢索所有單詞,即「at」將提供所有以「at」作爲前綴。我現在面臨的問題是,我們也應該按下移動電話上的這兩個按鈕,即按鈕2和按鈕8,以返回所有其他可能性,這也可以使用「au,av,bt,bu ,bv,ct,cu,cv「(其中大多數不會有任何實際的字詞)從多個字符生成排列
任何人都可以提出一個解決方案,我會如何去做這個計算不同的排列? (目前,我提示用戶輸入前綴(不使用GUI現在)
歡迎像遞歸性和組合爆炸:)
由於組合爆炸的概念,你必須是「智能「關於它:如果用戶想要輸入一個合法的20個字母的單詞,那麼解決方案」掛「試圖愚蠢地成千上萬的可能性是不可接受的。
因此,只有當trie至少有一個條目用於前綴時,您才應該進行遞歸處理。
以下是一種生成所有前綴的方法,只有匹配時才進行遞歸。
在這個例子中,我僞造了一個總是說有條目的樹。我在五分鐘內做到了這一點,所以它肯定可以美化/簡化。
這樣的解決方案的優點是,如果用戶按下一個,兩個,三個,四個或'n'鍵,而無需更改您的代碼,它的工作原理。
請注意,您可能不想添加全部當字符太多時,以'x'字母開始的單詞。您需要找到最適合您需求的策略(等待更多按鍵來減少候選人或添加候選人最常見的匹配項等)。
private void append(final String s, final char[][] chars, final Set<String> candidates) {
if (s.length() >= 2 && doesTrieContainAnyWordStartingWith(s)) {
candidates.add(s + "..."); // TODO: here add all words starting with 's' instead of adding 's'
}
if (doesTrieContainAnyWordStartingWith(s) && chars.length > 0) {
final char[][] next = new char[chars.length-1][];
for (int i = 1; i < chars.length; i++) {
next[i-1] = chars[i];
}
// our three recursive calls, one for each possible letter
// (you'll want to adapt for a 'real' keyboard, where some keys may only correspond to two letters)
append(s + chars[0][0], next, candidates);
append(s + chars[0][1], next, candidates);
append(s + chars[0][2], next, candidates);
} else {
// we do nothing, it's our recursive termination condition and
// we are sure to hit it seen that we're decreasing our 'chars'
// length at every pass
}
}
private boolean doesTrieContainAnyWordStartingWith(final String s) {
// You obviously have to change this
return true;
}
請注意遞歸調用(僅當存在匹配的前綴時)。
這裏是你如何可以把它稱爲:我僞造用戶按壓「1」,則「2」,然後「3」(我在字符炭[] []數組我創建僞造此):
public void testFindWords() {
// Imagine the user pressed 1 then 2 then 3
final char[][] chars = {
{'a','b','c'},
{'d','e','f'},
{'g','h','i'},
};
final Set<String> set = new HashSet<String>();
append("", chars, set); // We enter our recursive method
for (final String s : set) {
System.out.println("" + s);
}
System.out.println("Set size: " + set.size());
}
該示例將創建一個包含36個匹配的集合,因爲我「僞造」每個前綴都是合法的,並且每個前綴都會導致恰好一個單詞(並且,只有當它由至少兩個字母組成時才添加「單詞」 )。因此3 * 3 * 3 + 3 * 3,這給出了36.
您可以嘗試一下代碼,它完全正常工作,但您必須對其進行調整。
在我的假例子(用戶按1,2,然後3),它創建了一個:
cdh...
afi...
adi...
beg...
cf...
adh...
cd...
afg...
adg...
bei...
ceg...
bfi...
cdg...
beh...
aeg...
ce...
aeh...
afh...
bdg...
bdi...
cfh...
ad...
cdi...
ceh...
bfh...
aei...
cfi...
be...
af...
bdh...
bf...
cfg...
bfg...
cei...
ae...
bd...
Set size: 36
歡迎真正的編碼:)
@ adam08:現在當然如果你不熟悉遞歸,你可能會使用「簡單」(實際上要長得多,但如果你對遞歸不滿意,「更簡單」),你只需要處理「最多n個字母」,其中n是8,然後繼續寫e 8個嵌套循環。 – SyntaxT3rr0r 2010-05-04 15:21:31
感謝百萬WizardOfOdds ....我會堅持它到我的代碼,看看我能否得到它的工作。然後去嘗試去了解它:-) 我還在談論,你寫了五分鐘 – user330572 2010-05-04 15:34:49
@ adam08:它只需要練習(我輸入很快)...有很多非常精彩的算法和技巧,我只是碰巧熟悉遞歸。我曾經在「TopCoder」的第一部分參與競爭(甚至在1小時15分鐘內解決了三個難題,現在*很難:) – SyntaxT3rr0r 2010-05-04 16:34:19
你說得對,檢索是沒有問題的,它會檢索任意組合,只是從輸入中獲得可能的組合,然後發送到trie並輸出單詞列表 – user330572 2010-05-04 14:51:43