Advertisement
Guest User

Untitled

a guest
May 3rd, 2015
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.82 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace Codifica_aritmetica
  8. {
  9.     class Program
  10.     {
  11.         private static Dictionary<int, double> simboli = new Dictionary<int, double>();
  12.         static void Main(string[] args)
  13.         {
  14.             // Aggiuge i simboli al mio dizionario. Ogni simbolo è associato alla sua propbabilità.
  15.             simboli.Add(0, 0.9);
  16.             simboli.Add(1, 0.1);
  17.  
  18.             Console.WriteLine("Inserisci la stringa da codificare secondo la codifica aritmetica:<");
  19.  
  20.             // Recupera la stringa da codificare da console.
  21.             string stringa = Console.ReadLine();
  22.  
  23.             // Codifica la stringa.
  24.             string intervalloDiCodifica = IntervalloCodificaAritmetica(stringa).ToString();
  25.  
  26.             // Stampa la codifica su schermo.
  27.             Console.WriteLine("La stringa codifica è:");
  28.             Console.WriteLine(intervalloDiCodifica);
  29.  
  30.             // Aspetta la pressione di un tasto per terminare il programma.
  31.             Console.ReadKey();
  32.         }
  33.  
  34.         private static double Cdf(double x)
  35.         {
  36.             // La cdf parte con probabilità zero.
  37.             double probabilità = 0;
  38.  
  39.             // Il ciclo scorre tutti gli elementi inseriti nel dizionario dei simboli.
  40.             //
  41.             //         /|\
  42.             //        1 |- - - - - - -°
  43.             //      1/2 | - - °   !   |
  44.             //  ________|_____|___!___|______\
  45.             //          |     A   x   B      /
  46.             //
  47.             // Ad ogni passo del ciclo viene controllato se X è a sinistra o a destra di 'simbolo.key'.
  48.             // Se è a destra incremento la probabilità di 'simbolo.key' del valore 'simbolo.value'.
  49.             // Se è a sinistra allora ritorno la probabilità che ho calcolato fin'ora.
  50.             // Dato che la cdf è continua a destra è < e non <=
  51.             //
  52.             // Utilizzando la figura soprastante mostro un esempio:
  53.             // - La prima esecuzione del ciclo controllo la posizione di X rispetto al simbolo A.
  54.             // - In questo caso X è a destra, quindi la cdf(x) vale almeno cdf(A),
  55.             //   quindi aggiungo a 'probabilità' la probabilità del simbolo A ovvero 'simbolo.value'.
  56.             // - Termina l'esecuzione della prima esecuzione del ciclo.
  57.             // - La seconda esecuzione del ciclo controllo la posizione di X rispetto al simbolo B.
  58.             // - In questo caso X è a sinistra rispetto a B: dato che la cdf è costante nell'intervallo [A,B)
  59.             //   allora termino il ciclo e restituisco il valore di 'probabilità' precedentemente calcolato.
  60.             foreach (var simbolo in simboli)
  61.             {
  62.                 if (x < simbolo.Key)
  63.                 {
  64.                     return probabilità;
  65.                 }
  66.                 else
  67.                 {
  68.                     probabilità += simbolo.Value;
  69.                 }
  70.             }
  71.  
  72.             // Se l'esecuzione raggiunge questo punto la probabilità deve essere 1. Se questo non fosse verificato,
  73.             // la somma delle probabilità dei simboli non è uno, quindi probabilmente sono state inserite non corretamente.
  74.             if (probabilità != 1)
  75.             {
  76.                 Console.WriteLine("!!! I simboli non hanno somma delle probabilità uguale a 1 !!!");
  77.             }
  78.             return probabilità;
  79.         }
  80.  
  81.         private static Intervallo IntervalloCodificaAritmetica(string stringa)
  82.         {
  83.             // Definisce l'intervallo di partenza. Variabile utilizzata anche per tener conto dell'intervallo precedente.
  84.             Intervallo intervalloPrecedente = new Intervallo(0, 1);
  85.  
  86.             if (string.IsNullOrEmpty(stringa))
  87.             {
  88.                 Console.WriteLine("La stringa non deve essere vuota.");
  89.  
  90.                 // Risultato per indicare che si è verificato un errore.
  91.                 return new Intervallo(-1, -1);
  92.             }
  93.  
  94.             int i = 0;
  95.             double nuovoInizio = 0;
  96.             double nuovaFine = 0;
  97.  
  98.             // Scorre la stringa dal primo carattere all'ultimo.
  99.             for (i = 0; i < stringa.Length; i++)
  100.             {
  101.                 // Converte l'ultimo carattere della stringa in un intero.
  102.                 int simbolo = stringa[i] - '0';
  103.  
  104.                 // Controlla che il simbolo sia contenuto nel dizionario dei simboli.
  105.                 if (!simboli.ContainsKey(simbolo))
  106.                 {
  107.                     Console.WriteLine("Il simbolo " + stringa[i] + " non è contenuto nel dizionario dei simboli.");
  108.  
  109.                     // Risultato per indicare che si è verificato un errore.
  110.                     return new Intervallo(-1, -1);
  111.                 }
  112.  
  113.                 // Applico l'algoritmo per calcolare i nuovi estremi dell'intervallo.
  114.                 nuovoInizio = intervalloPrecedente.Inizio + (intervalloPrecedente.Fine - intervalloPrecedente.Inizio) * Cdf(simbolo - 1);
  115.                 nuovaFine = intervalloPrecedente.Inizio + (intervalloPrecedente.Fine - intervalloPrecedente.Inizio) * Cdf(simbolo);
  116.  
  117.                 // Salvo i risultati.
  118.                 intervalloPrecedente.Inizio = nuovoInizio;
  119.                 intervalloPrecedente.Fine = nuovaFine;
  120.             }
  121.  
  122.             return intervalloPrecedente;
  123.         }
  124.     }
  125.  
  126.     // Rappresenta un intervallo [Inizio, Fine].
  127.     public class Intervallo
  128.     {
  129.         public double Inizio { get; set; }
  130.         public double Fine { get; set; }
  131.  
  132.         public Intervallo(double i, double f)
  133.         {
  134.             Inizio = i;
  135.             Fine = f;
  136.         }
  137.  
  138.         // Sovrascrive la funzione ToString fornita a tutti gli oggetti di C#.
  139.         public override string ToString()
  140.         {
  141.             return "[" + Inizio + "," + Fine + "]";
  142.         }
  143.     }
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement