2011-01-28 4 views
0

J'utilise une hashtable pour lire les données du fichier et créer des clusters.Mon hashtable ne fonctionne pas

dire que les données dans le fichier est:

umair,i,umair 
sajid,mark,i , k , i 

La sortie est comme:

[{umair,umair},i] 
[sajid,mark,i,i,k] 

Mais mon code ne fonctionne pas. Voici le code:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Collections; 
namespace readstringfromfile 
{ 

    class Program 
    { 
     static void Main() 
     { 
      /* int i = 0; 
      foreach (string line in File.ReadAllLines("newfile.txt")) 
      { 
       string[] parts = line.Split(','); 
       foreach (string part in parts) 
       { 
        Console.WriteLine("{0}:{1}", i,part); 
       } 
       i++; // For demo only 
      }*/ 
      Hashtable hashtable = new Hashtable(); 

      using (StreamReader r = new StreamReader("newfile.txt")) 
      { 
       string line; 
       while ((line = r.ReadLine()) != null) 
       { 
        string[] records = line.Split(','); 
        foreach (string record in records) 
        { 
         if (hashtable[records] == null) 
          hashtable[records] = (int)0; 

         hashtable[records] = (int)hashtable[records] + 1; 
         Console.WriteLine(hashtable.Keys); 

        } 
/////this portion is not working///////////////////////////////////// 

        foreach (DictionaryEntry entry in hashtable) 
        { 
         for (int i = 0; i < (int)hashtable[records]; i++) 
         { 
          Console.WriteLine(entry); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

Vous n'avez pas besoin de convertir le littéral 0 en int. –

+4

En laissant de côté tout le reste, y a-t-il une raison pour que vous utilisiez encore les collections non génériques? –

+0

oki je ne vais pas lancer 0 mais qu'en est-il de cette section? foreach (entrée DictionaryEntry dans hashtable) { pour (int i = 0; i <(int) hashtable [enregistrements]; i ++) { Console.WriteLine (entrée); } } –

Répondre

2

Vous travaillez avec le tableau records lors de l'insertion dans la table de hachage (et lors de la lecture de celui-ci) au lieu d'utiliser la variable foreach record. En outre, dans le dernier look, vous itérez basé sur records au lieu de l'actuel entry.Key. Vous déclarez également la table de hachage dans une portée trop large, entraînant l'insertion de toutes les lignes dans la même table de hachage, au lieu d'une par ligne.

public static void Main() { 
    var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" }; 
    foreach (var line in lines) { 
     var hashtable = new Hashtable(); 
     var records = line.Split(','); 

     foreach (var record in records) { 
      if (hashtable[record] == null) 
       hashtable[record] = 0; 

      hashtable[record] = (Int32)hashtable[record] + 1; 
     } 

     var str = ""; 
     foreach (DictionaryEntry entry in hashtable) { 
      var count = (Int32)hashtable[entry.Key]; 
      for (var i = 0; i < count; i++) { 
       str += entry.Key; 
       if (i < count - 1) 
        str += ","; 
      } 
      str += ","; 
     } 

     // Remove last comma. 
     str = str.TrimEnd(','); 

     Console.WriteLine(str); 
    } 

    Console.ReadLine(); 
} 

Cependant, vous devriez envisager d'utiliser la Dictionary<TKey,TValue> générique de classe, et d'utiliser un StringBuilder si vous construisez beaucoup de chaînes.

public static void Main() { 
    var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" }; 
    foreach (var line in lines) { 
     var dictionary = new Dictionary<String, Int32>(); 
     var records = line.Split(','); 

     foreach (var record in records) { 
      if (!dictionary.ContainsKey(record)) 
       dictionary.Add(record, 1); 
      else 
       dictionary[record]++; 
     } 

     var str = ""; 
     foreach (var entry in dictionary) { 
      for (var i = 0; i < entry.Value; i++) { 
       str += entry.Key; 
       if (i < entry.Value - 1) 
        str += ","; 
      } 
      str += ","; 
     } 

     // Remove last comma. 
     str = str.TrimEnd(','); 

     Console.WriteLine(str); 
    } 

    Console.ReadLine(); 
} 
0

Vous tentez de regrouper des éléments d'une séquence. LINQ a un opérateur intégré pour cela; il est utilisé comme group ... by ... into ... ou la méthode équivalente .GroupBy(...)

Cela signifie que vous pouvez écrire votre code (hors fichier E/S etc.):

var lines = new[] { "umair,i,umair", "sajid,mark,i,k,i" }; 
foreach (var line in lines) { 
    var groupedRecords = 
     from record in line.Split(',') 
     group record by record into recordgroup 
     from record in recordgroup 
     select record; 

    Console.WriteLine(
     string.Join(
      ",", groupedRecords 
     ) 
    ); 
} 

Si vous préférez un code plus court, la boucle est équivalente écrit :

foreach (var line in lines) 
    Console.WriteLine(string.Join(",", 
     line.Split(',').GroupBy(rec=>rec).SelectMany(grp=>grp))); 

les deux versions de sortie ...

umair,umair,i 
sajid,mark,i,i,k 

Notez que vous ne devriez vraiment pas utiliser un Hashtable - c'est juste une version lente de type dangereux de Dictionary pour presque toutes les fins. En outre, l'exemple de sortie que vous mentionnez comprend les caractères [] et {} - mais vous n'avez pas spécifié comment ou s'ils sont censés être inclus, donc je les ai laissés de côté. Un groupe LINQ n'est rien d'autre qu'une séquence d'éléments (ici, des chaînes identiques) avec une clé (ici une chaîne).

L'appel GroupBy transforme ainsi la séquence d'enregistrements en une séquence de groupes. Cependant, vous voulez simplement concaténer ces groupes. SelectMany est une telle concaténation: à partir d'une séquence d'éléments, il concatène le "contenu" de chaque élément dans une grande séquence.