» »

C# program za pretvorbo v desetiško število z rekurzijo

C# program za pretvorbo v desetiško število z rekurzijo

Micho95 ::

Zdravo!

V šoli mam en problem naredit tole nalogo in imam na voljo še samo en zagovor. Imam narejeno večino naloge, razen podprogram za pretvorbo iz dvanajstiškega v naravno število (2. del programa).

Navodila:

Potrebno je implementirati:

podprogram za pretvorbo iz naravnega v dvanajstiško število (obvezna rekurzivna implementacija!),
podprogram za pretvorbo iz dvanajstiškega v naravno število (obvezna rekurzivna implementacija!),
podprogram za izračun vsote dveh dvanajstiških števil.
Prvi podprogram prejme naravno število in ga pretvori v dvanajstiško število ter ga vrne [v obliki niza znakov].
Drugi podprogram prejme dvanajstiško število [v obliki niza znakov], ga pretvori v naravno število ter ga vrne.
Tretji podprogram prejme dve dvanajstiški števili [dva niza znakov] ter izračuna in vrne vsoto teh dveh dvanajstiških števil [v obliki niza znakov].

V glavnem programu boste uporabniku ponudili izbiro podprograma, ki naj se izvrši. Poskrbite, da bo uporabnik pri posamezni izbiri vpisal samo tisto, kar izbrani podprogram zahteva (v primeru, da je zahtevan vpis dvanajstiškega števila in uporabnik vpiše kakšen znak, ki mu ne pripada, naj se izpiše napaka). Rezultat, ki ga vrne podprogram, v glavnem programu nato izpišite uporabniku.

Opomba: pri 3. podprogramu, si lahko pomagate z uporabo 1. in 2. podprograma.
Opomba 2: metod, ki samodejno pretvarjajo števila med posameznimi številskimi osnovami, ni dovoljeno uporabiti (npr. Convert.ToInt32()). Lahko jih uporabite samo v primeru, če jih implementirate sami.

Prosim za čim hitrejšo pomoč.

Koda (C#):

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

namespace ConsoleApplication5
{
    class Program
    {
        // SE REKURZIJA
        static string PretvoriVDvanajstiskoStevilo(int stevilo, string pretvorjenoStevilo)
        {            
            //SHRANJENI NIZ, KJER SE GRADI REZULTAT
            string rezultat = "";

            if (stevilo == 0)
            {
                //KO JE POGOJ IZPOLNJEN SE VRNE CELOTEN REZULTAT NIZA 
                for (int i = pretvorjenoStevilo.Length - 1; i >= 0; i--)
                {
                    rezultat += pretvorjenoStevilo[i];
                }
                return rezultat;
            }
            else
            {
                int ostanki;
                ostanki = stevilo % 12;
                pretvorjenoStevilo += ostanki.ToString();
                return PretvoriVDvanajstiskoStevilo(stevilo / 12, pretvorjenoStevilo);
            }   
        }

        //SE REKURZIJA
        static int PretvoriVDesetiskoStevilo(string stevilo, int desetiskoStevilo)
        {
            //int desetiskoStevilo = 0;
            int potenca = stevilo.Length - 1;
            int i = 0;

            if (i > potenca)
            {
                return desetiskoStevilo; 
            }

            else
            {
                desetiskoStevilo = desetiskoStevilo + (stevilo[i] - 48) * (int)Math.Pow(12, potenca);

                for (int j = 2; j < stevilo.Length; j++)
                {                    
                    PretvoriVDesetiskoStevilo(stevilo[j].ToString(), desetiskoStevilo);
                }
                i++;
                potenca--; 
            }


            /*for (int i = 0; i <= stevilo.Length - 1; i++)
            {
                desetiskoStevilo = desetiskoStevilo + (stevilo[i] - 48) * (int)Math.Pow(12, potenca);
                potenca--;
            }*/
            return desetiskoStevilo;
        }
       static string VsotaDvanajstiškihŠtevil(string stevilo1, string stevilo2, string pretvorjenoStevilo, string rezultat, int desetiskoStevilo)
        {
            //pretvori števili v desetiško in ju sešteje
            int sestevek = PretvoriVDesetiskoStevilo(stevilo1,desetiskoStevilo) + PretvoriVDesetiskoStevilo(stevilo2,desetiskoStevilo);
            //pretvori seštevek v osmiško števlo in ga vrne
            return PretvoriVDvanajstiskoStevilo(sestevek, pretvorjenoStevilo);
        }
        static bool PravilnostVnosaStevil(string nizZnakov)
        {
            bool ustreznost = false;
            char[] osmiskaStevila = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

            for (int a = 0; a < nizZnakov.Length; a++)
            {
                ustreznost = false;
                for (int b = 0; b < osmiskaStevila.Length; b++)
                {
                    if (nizZnakov[a] == osmiskaStevila[b])
                    {
                        ustreznost = true;
                        break;
                    }
                }
                if (ustreznost == false)
                {
                    break;
                }
            }
            return ustreznost;
        }

        static void Main(string[] args)
        {
            //uporabnika povpraša, kaj želi narediti
            Console.WriteLine("Vpišite 1-Za pretvorbo naravnega števila v osmiško" + "Vpišite 2-pretvorba osmiškega števila v desetiškega" + "Vpišite 3-za seštevanje dveh osmiških števil");
            //prebere število in ga shrani v spremenljivko
            string odlocitev = Console.ReadLine();
            string pretvorjenoStevilo = "";
            string rezultat = "";
            

            //odvisno od vnosa se izvede eden od podprogramov in izpiše rezultat
            if (odlocitev == "1")
            {
                try
                {
                    Console.WriteLine("Vpišite število, ki ga želite spremeniti v osmiško: ");
                    string stevilo = Console.ReadLine();
                    if (int.Parse(stevilo) >= 0)
                    {
                        PretvoriVDvanajstiskoStevilo(int.Parse(stevilo), pretvorjenoStevilo);
                        Console.Write("Pretvorjeno število = " + PretvoriVDvanajstiskoStevilo(int.Parse(stevilo), pretvorjenoStevilo));
                    }
                    else Console.WriteLine("Pretvorba negativnega števila v osmiškega ni mogoče!");
                }
                catch
                {
                    Console.Write("Napačen vnos!");
                }
            }
            else if (odlocitev == "2")
            {
                try
                {
                    Console.WriteLine("Vpišite osmiško število, ki ga želite spremeniti v desetiškega: ");
                    string stevilo = Console.ReadLine();
                    int desetiskoStevilo = 0; 
                    if (PravilnostVnosaStevil(stevilo) == true)
                    {
                        Console.Write("Pretvorjeno število = " + PretvoriVDesetiskoStevilo(stevilo, desetiskoStevilo));
                    }
                    else Console.Write("Napačen vnos!");
                }
                catch
                {
                    Console.Write("Napačen vnos!");
                }
            }
            else if (odlocitev == "3")
            {
                try
                {
                    Console.WriteLine("Vpišite prvo osmiško število: ");
                    string stevilo1 = Console.ReadLine();
                    Console.WriteLine("Vpišite drugo osmiško število: ");
                    string stevilo2 = Console.ReadLine();
                    if (PravilnostVnosaStevil(stevilo1) == true && PravilnostVnosaStevil(stevilo2) == true)
                    {
                       // Console.Write("Seštevek osmiških števil = " + VsotaDvanajstiškihŠtevil(stevilo1, stevilo2, pretvorjenoStevilo, rezultat));
                    }
                    else Console.Write("Napačen vnos!");
                }
                catch
                {
                    Console.Write("Napačen vnos!");
                }
            }
            else Console.WriteLine("Napačen vnos!");

            Console.ReadKey(true);
        }
    }
}

smacker ::

Dvanajstiško število ma števke 0,1,2,3,4,5,6,7,8,9,A(10),B(11). Prebereš dvanajstiško število od zadaj naprej (povečuješ i od 0 do dolžine vhodnega niza) in seštevaš v desetiško število ŠTEVKA * 12^i. (pri števki za A vzameš 10, za B pa 11).
Matematično: 1A2B = B(11) * 12^0 + 2 * 12^1 + A(10) * 12^2 + 1*12^4.
Kako to rekurzivno? simple, namesto for loopa si v naslednji klic funkcije pošlješ celo število brez zadnje števke + i povečan za ena.
Pseudokod:
function dvanajstistko_v_decimalno (string dvanajstisko, i=0){
   if(dvanajstisko.length==0) //če ni več števk v številu, vrne nič
       return 0; 
   else // drugače pa rekurzivno zračuna vrednost
       decimalno = dvanajstisko.zadnja_stevka * Math.Pow(12,i) + dvanajstistko_v_decimalno(dvanajstisko_brez_zadnje_stevke, i+1);
}

Spura ::

Smacker tale i je cist brez potrebe.

if (length == 0) return 0 else return convert(substring(0, end - 1)) * 12 + last

smacker ::

Res je, da se brez i-ja. Moj namen ni bil dat rešitve, ampak razložit da bo razumel. In analogija rekurzije z zanko (zato i) se mi je zdela posrečena razlaga. Enovrstičnico z rešitvijo bi mi bilo lažje prilimat, ampak glede na preostalo kodo bi vsak ugotovil, da tiste funkcije ni napisal sam :D

Spura ::

No, ampak tail recursion s parametrom i je pac najslabsa rekurzija, ker je dobesedno for loop.

smacker ::

Presenečen bi bil, kolk ljudi še tega ne razume ;) Se pa absolutno strinjam, da je pravilneje tako, kot si ti zapisal.

Micho95 ::

Zdravo!

Hvala za odgovore. Smacker, najbolj sem se približal tvojemu odgovoru, vendar mi še vedno logika pri tej zahtevni rekurziji ni točno jasna. Spodaj prilagam kodo te funkcije, ki sem jo spisal po tvoji odlični psevdokodi, ampak problem je nastal, ker mi piše da je vnos števila napačen (čeprav je vnos pravilen - recimo število 210).

Koda, kjer napaka nastane:

else if (odlocitev == "2")
            {
                try
                {
                    Console.WriteLine("Vpišite osmiško število, ki ga želite spremeniti v desetiškega: ");
                    string stevilo = Console.ReadLine();
                    int desetiskoStevilo = 0; 
                    if (PravilnostVnosaStevil(stevilo) == true)
                    {
                        Console.Write("Pretvorjeno število = " + PretvoriVDesetiskoStevilo(stevilo, desetiskoStevilo));
                    }
                    else Console.Write("Napačen vnos!");
                }
                catch
                {
                    Console.Write("Napačen vnos!");
                }
            }


Koda rekurzivne funkcije po psevdokodu:

static int PretvoriVDesetiskoStevilo(string stevilo, int i = 0)
{
	int desetiskoStevilo = 0;
	int potenca = stevilo.Length - 1;
	//int a = 0;
	int rezultat = 0;

	if (stevilo.Length == 0)
	{
		return 0;
	}
	else
	{
		//desetiskoStevilo = desetiskoStevilo + (stevilo[i] - 48) * (int)Math.Pow(12, potenca);
		desetiskoStevilo = (stevilo[i] * (int)Math.Pow(12, potenca)) + PretvoriVDesetiskoStevilo(stevilo[i + 1].ToString(), i++);
		//rezultat += desetiskoStevilo;
		potenca--;
		return rezultat += desetiskoStevilo;
	}
 }

Spura ::

Ni ti treba pisat if (x == true) ker je if (x) ekvivalentno.
Zgleda imas nek mismas pretvarjanja v dvanajstiska in osmiska.

Rekurzivni algoritem za pretvorbo iz dvanajstiskega v desetiskega je preprost:

Rezultat pretvorbe stringa dolzine 1 je vrednost te stevke.
Rezultat pretvorbe stringa dolzine n je rezultat pretvorbe prvih n-1 znakov krat 12 plus vrednost zadnje stevke.

convert("13A") -> convert("13") * 12 + A -> ((convert("1")) * 12 + 3) * 12 + A -> (1 * 12 + 3) * 12 + A

To je ocitno prav, saj je (1 * 12 + 3) * 12 + A drugace zapisano kar 1 * 12^2 + 3 * 12^1 + A * 12^0.

Torej 13A dvanajstisko je 144 + 36 + 10 = 190 desetisko.

MrStein ::

Se opravičujem, ampak ... naravno število? Katera šola je to?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

c# seminarska

Oddelek: Programiranje
112436 (2109) tuned
»

[C#] Operacija IN in ALI med dvema int številoma

Oddelek: Programiranje
111087 (900) LeQuack
»

[C#] Input string was not in a correct format.

Oddelek: Programiranje
6965 (902) Cvenemir
»

[C#] Reševanje domačih nalog

Oddelek: Programiranje
173049 (2553) krastača
»

[C#] razlaga

Oddelek: Programiranje
161530 (1247) krastača

Več podobnih tem