Black friday Black friday
Pouze tento týden až 80% sleva na PHP, Nette, Symfony!
Aprílový black friday tě nenechá v klidu! Až 80 % prémiového obsahu zdarma. Více informací
Avatar
Tomáš Berky:5. března 8:31

Potřeboval bych nějak pomoci s frekvenční analýzou písmen, nemusí mi to tady někdo poslat hotové, stačilo by mi trochu výraznější postrčení správným směrem. Děkuji

 
Odpovědět 5. března 8:31
Avatar
Ilja Židkov
Člen
Avatar
Odpovídá na Tomáš Berky
Ilja Židkov:5. března 9:55

Stará dobrá školní úloha, která může mít 1000 řešení. Přikládám moji implementaci a vysvětlení.

Podle mě, nejpřirozenější řešení je využít algoritmu Hašovací tabulka. Podobná implementace už existuje v C#. Je to kontejner Dictionary<TKey, TValue>().

Slovník, jehož klíčem je hledaný prvek (unikátní pochopitelně), který může mít více výskytů.

using System;
using System.Collections.Generic;
using System.IO;

namespace FrequencyAnalysis
{
    /// <summary>
    /// Reprezentuje analyzator frekvence výskytu znaků v textu.
    /// </summary>
    public static class Analyzer
    {
        /// <summary>
        /// Analyzuje frekvenci výskytu znaků v přiloženém souboru.
        /// </summary>
        /// <param name="filePath">Cesta k souboru, který je určený pro analýzu znaků.</param>
        /// <returns>Kolekci, jehož klíčem je hledaný znak a hodnotou, je frekvence výskytu.</returns>
        public static Dictionary<char, int> AnalyzeCharacters(string filePath)
        {
            // Výsledná frekvenční analýza znaku.
            var frequency = new Dictionary<char, int>();

            // Načti veškerý text ze souboru.
            var text = File.ReadAllText(filePath);

            // Pro každý znak v načteném textu...
            foreach (var character in text)
            {
                // ověř, jestli náhodou znak není mezera nebo číslo...
                if (!char.IsLetterOrDigit(character))
                    // pokud je, přeskoč tento klíč a iteruj dál...
                    continue;

                // jestliže aktuálně nalezený znak je nový...
                if (!frequency.ContainsKey(character))
                    // zaznemenej ho, a nastav počet výskytů na 1 (čili je nový)
                    frequency.Add(key: character, value: 1);
                // v opačném případě... (čili znak už existuje)
                else
                    // zvyš počet výskytů o 1.
                    frequency[character]++;
            }

            // Vrať výslednou frekvenční analýzů znaků.
            return frequency;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Jsem na Macu ve Visual Studiu Code, na Windows ve Visual Studiu tohle přeskoč.
            Console.Clear();

            // Proveď frekvenční anlýzů znaků v souboru "lorem.txt"
            var characters = Analyzer.AnalyzeCharacters("lorem.txt");

            Console.WriteLine("KLIC\tHODNOTA");

            // Iteruj skrz každý znak (klíč) ve výsledné analýze
            foreach (var character in characters)
                // zobraz samotný znak (klíč) a jeho počet výskytu.
                Console.WriteLine($"{character.Key}\t{character.Value}");

            Console.ReadKey();
        }
    }
}

lorem.txt

aaaa bbb cc d

výstup

KLIC    HODNOTA
a       4
b       3
c       2
d       1

Samozřejmě, normálně bych vytvořil rozhraní, která by obsahovala metodu Analyze() a vytvářel instance implementací, protože toto řešení je v rozporu s OCP (Open-closed principle) v SOLID design principles.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět  +3 5. března 9:55
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.