Lestvica

Lestvica

Avtor: Katja Pleško

OPIS PROBLEMA

Na datotekah prva.txt in druga.txt so zapisane podatki o priljubljenosti skladb na lokalni radijski postaji Vreščalo. V vsaki vrstici so podatki: ime izvajalca in naslov skladbe ter število glasov. Podatek o številu glasov je s podpičjem ločen od ostalih podatkov. Podatki NISO urejeni, se pa vsaka skladba pojavi samo enkrat. Ob koncu drugega leta je želel DJ Ropotalo poiskati tisto skladbo, kateri je priljubljenost najbolj narastla ali padla v enem letu. (Priljubljenost je uvrstitev na lestvici glede na število prejetih glasov. Pazi: Nekatere skladbe se lahko pojavijo le na eni lestvici.)

IDEJA REŠITVE IN RAZLAGA ALGORITMA

Na datoteko prva.txt in druga.txt zapišemo podatke o priljubljenosti skladb na lokalni radijski postaji Vreščalo.

Napišemo razred Skladba s komponentami naslovInIzvajalec, stPrejetihGlasov. Napišemo get in set metode.

Nato napišemo glavni program. Naredimo dva seznama, kjer hranimo indekse skladb na lestvici z največjim napredkom oziroma največjim padcem. Seznam potrebujemo zato, ker lahko več sklad doseže največji napredek ali padec. Nato s for zanko poiščemo skladbo, ki je najbolj napredovala na lestvici. Želimo izračunati mesto na lestvici. V primeru, da si skladba nima enakega števila glasov kot katerakoli druga skladba je mesto na lestvici enako indeksu skladbe v seznamu lestvica (predpostavimo, da je 0 najboljše mesto na lestvici, saj je pri računanju napredka in padca po lestvici vseeno s katerim mestom začnemo. V primeru, da si skladba deli mesto s kako drugo skladbo pa je mesto na lestvici enako indeks skladbe v seznamu – št. pesmi, ki imajo enako število glasov in se nahajajo v seznamu pred indeksom skladbe za katero računamo mesto.

Preberemo skladbe iz datoteke "imeDatoteke". Gradimo urejen seznam skladb (skladbe urejene po številu prejetih glasov).

List<Skladba> je seznam objektov tipa Skladba. Zakaj smo uporabili seznam in ne tabelo? Seznam ima dinamičen prostor, tabela pa statičen, kar omogoča vrivanje elementov na različne indekse. Naloga je tako veliko lažje rešljiva.

Datoteko beremo vrstico za vrstico, dokler ne pridemo do konca datoteke. Ločimo podatek o naslovu in izvajalcu ter število glasov. Skladbo dodamo v tabelo vseh skladb glede na število prejetih glasov. Skladbe v tabeli uredimo od tiste, ki ima največ glasov do tiste z najmanj glasovi.

PROGRAM - RAZRED SKLADBA


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nal_Lestvica
{
    public class Skladba
    {
        string naslovInIzvajalec;

        public string NaslovInIzvajalec
        {
            get { return naslovInIzvajalec; }
            set { naslovInIzvajalec = value; }
        }
        int stPrejetihGlasov;

        public int StPrejetihGlasov
        {
            get { return stPrejetihGlasov; }
            set { stPrejetihGlasov = value; }
        }

        public Skladba(string naslovInIzvajalec, int stPrejetihGlasov)
        {
            this.naslovInIzvajalec = naslovInIzvajalec;
            this.stPrejetihGlasov = stPrejetihGlasov;
        }

        public Skladba(string naslovInIzvajalec)
        {
            this.naslovInIzvajalec = naslovInIzvajalec;
            this.stPrejetihGlasov = 0;
        }
    }
}

PROGRAM - GLAVNI PROGRAM


namespace Nal_Lestvica
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Skladba> prvaLestvica = PreberiSkladbeIzDatoteke("prva.txt");
            List<Skladba> drugaLestvica = PreberiSkladbeIzDatoteke("druga.txt");

            int maxNapredek = 0;
            int maxPadec = 0;
            //v seznamu hranimo indekse skladb na lestvici z največjim napredkom oz. največjim padcem
            //Seznam potrebujemo zato ker lahko več skladb doseže največji napredek oz. padec
            //ker je lahko več enakih
            List<int> indexMaxNapredka = new List<int>();
            List<int> indexMaxPadca = new List<int>();

            //poiščemo skladbo ki je najbolj napredovala po lestvici
            for (int index = 0; index < drugaLestvica.Count; index++)
            {
                int mestoDrugaLestvica = IzracunMestaNaLestvici(drugaLestvica, index);
                //v primeru, da se skladba pojavi samo na drugi lestvici bi napredek izračunali:
                int napredek = drugaLestvica.Count - mestoDrugaLestvica;
                //preverimo ali se skladba iz druge lestvice pojavi v prvi lestvici
                for (int index2 = 0; index2 < prvaLestvica.Count; index2++)
                {
                    //v primeru, da je spodnji if stavek resničen se skladba pojavi v obeh lestvicah
                    if (drugaLestvica[index].NaslovInIzvajalec.CompareTo(prvaLestvica[index2].NaslovInIzvajalec) == 0)
                    {
                        int mestoPrvaLestvica = IzracunMestaNaLestvici(prvaLestvica,index2);
                        //ponastavimo napredek ter zaključimo iskanje po prvi lestvici
                        napredek = mestoPrvaLestvica - mestoDrugaLestvica;
                        break;
                    }
                }
                if (napredek >= maxNapredek)
                {
                    if (napredek > maxNapredek)
                    {
                        //zbrišemo vse elemente iz seznama
                        indexMaxNapredka.Clear();
                        //Ponastavimo vrednost maxNapredka
                        maxNapredek = napredek;
                    }
                    //dodamo indeks skladbe, ki ima enak napredek kot skladba z dosedaj največjim napredkom
                    indexMaxNapredka.Add(index);
                }
                if (napredek <= maxPadec)
                {
                    if (napredek < maxPadec)
                    {
                        //zbrišemo vse elemente iz seznama
                        indexMaxPadca.Clear();
                        //Ponastavimo vredsnot maxPadca
                        maxPadec = napredek;
                    }
                    indexMaxPadca.Add(index);
                }
            }
            Console.WriteLine("Max napredek: ");
            for (int index = 0; index < indexMaxNapredka.Count; index++)
            {
                Console.WriteLine(String.Format("Izvajalec in naslov: {0} Število napredovanih mest: {1}",
                    ((Skladba)drugaLestvica[indexMaxNapredka[index]]).NaslovInIzvajalec, maxNapredek));
            }
            Console.WriteLine();
            Console.WriteLine("Max padec: ");
            for (int index = 0; index < indexMaxPadca.Count; index++)
            {
                Console.WriteLine(String.Format("Izvajalec in naslov: {0} Število napredovanih mest: {1}",
                    ((Skladba)drugaLestvica[indexMaxPadca[index]]).NaslovInIzvajalec, maxPadec));
            }
            Console.ReadLine();
        }

        //Izračun mesta na lestvici
        //V primeru, da si skladba nima enakega števila glasov kot katerakoli druga skladba je mesto na lestvici enako
        //indeksu skladbe v seznamu lestvica (predpostavili bomo da je 0 najboljše mesto na lestvici, saj je
        //pri računanju napredka ali padca po lestvici vseeno s katerim mestom začnemo)
        //V primeru, da si skladba deli mesto s kako drugo skladbo pa je mesto na lestvici enako:
        //indeks skladbe v seznamu - št. pesmi, ki imajo enako število glasov in se nahajajo v seznamu pred indeksom skladbe
        //za katero računamo mesto.
        private static int IzracunMestaNaLestvici(List<Skladba> lestvica, int indexSkladbe)
        {
            int stevecEnakih = 0;
            for (int i = indexSkladbe - 1; i >= 0; i--)
            {
                if (lestvica[i].StPrejetihGlasov != lestvica[indexSkladbe].StPrejetihGlasov)
                {
                    break;
                }
                stevecEnakih++;
            }
            return indexSkladbe - stevecEnakih;
        }

        //Preberemo skladbe iz datoteke "imeDatoteke"
        //Gradimo urejen seznam skladb (skladbe urejene po številu prejetih glasov)
        //Algoritem urejanja z Vstavljanjem, le da urejanje izvajamo že med samim branjem iz datoteke
        private static List<Skladba> PreberiSkladbeIzDatoteke(string imeDatoteke)
        {
            //List<Skladba> je seznam objektov tipa Skladba
            //Zakaj smo uporabili seznam in ne tabelo:
            //Seznam ima dinamičen prostor, tabela pa statičen
            //Omogoča "vrivanje" elementov na različne indekse

            //Več o tipu List : http://www.dotnetperls.com/list
            List<Skladba> lestvica = new List<Skladba>();
            StreamReader dat = File.OpenText(imeDatoteke);
            //datoteko beremo vrstico po vrstico, dokler ne pridemo do konca datoteke
            string vrstica = dat.ReadLine();
            while (vrstica != null)
            {
                //ločimo podatek o izvajalcu in naslovu ter podatek o številu glasov
                string[] razclenjenaVrstica = vrstica.Split(';');
                Skladba skladba = new Skladba(razclenjenaVrstica[0], int.Parse(razclenjenaVrstica[1]));
                bool dodanoVtabelo = false;
                //skladbo dodamo v tabelo vseh skladb glede na število prejetih glasov
                //skladbe v tabeli uredimo od tiste, ki ima največ glasov do tiste z najmanj glasovi
                for (int index = 0; index < lestvica.Count; index++)
                {
                    if (((Skladba)lestvica[index]).StPrejetihGlasov < skladba.StPrejetihGlasov)
                    {
                        lestvica.Insert(index, skladba);
                        dodanoVtabelo = true;
                        break;
                    }
                }
                if (!dodanoVtabelo)
                {
                    lestvica.Add(skladba);
                }
                vrstica = dat.ReadLine();
            }
            dat.Close();
            return lestvica;
        }
    }
}

TESTNI PRIMERI

0%
0%