Τι κάνει ο αλγόριθμος CountVowels
Ο αλγόριθμος CountVowels παίρνει μια λέξη ή πρόταση και μετρά πόσα φωνήεντα περιέχει.
Βήματα λειτουργίας:
- Δέχεται ένα string από τον χρήστη.
- Για κάθε χαρακτήρα: Ελέγχει αν είναι φωνήεν (α, ε, η, ι, ο, υ, ω ή a, e, i, o, u).
- Αν είναι φωνήεν ➜ αυξάνει τον μετρητή.
- Τέλος, εμφανίζει πόσα φωνήεντα βρέθηκαν.
Χρονική πολυπλοκότητα: O(n) (μία διέλευση του string).
```using System.Globalization;
using System.Text;
namespace CountVowels
{
public static class CountVowelsCalc
{
public static int CountVowels(string word, HashSet<char> GreekVowels) {
if (string.IsNullOrWhiteSpace(word))
return 0;
word = RemoveDiacritics(word);
int count = 0;
foreach (char character in word)
{
if (GreekVowels.Contains(character))
count++;
}
return count;
}
private static string RemoveDiacritics(string text) {
var normalized = text.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
foreach (var ch in normalized)
{
var unicodeChar = CharUnicodeInfo.GetUnicodeCategory(ch);
if (unicodeChar != UnicodeCategory.NonSpacingMark)
stringBuilder.Append(ch);
}
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}
}
}```
Βλέπουμε δύο μεθόδους την CountVowels και την RemoveDiacritics η οποία γίνεται χρήση μέσα απο την CountVowels προκειμένου να καθαρίσει το κείμενο απο τονισμένα γράμματα, και να μπορέσει στην συνέχεια να υπολογίσει τα φωνίεντα που περιέχει η λέξη.
namespace CountVowels
{
internal class Program
{
static readonly HashSet<char> GreekVowels = [.."αεηιουωΑΕΗΙΟΥΩ"];
static void Main(string[] args)
{
Console.Write("Δώσε μια πρόταση: ");
string input = Console.ReadLine() ?? "";
int vowels = CountVowelsCalc.CountVowels(input, GreekVowels);
Console.WriteLine($"Η πρότασή σου περιέχει {vowels} φωνήεντα.");
Console.WriteLine("\nΠάτησε Enter για έξοδο...");
Console.ReadLine();
}
}
}
Διαφορά μεταξύ HashSet και List, πως επηρεάζει ταχύτητα, τρόπο αναζήτησης και χρήση μνήμης.
🔹 Τι είναι το HashSet
Το HashSet είναι μια δομή συλλογής (collection) που:
- Αποθηκεύει μοναδικές τιμές (χωρίς διπλότυπα),
- Δεν έχει σειρά (τα στοιχεία δεν είναι ταξινομημένα),
- Είναι πολύ γρήγορη όταν θες να ελέγξεις αν ένα στοιχείο υπάρχει.
📋 Παράδειγμα
var vowels = new HashSet<char> { 'α', 'ε', 'η', 'ι', 'ο', 'υ', 'ω' };
bool hasAlpha = vowels.Contains('α'); // True
vowels.Add('α'); // Δεν θα προστεθεί ξανά, γιατί ήδη υπάρχει
🔹 Τι είναι το List
Το List είναι μια σειριακή συλλογή:
- Μπορεί να έχει διπλότυπα στοιχεία,
- Διατηρεί τη σειρά με την οποία προσθέτεις τα στοιχεία,
- Είναι κατάλληλη για αποθήκευση και επεξεργασία λιστών δεδομένων, όπου σε νοιάζει η σειρά ή η θέση.
📋 Παράδειγμα
var numbers = new List<int> { 1, 2, 3, 3 };
numbers.Add(4); // Μπορείς να προσθέσεις το ίδιο νούμερο ξανά
bool hasThree = numbers.Contains(3); // True (αλλά η αναζήτηση είναι πιο αργή)
int first = numbers[0]; // Πρόσβαση με index
Διαφορές με μια ματιά
Χαρακτηριστικό | HashSet<T> |
List<T> |
---|---|---|
Διπλότυπα στοιχεία | ❌ Όχι επιτρεπτά | ✅ Επιτρεπτά |
Σειρά στοιχείων | ❌ Δεν διατηρείται | ✅ Διατηρείται |
Ταχύτητα Contains() |
⚡ Πολύ γρήγορη (O(1)) | 🐢 Πιο αργή (O(n)) |
Πρόσβαση με index | ❌ Όχι | ✅ Ναι |
Κατάλληλο για | Έλεγχο ύπαρξης στοιχείου | Διαχείριση ακολουθιών |
Παράδειγμα για να το καταλάβεις πρακτικά
Στο πρόγραμμά γίνεται χρήση:
HashSet<char> GreekVowels = new HashSet<char>("αεηιουωΑΕΗΙΟΥΩ");
Αν γίνοταν χρηση της List, τότε κάθε φορά που θα ήθελες να ελέγξεις:
if (GreekVowels.Contains(character))
η List θα έπρεπε να ψάξει όλα τα στοιχεία ένα-ένα, δηλαδή αργά (O(n)).
Με το HashSet, ο έλεγχος Contains() είναι άμεσος (O(1)) χάρη στο hashing.
Με απλά λόγια:
👉 Χρησιμοποίησε List όταν σε νοιάζει η σειρά ή έχεις διπλότυπα.
👉 Χρησιμοποίησε HashSet όταν σε νοιάζει η μοναδικότητα και η ταχύτητα στις αναζητήσεις.
Υποσημείωση
Το O(n) (λέγεται “Big O notation”) είναι ένας τρόπος να περιγράψουμε πόσο “κοστίζει” ένας αλγόριθμος — δηλαδή πόσο χρόνο χρειάζεται (ή μνήμη) καθώς μεγαλώνει το μέγεθος των δεδομένων.
Τι σημαίνει το “O(n)”
Το n είναι το πλήθος των στοιχείων που επεξεργάζεται ο αλγόριθμος.
Αν έχεις λίστα με 10 στοιχεία, τότε n = 10
Αν έχεις λίστα με 1.000.000 στοιχεία, τότε n = 1.000.000
Το O(n) σημαίνει:
Ο χρόνος εκτέλεσης αυξάνεται αναλογικά με το μέγεθος των δεδομένων.
Δηλαδή, αν διπλασιάσεις τα δεδομένα → διπλασιάζεται περίπου και ο χρόνος.
Παράδειγμα με λίστα (List)
Αν κάνεις:
var list = new List<int> {1, 2, 3, 4, 5};
bool found = list.Contains(5);
Η μέθοδος Contains() ψάχνει ένα-ένα τα στοιχεία:
Είναι το 1; ❌
Είναι το 2; ❌
Είναι το 3; ❌
Είναι το 4; ❌
Είναι το 5; ✅ — σταματά.
➡️ Αν το στοιχείο είναι στο τέλος (ή δεν υπάρχει), θα χρειαστεί να ελέγξει όλα τα n στοιχεία.
Γι’ αυτό λέμε ότι έχει χρονική πολυπλοκότητα O(n).
Παράδειγμα με HashSet
Αν κάνεις το ίδιο με ένα HashSet:
var set = new HashSet<int> {1, 2, 3, 4, 5};
bool found = set.Contains(5);
Το HashSet δεν ψάχνει ένα-ένα — χρησιμοποιεί hashing, δηλαδή έναν γρήγορο μαθηματικό τρόπο να ξέρει αμέσως πού βρίσκεται κάθε στοιχείο.
➡️ Ελέγχει σχεδόν ακαριαία, ανεξάρτητα από το μέγεθος της συλλογής.
Γι’ αυτό λέμε ότι έχει O(1) (σταθερό χρόνο).
Με απλά λόγια
Δομή | Παράδειγμα | Πολυπλοκότητα | Τι σημαίνει πρακτικά |
---|---|---|---|
List |
list.Contains(x) |
O(n) | Όσο μεγαλώνει η λίστα, τόσο πιο αργό το ψάξιμο |
HashSet |
set.Contains(x) |
O(1) | Εξίσου γρήγορο, όσα στοιχεία κι αν έχει |
Quick C# Challenges to Keep Your Coding Skills Fresh 3."FizzBuzz"
Top comments (0)