我需要創建一個字典,每個鍵有2個值,它必須以相同的概率返回2個值之一。雙值字典返回任何一個特定的鍵的值
例子:
myDicry
{
key = "A", value1=15, value2=56;
}
int firstCall = myDicry["A"]; // = 15
int secondCall = myDicry["A"]; // = 56
我需要創建一個字典,每個鍵有2個值,它必須以相同的概率返回2個值之一。雙值字典返回任何一個特定的鍵的值
例子:
myDicry
{
key = "A", value1=15, value2=56;
}
int firstCall = myDicry["A"]; // = 15
int secondCall = myDicry["A"]; // = 56
我真的只是實現這個在使用Dictionary<TKey, TValue[]>
內部類。這樣你甚至可以實現這個類型,每個鍵的值都是可變的。
像:
class RandomDictionary<TKey, TValue>
{
Dictionary<TKey, TValue[]> m_dict;
Random m_random;
public RandomDictionary()
{
m_dict = new Dictionary<TKey, TValue[]>();
m_random = new Random();
}
public TValue this[TKey key]
{
get
{
TValue[] values = m_dict[key];
return values[m_random.Next(0, values.Length)];
}
}
public void Define(TKey key, params TValue[] values)
{
m_dict[key] = new TValue[values.Length];
Array.Copy(values, m_dict[key], values.Length);
}
public bool TryGetValue(TKey key, out TValue value)
{
TValue[] values;
if (!m_dict.TryGetValue(key, out values))
{
value = default(TValue);
return false;
}
value = values[m_random.Next(0, values.Length)];
return true;
}
}
使用元組作爲字典值類型。
IDictionary<string, Tuple<int, int>> doubleDictionary = new Dictionary<string, Tuple<int, int>>();
// ...
int secondValue = doubleDictionary["A"].Item2;
你也可以寫一個擴展方法的字典,所以你可以創建這樣的事情:
IDictionary<string, Tuple<int, int>> doubleDictionary = new Dictionary<string, Tuple<int, int>>();
doubleDictionary.GetRandomValueForKey("A");
然後,你可以用任何字典使用。
public static void GetRandomValueForKey(this Dictionary<string, Tuple<int, int>> dict,
string key)
{
... Code to return the value
}
^^這是從我頭頂上寫下來的,所以請原諒,如果這有點不對勁。
有可能編寫一個以這種方式運行的IDictionary<TKey, TValue>
實現,但這不是一個好主意:大多數人會發現集合類的非確定性索引器非常不直觀。
取而代之的是,我建議您將這個值作爲值的責任,而不是字典本身。一種選擇是編寫一種能夠以相同的概率從一組可能性中挑選的自定義類型。例如:
public class UnbiasedRandomPicker<T>
{
private readonly Random _rand = new Random();
private readonly T[] _possibilities;
public UnbiasedRandomPicker(params T[] possibilities)
{
// argument validation omitted
_possibilities = possibilities;
}
public T GetRandomValue()
{
return _possibilities[_rand.Next(_possibilities.Length)];
}
}
然後,您可以使用字典是這樣的:
var dict = new Dictionary<string, UnbiasedRandomPicker<int>>
{
{"A", new UnbiasedRandomPicker<int>(15, 56)},
{"B", new UnbiasedRandomPicker<int>(25, 13)}
};
int randomValueFromA = dict["A"].GetRandomValue();
謝謝,我認爲這對我來說是更好的解決方案! – ZAA 2010-09-26 19:08:30
這下面的代碼就能解決問題的字典部分,使隨機化定製,使您可以應用水平,使僞隨機性,適合您的需求。 (或者乾脆硬編碼,而不是使用函子)
public class DoubleDictionary<K, T> : IEnumerable<KeyValuePair<K, T>>
{
private readonly Dictionary<K, Tuple<T, T>> _dictionary = new Dictionary<K, Tuple<T, T>>();
private readonly Func<bool> _getFirst;
public DoubleDictionary(Func<bool> GetFirst) {
_getFirst = GetFirst;
}
public void Add(K Key, Tuple<T, T> Value) {
_dictionary.Add(Key, Value);
}
public T this[K index] {
get {
Tuple<T, T> pair = _dictionary[index];
return GetValue(pair);
}
}
private T GetValue(Tuple<T, T> Pair) {
return _getFirst() ? Pair.Item1 : Pair.Item2;
}
public IEnumerable<K> Keys {
get {
return _dictionary.Keys;
}
}
public IEnumerable<T> Values {
get {
foreach (var pair in _dictionary.Values) {
yield return GetValue(pair);
}
}
}
IEnumerator<KeyValuePair<K, T>> IEnumerable<KeyValuePair<K, T>>.GetEnumerator() {
foreach (var pair in _dictionary) {
yield return new KeyValuePair<K, T>(pair.Key, GetValue(pair.Value));
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return ((IEnumerable<KeyValuePair<K, T>>)this).GetEnumerator();
}
}
有趣的問題..你能一點就可以了擴大? – 2010-09-26 17:55:01
當查找某個鍵時,它是否總是先返回第一個值,然後是第二個還是應該是隨機的(這不違反概率要求)? – NullUserException 2010-09-26 17:56:37