Program C# do usuwania duplikatów

Program C# do usuwania duplikatów

Napiszemy teraz program c#, aby wydrukować niepowtarzalne imiona, usuwając zduplikowane wpisy.

Na przykład w poniższym łańcuchu wejściowym imiona Marcin i Adam są powtarzane dwukrotnie. Program c#, który napiszemy, powinien usunąć duplikaty i zwrócić ciąg, taki jak pokazano w Stringu wyjściowym. Łańcuch wyjściowy zawiera każde imię zapisane tylko raz, eliminując duplikaty.

String wejściowy = „Marcin;Tomek;Adam;Iza;Marcin;Piotr;Adam;”
String wyjściowy = „Marcin;Tomek;Adam;Iza;Piotr;”

Program w języku C# do usunięcia duplikatów z ciągu imion może wyglądać następująco:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string inputString = "Marcin;Tomek;Adam;Iza;Marcin;Piotr;Adam;";
        string[] names = inputString.Split(';');
        HashSet<string> uniqueNames = new HashSet<string>();

        foreach (var name in names)
        {
            if (!string.IsNullOrWhiteSpace(name))
            {
                uniqueNames.Add(name);
            }
        }

        string outputString = string.Join(";", uniqueNames) + ";";
        Console.WriteLine(outputString);
    }
}

W tym programie:

  1. Splitowanie Stringów: Łańcuch wejściowy jest dzielony na poszczególne imiona. Metoda Split w C# jest używana do dzielenia stringów na podstawie separatorów. W tym przypadku używamy średnika (;) jako separatora, aby podzielić łańcuch wejściowy na poszczególne imiona. Wynikiem tej operacji jest tablica stringów, gdzie każdy element to pojedyncze imię.
  2. HashSet: HashSet<T> to kolekcja dostępna w .NET, która przechowuje unikalne elementy. Główną cechą tej kolekcji jest to, że automatycznie ignoruje duplikaty – jeśli próbujesz dodać element, który już istnieje w HashSet, operacja dodawania zignoruje ten element. Dzięki temu jest to idealne narzędzie do usuwania duplikatów z listy. Dodatkowo, operacje sprawdzania obecności elementu (czyli czy element już istnieje w zbiorze) są bardzo szybkie w HashSet.
  3. Sprawdzanie Pustych Stringów: Używam string.IsNullOrWhiteSpace przed dodaniem imienia do HashSet, aby upewnić się, że puste stringi (wynikające np. z dodatkowych średników na końcu łańcucha wejściowego) nie są uwzględniane.
  4. Łączenie Stringów: Na końcu, po uzyskaniu zbioru unikalnych imion, używam metody string.Join, aby połączyć te imiona z powrotem w jeden string, oddzielając je średnikami. Wynikiem jest łańcuch zawierający każde imię tylko raz, w formacie podobnym do łańcucha wejściowego.
  5. Kolejność Elementów: Warto zauważyć, że HashSet nie gwarantuje zachowania kolejności elementów. Oznacza to, że kolejność imion w łańcuchu wyjściowym może być inna niż w łańcuchu wejściowym. Jeśli kolejność jest ważna, należałoby użyć innej metody, na przykład List w połączeniu ze sprawdzaniem, czy lista już zawiera dane imię, zanim zostanie ono dodane.
  6. Wykorzystanie w Innych Kontekstach: Ten wzorzec można zastosować w różnych scenariuszach, gdzie potrzebujemy usunąć duplikaty z listy. Może to być przydatne nie tylko dla stringów, ale także dla innych typów danych, pod warunkiem, że typ danych można porównać w celu ustalenia unikalności.

Alternatywny sposób

Alternatywną metodą usuwania duplikatów z ciągu imion w C#, bez użycia HashSet, jest wykorzystanie listy (List<string>) oraz opcjonalnie LINQ. Oto jak można zaimplementować tę metodę:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string inputString = "Marcin;Tomek;Adam;Iza;Marcin;Piotr;Adam;";
        string[] names = inputString.Split(';');
        List<string> uniqueNamesList = new List<string>();

        foreach (var name in names)
        {
            if (!string.IsNullOrWhiteSpace(name) && !uniqueNamesList.Contains(name))
            {
                uniqueNamesList.Add(name);
            }
        }

        string outputString = string.Join(";", uniqueNamesList) + ";";
        Console.WriteLine(outputString);
    }
}

Ta metoda jest szczególnie przydatna, gdy kolejność imion jest ważna, ponieważ lista zachowuje kolejność dodawania elementów. Jednak, jak wspomniano, jest mniej wydajna niż wykorzystanie HashSet, szczególnie dla dużych zestawów danych. ​​

  1. Rozdzielenie Stringa na Imiona: Tak jak w poprzednim przykładzie, najpierw dzielimy łańcuch wejściowy na poszczególne imiona, używając metody Split.
  2. Lista i Manualne Sprawdzanie Unikalności: Zamiast HashSet, używamy listy (List<string>) do przechowywania imion. Następnie iterujemy przez każde imię i dodajemy je do listy tylko wtedy, gdy jeszcze się tam nie znajduje. Ta metoda wymaga ręcznego sprawdzenia, czy lista już zawiera dane imię, co jest mniej wydajne niż użycie HashSet, ale pozwala na zachowanie kolejności imion.
  3. Opcjonalne Użycie LINQ: Możemy użyć LINQ (Language Integrated Query) w C# do dodatkowych operacji na listach, takich jak filtrowanie pustych stringów, ale w tym przypadku nie jest to konieczne, ponieważ już manualnie kontrolujemy zawartość listy.
  4. Łączenie Imion z Powrotem w Ciąg: Na końcu, tak jak wcześniej, używamy string.Join, aby połączyć imiona z listy w jeden string, oddzielając je średnikami.

Alternatywny sposób

Istnieje jeszcze inna metoda realizacji tego zadania w C# bez używania HashSet czy listy (List<string>) wraz z ręcznym sprawdzaniem duplikatów. Tym razem zastosujemy LINQ (Language Integrated Query), które jest potężnym narzędziem do manipulacji kolekcjami danych w C#. Oto jak można to zrobić:

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        string inputString = "Marcin;Tomek;Adam;Iza;Marcin;Piotr;Adam;";
        var names = inputString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

        var uniqueNames = names.Distinct();

        string outputString = string.Join(";", uniqueNames) + ";";
        Console.WriteLine(outputString);
    }
}
  1. Rozdzielenie Stringa na Imiona i Użycie LINQ: Rozpoczynamy od rozdzielenia łańcucha wejściowego na poszczególne imiona, a następnie używamy LINQ do przetworzenia tych danych. LINQ pozwala na wykonanie złożonych zapytań do kolekcji w stylu podobnym do zapytań SQL.
  2. Distinkt i Filtrowanie: Z LINQ, możemy użyć metody Distinct(), aby automatycznie usunąć duplikaty. Dodatkowo, możemy zastosować Where() do filtrowania pustych stringów lub innych niepożądanych wartości.
  3. Łączenie Wyników: Po przetworzeniu danych za pomocą LINQ, używamy string.Join, aby połączyć wyniki z powrotem w jeden ciąg, oddzielając imiona średnikami.

W tym programie:

  • Używamy Split z StringSplitOptions.RemoveEmptyEntries, aby od razu usunąć puste stringi z wynikowej tablicy.
  • Distinct() z LINQ usuwa wszelkie duplikaty.
  • Join łączy wszystkie unikalne imiona z powrotem w jeden ciąg.

Ta metoda jest bardziej elegancka i mniej kodu wymaga niż poprzednie, wykorzystując moc LINQ do efektywnego przetwarzania kolekcji. Jest szczególnie przydatna w przypadkach, gdy chcemy zastosować bardziej złożone operacje na danych.

1 comment

  1. Twoje podejście do problemu jest bardzo klarowne. Dzięki za dzielenie się swoją wiedzą

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *