Используя StreamReader для подсчета дубликатов? - PullRequest
0 голосов
/ 10 ноября 2011

Я использую Streamreader для чтения файла имен людей, это текстовый файл с именами людей, так что, очевидно, есть дубликаты, и я хочу иметь возможность отображать, сколько людей сейчас имеют одно и то же, так чтонапример:

josh
alex
josh
john
alex

Я хочу сказать,

josh 2
alex 2
john 1

, но я не могу найти легкий способ сделать это, что было бы самым простым способом сделатьэто,

Ответы [ 7 ]

1 голос
/ 10 ноября 2011

Попробуйте это с помощью LINQ.

Сначала прочитайте ваш текстовый файл на List<string>, используя этот код:

const string f = "TextFile1.txt";

// 1
// Declare new List.
List<string> lines = new List<string>();

// 2
// Use using StreamReader for disposing.
using (StreamReader r = new StreamReader(f))
{
    // 3
    // Use while != null pattern for loop
    string line;
    while ((line = r.ReadLine()) != null)
    {
    // 4
    // Insert logic here.
    // ...
    // "line" is a line in the file. Add it to our List.
    lines.Add(line);
    }
}

Вам необходимо определить класс, в котором вы будете иметь имя и, соответственно,the count:

class PersonCount
{
    public string Name { get; set; }
    public int Count { get; set; }
}

И, наконец, используйте это выражение Lambda, чтобы получить желаемое List<string>

List<PersonCount> personCounts = lines.GroupBy(p => p).Select(g => new PersonCount() {Name = g.Key, Count = g.Count()}).ToList();

Теперь переберите список, чтобы получить имена и количество дубликатов.

1 голос
/ 10 ноября 2011

Я бы сказал, использовать Dictionary<string, int>.

Dictionary<string, int> firstNames = new Dictionary<string, int>();

foreach (string name in YourListWithNames)
{
   if (!firstNames.ContainsKey(name))
      firstNames.Add(name, 1);
   else
      firstNames[name] += 1; 
}

Конечно, есть много разных путей к решению, но я бы так и решил. Я еще не запускал этот код, но я думаю, это поможет вам.

0 голосов
/ 10 ноября 2011

попробуйте это автономное решение

StreamReader dr = new StreamReader(@"C:\txt.txt");
string str = dr.ReadToEnd();
string[] p = str.Split(new string[] { Environment.NewLine, " " }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, int> count = new Dictionary<string, int>();
for (int i = 0; i < p.Length; i++)
{
    try
    {
        count[p[i].Trim()] = count[p[i]] + 1;
    }
    catch
    {
        count.Add(p[i], 1);
    }
}
0 голосов
/ 10 ноября 2011
foreach (var keyvalue in File.ReadAllLines(@"C:\....").GroupBy(x => x).Select(x => new { name = x.Key, count = x.Count() }))
{
        Console.WriteLine(keyvalue.name + ": " + keyvalue.count);
}
0 голосов
/ 10 ноября 2011

Конечно, вы также можете сделать что-то подобное (проверка ошибок не включена), используя Linq:

var names = new List<string>(
    File.ReadAllText(pathToFile).Split(
    Environment.NewLine.ToCharArray(),
    StringSplitOptions.RemoveEmptyEntries
));
var namesAndOccurrences =
    from name in names.Distinct()
    select name + " " + names.Count(n => n == name);

foreach (var name in namesAndOccurrences)
    Console.WriteLine(name);

В зависимости от размера файла может быть желательно избавиться от потока; тем не менее, это не означает, что, если файл был достаточно большим для памяти, вы должны использовать ReadLine.

0 голосов
/ 10 ноября 2011

Сохраните все имена в Dictionary<string, int> names.

. Используйте для каждой строки что-то вроде этого:

var theName = reader.ReadLine();
names[theName] += 1;

(следует установить значение, равное единице, если элемент не существует)

0 голосов
/ 10 ноября 2011

Использование HashMap - решение вашей проблемы. Когда вы читаете имя, проверьте, присутствует ли ключ, если это так, обновите его (+1), если нет, добавьте его в свою хэш-карту.

В конце концов, все, что вам нужно сделать, это напечатать пары ключ-значение.

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