Моя хеш-таблица не работает - PullRequest
0 голосов
/ 28 января 2011

Я использую хеш-таблицу для чтения данных из файла и создания кластеров.

Скажем, данные в файле:

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

Вывод похож на:

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

Но мой код не работает. Вот код:

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);
                        }
                    }
                }
            }
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 28 января 2011

Вы работаете с массивом records при вставке в хеш-таблицу (и при чтении из нее) вместо использования переменной foreach record.Кроме того, в конечном итоге вы выполняете итерацию на основе records вместо текущего entry.Key.Вы также объявляете хеш-таблицу в слишком широкой области, в результате чего все строки вставляются в одну и ту же хеш-таблицу, а не по одной на строку.

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();
}

Однако вам следует рассмотреть возможность использования универсального толковый словарь class, и используйте StringBuilder , если вы строите много строк.

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 голосов
/ 28 января 2011

Вы пытаетесь сгруппировать элементы последовательности. LINQ имеет встроенный оператор для этого; используется как group ... by ... into ... или эквивалентный метод .GroupBy(...)

Это означает, что вы можете написать свой код (исключая File I / O и т. Д.) Как:

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
        )
    );
}

Если вы предпочитаете более короткий код, цикл должен быть эквивалентно записан как:

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

обе версии выведут ...

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

Обратите внимание, что вам действительно не следует использовать Hashtable - это просто небезопасная медленная версия Dictionary почти для всех целей. Кроме того, приведенный вами пример вывода включает в себя символы [] и {} - но вы не указали, как или они должны быть включены, поэтому я пропустил их.

Группа LINQ - это не что иное, как последовательность элементов (здесь идентичные строки) с ключом (здесь строка). Вызов GroupBy, таким образом, преобразует последовательность записей в последовательность групп. Однако вы хотите просто объединить эти группы. SelectMany является такой конкатенацией: из последовательности элементов она объединяет «содержимое» каждого элемента в одну большую последовательность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...