2011年5月11日 星期三

[C#] 如何實做 IComparer

Example: (TopCoder, TheLotteryBothDivs)
There are 1,000,000,000 types of lottery tickets. They are numbered "000000000" to "999999999" (they may have leading zeroes). Each type of ticket has an equal probability of being bought by John. You are given a String[] goodSuffixes. If the number written on John's ticket has at least one element of goodSuffixes as a suffix, he will get a prize.

我的想法很簡單: 先把 goodSuffixes String array 做 sorting: string length 短的在前面,長的在後面,如果一樣長的話,按照字母順序排列。

我發現 Array.Sort(goodSuffixes) 不符合我的需求,String.Compare() 只會按照字母順序排序,因此我必須實做自己的 IComparer:
class StringLengthThenAlphabetComparer : IComparer {
public int Compare(object obj_x, object obj_y) {
String x = (String)obj_x;
String y = (String)obj_y;
if (x.Length < y.Length) {
return -1;
}
else if (x.Length > y.Length) {
return 1;
} else {
return x.CompareTo(y);
}
}
}
回傳 -1 表示 x < y, 回傳 1 表示 x > y, 回傳 0 表示 x = y. 有了 StringLengthThenAlphabetComparer class, 我們就可以用它來做自己的排序: Array.Sort(goodSuffixes, new StringLengthThenAlphabetComparer()), 有沒有很簡單?



底下附上其餘的原始碼:
using System;
using System.Collections;
using System.Collections.Generic;

public class TheLotteryBothDivs {
public double find(String[] goodSuffixes) {
Array.Sort(goodSuffixes,
new StringLengthThenAlphabetComparer());

var effective_suffixes = new List<String>();
for (int i = 0; i != goodSuffixes.Length; ++i) {
bool is_new_suffix = true;
foreach (var suffix in effective_suffixes) {
int pos = goodSuffixes[i].Length - suffix.Length;
if (goodSuffixes[i].Substring(pos) == suffix) {
is_new_suffix = false;
break;
}
}
if (is_new_suffix) {
effective_suffixes.Add(goodSuffixes[i]);
}
}

double probability = 0.0;
for (int i = 0; i != effective_suffixes.Count; ++i) {
probability += Math.Pow(0.1,
effective_suffixes[i].Length);
}

return probability;
}
}

class StringLengthThenAlphabetComparer : IComparer { ... }

沒有留言:

張貼留言