2009-03-06 18 views
2

Renklerin (anahtarları olan) ve anahtarın renk sayısını tuttuğum bir HashTable'ım var.Bir HashTable'daki değeri nasıl artırabilirim?

HashTable zaten rengi içerdiğinde anahtarı nasıl artırmanız gerektiğini anlamaya çalışıyorum.

Hashtable htColors = new Hashtable(); 

if (htColors.Contains(color)) 
{ 
    // Want to increase the "value" of the key here.  
} 
else 
{ 
    htColors.Add(color, 1); //Found color for first time 
} 

cevap

4

yalnızca 1) güvenli yazıp 2 çünkü

IMHO, sözlük yaklaşım çok daha iyidir yorumlarına aşağıdaki

if (htColors.Contains(color)) 
{ 
    int old = (int)htColors[color]; 
    htColor[color] = old + 1; 
} 

DÜZENLEME Yanıtını deneyin: İşte bir kod parçacığı İşte) Bu çözümde yer alan boksu ortadan kaldırır.

hat şu anahtarı, ben bilgiçlik olmak için bu post ediyorum

htColor[color] = (int)htColor[color] + 1; 
+0

Ok, çözüm çalışıyor gibi gözüküyor. Sözlük alternatifi hakkında ne düşünüyorsunuz? Ayrıca, ne yapsaydım (int) htColors [color] + 1, anahtar veya değeri değiştirirse? – Xaisoft

+0

HashTable ile ilgili yardım için teşekkürler. Sonuçta bir Sözlük ile gideceğim gibi görünüyor. – Xaisoft

+0

Burada yanlış olduğumda birisi beni düzeltebilir, ancak otomatik kutulama/kutulama işleminin, yığına taşınan herhangi bir değer türü için (hatta bu durumda) yazılı bir sözlükte (Sözlük ) ints için gerçekleştiğine inanıyorum. Sözlük ne yaparsa dökümden dağılır. –

4

sadece değerini etkilemez olmak olmak. Sözlükle ara yüzlemeyi sevmiyorum çünkü bu çok yaygın erişim türüne bir maliyet var - en yaygın durumunuz zaten var olan bir öğeye dokunuyorsa, 3 kez değerinizi almalı ve bulmalısınız. Bana inanma Bu mesajı alır -

IL koymak
static void AddInc(Dictionary<string, int> dict, string s) 
{ 
    if (dict.ContainsKey(s)) 
    { 
     dict[s]++; 
    } 
    else 
    { 
     dict.Add(s, 1); 
    } 
} 

:

ContainsKey, Get_Item ve set_item çağrıları
L_0000: nop 
L_0001: ldarg.0 
L_0002: ldarg.1 
L_0003: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::ContainsKey(!0) 
L_0008: ldc.i4.0 
L_0009: ceq 
L_000b: stloc.0 
L_000c: ldloc.0 
L_000d: brtrue.s L_0028 
L_000f: nop 
L_0010: ldarg.0 
L_0011: dup 
L_0012: stloc.1 
L_0013: ldarg.1 
L_0014: dup 
L_0015: stloc.2 
L_0016: ldloc.1 
L_0017: ldloc.2 
L_0018: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::get_Item(!0) 
L_001d: ldc.i4.1 
L_001e: add 
L_001f: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::set_Item(!0, !1) 
L_0024: nop 
L_0025: nop 
L_0026: br.s L_0033 
L_0028: nop 
L_0029: ldarg.0 
L_002a: ldarg.1 
L_002b: ldc.i4.1 
L_002c: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1) 
L_0031: nop 
L_0032: nop 
L_0033: ret 

, hepsi karma ve bakmak arasında burada DK çözümünü yazdı.

Int içeren bir sınıf kullanan güzel bir şey yazdım ve sınıf onu yan etki yapmanıza izin veriyor (struct struct semantics'i nedeniyle aynı cezaya çarpmadan gerçekten bir struct kullanamazsınız).

class IntegerHolder { 
    public IntegerHolder(int x) { i = x; } 
    public int i; 
} 
static void AddInc2(Dictionary<string, IntegerHolder> dict, string s) 
{ 
    IntegerHolder holder = dict[s]; 
    if (holder != null) 
    { 
     holder.i++; 
    } 
    else 
    { 
     dict.Add(s, new IntegerHolder(1)); 
    } 
} 

Bu size aşağıdaki IL verir: Get_Item kez çağırır

L_0000: nop 
L_0001: ldarg.0 
L_0002: ldarg.1 
L_0003: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class AddableDictionary.IntegerHolder>::get_Item(!0) 
L_0008: stloc.0 
L_0009: ldloc.0 
L_000a: ldnull 
L_000b: ceq 
L_000d: stloc.1 
L_000e: ldloc.1 
L_000f: brtrue.s L_0023 
L_0011: nop 
L_0012: ldloc.0 
L_0013: dup 
L_0014: ldfld int32 AddableDictionary.IntegerHolder::i 
L_0019: ldc.i4.1 
L_001a: add 
L_001b: stfld int32 AddableDictionary.IntegerHolder::i 
L_0020: nop 
L_0021: br.s L_0033 
L_0023: nop 
L_0024: ldarg.0 
L_0025: ldarg.1 
L_0026: ldc.i4.1 
L_0027: newobj instance void AddableDictionary.IntegerHolder::.ctor(int32) 
L_002c: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, class AddableDictionary.IntegerHolder>::Add(!0, !1) 
L_0031: nop 
L_0032: nop 
L_0033: ret 

- bir nesne mevcut durumunda hiçbir ek karma yoktur. Biraz alçakgönüllüyüm ve yöntemin mülkiyete erişimini engellemek için alanı kamusal hale getirdim. Yerinde olsaydım

, ben kendi sınıfının içine bu genel işlevselliğini sarın ve genel görünümden IntegerHolder sınıfını saklasın - burada sınırlı bir sürümü:

public class CountableItem<T> 
{ 
    private class IntegerHolder 
    { 
     public int i; 
     public IntegerHolder() { i = 1; } 
    } 
    Dictionary<T, IntegerHolder> dict = new Dictionary<T, IntegerHolder>(); 

    public void Add(T key) 
    { 
     IntegerHolder val = dict[key]; 
     if (val != null) 
      val.i++; 
     else 
      dict.Add(key, new IntegerHolder()); 
    } 

    public void Clear() 
    { 
     dict.Clear(); 
    } 

    public int Count(T key) 
    { 
     IntegerHolder val = dict[key]; 
     if (val != null) 
      return val.i; 
     return 0; 
    } 

    // TODO - write the IEnumerable accessor. 
} 
+0

+1.Bu, sözlük kovası için bir değer türü kullanıldığında/neden kötü bir fikir olabileceğini gösterir. –

İlgili konular