2012-04-24 85 views
1

我有一個奇怪的要求,我似乎無法得到我的頭。我需要想出一個函數,它會接受一個文本字符串並返回一個與該字符串相對應的數字 - 這樣,當排序時,這些數字將按照與原始字符串相同的順序進行排列。例如,如果我的函數產生該映射:在保留排序的同時將文本轉換爲數字?

"abcd" -> x 
"abdef" -> y 
"xyz" -> z 

則號碼必須使得x < y < z。字符串可以是任意長度,但始終爲非空字符串,並且字符串比較應該不區分大小寫(即"ABC"和​​應該導致相同的數值)。

我的第一個嘗試是將每個字母映射到相應的數字1到26,然後獲得結果數字,例如, a = 1, b = 2, c = 3, ..., z = 26,然後​​會變成1*26^2 + 2*26 + 3,然後我意識到文本字符串可以包含任何語言的任何文本(即完整的unicode),所以這是行不通的。此時我卡住了。在我告訴客戶解散之前有任何其他想法?

P.S.這個奇怪的要求是由於只能通過數字字段進行排序的專有系統的限制。如果任何其他字段類型需要排序,則必須將其轉換爲數字表示 - 然後進行排序。不要問。

+0

你可以在應用程序之外進行排序嗎?即做一個正常的alpha排序,那麼你的映射只是排序列表中的索引? – 2012-04-24 14:25:02

+0

@TonyHopkinson如果數據不是來自應用程序本身,那麼這將是一個選項。 – 2012-04-24 14:30:33

+0

允許使用哪些數字?你可以做任意精度的實數或分數嗎? – templatetypedef 2017-07-19 21:35:07

回答

0

如果你允許任意精度的實數,你可以使這個工作,雖然那種感覺就像作弊。 Unicode字符串是從1,114,112個選項中抽取的字符序列。因此,您可以將它們視爲十進制基數-1,114,113數字:寫入0,然後寫出您的Unicode字符串,並且您有一個以1,114,113爲基數的實數(將每個字符的數值向上移一位,以便缺少的字符具有該值0)。比較其中兩個以1,114,113爲基數的數字,按字典順序對數字進行比較:如果您從左到右掃描數字,他們會在兩者之間的tiebreak中不同意第一個數字。除非您擁有任意精度的實數庫,否則這種方法是完全不可行的。

如果你只有IEEE-734雙打,這種方法將無法工作。看到這種情況的一種方法是,由於double中只有64位(80),所以最多有兩個可能的雙打(或者如果允許long double s,那麼它們可能是2 ),但是無限多不同的字符串這消除了可能性,因爲有太多的字符串要繞過。

不幸的是,如果你有任意精度的整數,你不能做這個工作。字符串的自然排序具有fun屬性,您可以在它們之間找到具有無限多個字符串的字符串對。例如,注意

一個< AB < AAB < AAAB < AAAAB < ... < b

現在,假設你有每個字符串映射到遵守規則的整數的函數你想。這將意味着

F(一)<的F(ab)< F(AAB)< F(甲A甲B)< F(AAAAB)< ...< f(b)

但是,這是不可能的整數 - 你不能有兩個整數f(a)和f(b)與他們之間的無限多個整數。 (f(a)和f(b)之間的整數數目至多爲f(b) - f(a) - 1)。 「

所以看起來答案是」這是可能的,如果你有任意精度的實數,這是不可能的double s,並且這是不可能的任意精度的整數。儘管理論上可行,但我基本上將其標記爲「不會在實踐中發生」。 :-)

+0

這是真的 - 但只有當你堅持整數。在我的問題中,我沒有說「整數」,只是「數字」。然後0.1> 0.01> 0.001> ...> 0 – 2017-07-19 21:32:15

+0

@AleksG哦哎呀,我完全誤讀了。讓我想一想這個... – templatetypedef 2017-07-19 21:33:14

相關問題