Reševanje naloge KVADRAT

Reševanje naloge KVADRAT

Avtor: Tanja Kokalj

BESEDILO NALOGE

Vsi razredi naj obvezno vsebujejo naslednji dve metodi (torej jih morate obvezno napisati!): • DodajNaDatoteko(string imeDatoteke), ki objekt this zapiše (doda! – glej metodo File.AppendText()) vrstico, kjer doda vse podatke objekta, med sabo ločene z znakom ';' • PreberiZDatoteke(string imeDatoteke), ki vrne tabelo objektov, kjer posamezni objekt vsebuje podatke, ki so zapisani v posamezni vrstici datoteke, med sabo ločeni z znakom ';'.

Pri sestavljanju razredov si prej oglejte problem(e), ki ga (jih) rešujete, da boste vedeli, kako mora biti zgrajen (katere podatke in metode vsebuje). Za vsako nalogo sestavite dva testna programa. Prvi služi zato, da v njem ustvarite vsaj 20 objektov in jih zapišite na datoteko. V "pravem" testnem programu pa naredite naslednje:

  • Napišite ustrezne metode za reševanje zastavljenih problemov.
  • Ustvarite vsaj en objekt in ga dodajte (z DodajNaDatotekov) v datoteko (na tej je sedaj vsaj 21 objektov).
  • Preberite vse podatke z datoteke v tabelo.
  • Tabelo potem pregledno izpišite.
  • Nato kličite metode, ki so potrebne, da rešite zastavljene probleme in pregledno izpišite rezultate.
  • Na koncu V datoteko z imenom imeDat (parameter) zapišite ponovno vse podatke vseh objektov (ne glede na to, ali so jih zgornje metode spremenile ali ne) v tabeli, med sabo ločene z znakom ':' (podatki o posameznem objektu gredo v svojo vrstico).

KVADRAT

Napišite razred Kvadrat, s katerim predstavite kvadrat. Kvadrat je predstavljen z dolžino ene stranice. Sestavite tudi metodi za izračun ploščine in obsega kvadrata.

  • Izračunajte, kakšno površino lahko prekrijete s kvadrati, ki so v tabeli
  • Vrnite kopijo tistega kvadrata, ki ima najmanjši obseg.
  • Vsem tistim kvadratom v tabeli, katerih obseg je več kot 10% manjši od povprečnega obsega vseh kvadratov, spremenite stranico tako, da bodo imeli obseg (do zaokrožitvene napake) enak povprečnemu.
  • Vsaj en (zaželjeno pa več) problem po vaši izbiri ... (opišite jih!)

OPIS PROBLEMA IN IDEJA REŠITVE TER RAZLAGA ALGORITMA

Ustvarili bomo razred Kvadrat. Sprva mu bomo napisali ustrezne metode za reševanje zastavljenih problemov. Najprej določimo, da bo parameter, ki bo podan pri definiranju objekta, predstavljal dolžino stranice kvadrata.
class Kvadrat
{
  public int dolzinaStranice;
  public Kvadrat(int dolzina)
  {
    dolzinaStranice = dolzina;
  }

Nato bomo še sestavili metodi za izračun obsega ter ploščine. Metodi bosta delovali na naš objekt.
  public int ploscina()
  {
    return dolzinaStranice * dolzinaStranice;
  }

  public int obseg()
  {
    return 4*dolzinaStranice;
  }

Znotraj razreda bomo ustvarili tudi metodo DodajNaDatoteko. Ta bo zapisovala objekte na datoteko. Vsak objekt bo predstavljen le z dolžino stranice.


  public void DodajNaDatoteko(string imeDatoteke)
  {
     StreamWriter pisalec = new StreamWriter(imeDatoteke, true);
     pisalec.WriteLine(this.dolzinaStranice+";");
     pisalec.Close();
  }

Eden izmed osnovnih metod pri razredu je tudi spraviti objekt v zapis. Pri tem bomo prepisali metodo ToString v obliko, ki jo bomo razumeli. V zapisu bo razvidno, da gre za objekt kvadrat in da vrednost predstavlja dolžino stranice.
  override public string ToString()

  {
    return "<Kvadrat - dolzina stranice:" + this.dolzinaStranice + ">";
  }
}

Sedaj moramo še narediti zunanjo metodo PreberiZDatoteke. Ta bo podatke iz datoteke zapisala v seznam vseh kvadratov. Elementi tega seznama pa bodo objekti iz razreda kvadrat in bomo na njih lahko izvajali vse metode.


static Kvadrat[] PreberiZDatoteke(string imeDatoteke)
{
    StreamReader bralec = new StreamReader(imeDatoteke);
    string[] vrstice = bralec.ReadToEnd().Split('\n');

    List<Kvadrat> tabelaKvadratov = new List<Kvadrat>();
    for (int i = 0; i < vrstice.Length; i++)
    {
         if (vrstice[i].Length > 0)
         {
             string dolzinaStranice = vrstice[i].Split(';')[0];
             tabelaKvadratov.Add(new Kvadrat(int.Parse(dolzinaStranice)));
         }
    }

    return tabelaKvadratov.ToArray();
 }

TESTNI PRIMERI


        static void Main(string[] args)
        {
            string imeDat = "tabela.txt";
            // Kličemo testni program 1 (generira in zapiše 20 objektov)
            test1(imeDat);

            // Kličemo testni program 2 (prebere in operira z objekti)
            test2(imeDat);

        }

Na začetku nimamo podatkov, zato naključno zgeneriramo nekaj elementov. V tabeli so zgolj podatki o dolžini stranice.


        static void test1(string imeDat)
        {
            //Datoteko najprej pobrišemo
            FileStream stream = new FileStream(imeDat, FileMode.Create);
            TextWriter writer = new StreamWriter(stream);
            writer.Write("");
            writer.Close();

            // Generiramo 20 objektov tipa Kvadrat
            for (int i = 0; i < 20; i++)
            {
                Random generator = new Random();
                Kvadrat kvadrat = new Kvadrat(generator.Next(1,10) * (i+1));
                kvadrat.DodajNaDatoteko(imeDat);
            }
        }

        static void test2(string imeDat)
        {
            // Ustvarimo in dodamo nov objekt, da jih je potem 21
            Kvadrat kvadrat = new Kvadrat(10);
            kvadrat.DodajNaDatoteko(imeDat);

Podatke iz datoteke preberemo in vstavimo v tabelo. Tabela vsebuje elemente, ki so objekti razreda Kvadrat.
            // Preberemo podatke iz datoteke v tabelo
            Kvadrat[] tabelaKvadratov = PreberiZDatoteke(imeDat);

Tabelo s pomočjo metode ToString izpišemo v konzolno okno.
            // Tabelo izpišemo v konzolo
            Console.WriteLine("Tabela kvadratov iz datoteke " + imeDat + ":");
            for (int i = 0; i < tabelaKvadratov.Length; i++)
            {
                Console.WriteLine(tabelaKvadratov[i].ToString());
            }

Zanima nas površina, ki jo zasedejo vsi kvadrati iz tabele. Ploščino računamo preko metode ploščina, ki smo jo definirali zgoraj.
            // Izračunamo skupno površino in jo izpišemo
            int skupnaPovrsina = 0;
            for (int i = 0; i < tabelaKvadratov.Length; i++)
            {
                skupnaPovrsina += tabelaKvadratov[i].ploscina();
            }
            Console.WriteLine("");
            Console.WriteLine("S kvadrati, ki so v tabeli lahko prekrijemo površino: " + skupnaPovrsina + " e^2");

Želeli bi tudi vedeti kateri kvadrat ima najmanjši obseg. To naredimo tako, da gremo čez vse objekte in pogledamo kateri ima najmanjši obseg. Metodo za obseg pa smo tudi že definirali zgoraj.
            // Vrnemo kvadrat z najmanjšim obsegom
            Kvadrat najmanjsiKvadrat = tabelaKvadratov[0];
            float skupniObseg = 0;
            for (int i = 0; i < tabelaKvadratov.Length; i++)
            {
                skupniObseg += tabelaKvadratov[i].obseg();
                if (tabelaKvadratov[i].obseg() < najmanjsiKvadrat.obseg())
                {
                    najmanjsiKvadrat = tabelaKvadratov[i];
                }
            }
            Console.WriteLine("");
            Console.WriteLine("Kvadrat z najmanjšim obsegom: " + najmanjsiKvadrat.ToString());
            Console.WriteLine("");

Imamo nalogo , da preverimo obseg vseh objektov. Tistim objektom, ki imajo za več kot 10% manjši obseg od povprečnega moramo spremeniti dolžino stranice tako, da bo obseg enak povprečnemu. Najprej izračunamo povprečni obseg vseh kvadratov. Nato gremo s for zanko čez kvadrate in za vsakega izračunamo odstopanje od povprečja. Če je obseg manjši in je razlika večja od 10%, potem kvadrat popravimo na željeno dolžino stranice.


            // Vsem tistim kvadratom v tabeli, katerih obseg je več kot 10% manjši od povprečnega obsega vseh kvadratov, spremenimo stranico tako, da imajo obseg (do zaokrožitvene napake) enak povprečnemu.
            float povprecniObseg = skupniObseg / tabelaKvadratov.Length;
            for (int i = 0; i < tabelaKvadratov.Length; i++)
            {
                float razlika = Math.Abs(tabelaKvadratov[i].obseg() - povprecniObseg) / povprecniObseg;

                if (razlika > 0.10 && tabelaKvadratov[i].obseg() < povprecniObseg)
                {
                    Console.Write("Razlika: "+ razlika +" Dolžino stranice: "+tabelaKvadratov[i].dolzinaStranice + " popravimo na: ");
                    tabelaKvadratov[i].dolzinaStranice = (int)povprecniObseg / 4;
                    Console.Write(tabelaKvadratov[i].dolzinaStranice + "\n");
                }

            }

Med vsemi kvadrati poiščemo naključnega. Temu izračunamo ploščino včrtanega 45 0 zarotiranega kvadrata. To naredimo tako, da izračunamo razdaljo med razpoloviščema priležnih stranic. In izračunamo ploščino kvadrata, ki ima za stranico tako dolžino.
            // Naključno izbranemu kvadratu izračunaj ploščino včrtanega 45° zarotiranega kvadrata.
            Random generator = new Random();
            int indeksIzbranega = generator.Next(0, tabelaKvadratov.Length);
            Kvadrat izbraniKvadrat = tabelaKvadratov[indeksIzbranega];
            double stranicaRotiranegaKvadrata = (izbraniKvadrat.dolzinaStranice / 2) * Math.Sqrt(2);
            double ploscinaRotiranegaKvadrata = stranicaRotiranegaKvadrata * stranicaRotiranegaKvadrata;
            Console.WriteLine("");
            Console.WriteLine("Naključno izbrani kvadrat:"+izbraniKvadrat+" - ploščina včrtanega kvadrata rotiranega za 45°: "+ploscinaRotiranegaKvadrata+" e^2.");

Na koncu tabelo kvadratov le še zapišemo na datoteko.
            // Končno tabelo zapišemo v datoteko
            string imeKoncneDat = "koncna.txt";

            FileStream stream = new FileStream(imeKoncneDat, FileMode.Create);
            TextWriter writer = new StreamWriter(stream);
            writer.Write("");
            writer.Close();

            for (int i = 0; i < tabelaKvadratov.Length; i++)
            {
                tabelaKvadratov[i].DodajNaDatoteko(imeKoncneDat);
            }

            Console.Read();
        }

Prikaz testov s pomočjo filmčka

0%
0%