» »

[c#] Vstavljanje vrednosti v tabelo

[c#] Vstavljanje vrednosti v tabelo

Cvenemir ::

Lp, izdelati moram metodo, ki vstavi podano vrednost na podan indeks v tabeli.
Poskusil sem z naslednjo kodo, vendar mi test vedno javi napako, češ da elementa ni v polju.

Metoda:
public static double[] Vstavi(double[] tabela, int indeks, double vrednost)
        {
            if (indeks < 0 || indeks >= tabela.Length)
            {               
                return null;
            }
            else
            {
                tabela[indeks] = vrednost;
                return tabela;               
            }
        }


Testna koda:
int velikost = 5;
double[] arr0 = new double[velikost];
if (null == Tabela.Vstavi(arr0, 6, 0))
                Console.WriteLine("Napaka pri vstavljanju! ");

Kje sem naredil napako?

P3Hi ::

Kje sem naredil napako?

...(arr0, 6, 0).. ? Na mesto 7(index 6) v tabeli velikosti 5 zapisuješ vrednost 0.

Zgodovina sprememb…

  • spremenil: P3Hi ()

Cvenemir ::

Sej zato se mi je pa čudno zdelo. Testno kodo je napisal profesor. Ne vem, če se je zmotil ali kaj... Ampak recimo da mora biti tako kot je napisano. A se da naprimer napisat kodo, ki bi tabelo ustrezno povečala, se pravi v tem primeru na 7?

Nevermind. problem rešen. hvala za pomoč

Zgodovina sprememb…

  • spremenil: Cvenemir ()

P3Hi ::

public static double[] Vstavi(double[] tabela, int indeks, double vrednost)
{
	int velikostTabele = tabela.Length;
	if(indeks >= velikostTabele) // tabela je premajhna
	{
		int novaVelikost = tabela.Length+(indeks-tabela.Length);
		double zacasnaTabela = new double[novaVelikost]
		for(int i = 0;i < velikostTabele-1; i++) // grem, čez staro polje in prepišem v novo
			zacasnaTabela[i] = tabela[i];
		zacasnaTabela[indeks] = vrednost; // dodam vrednost v novo, večje polje
		return zacasnaTabela; // vrnem večjo tabelo, z starimi in novo vrednostjo
	}
    else if (indeks < 0 /*|| indeks >= tabela.Length*/)         
	{
		return null;
	}
    else // če ne vstaljam na index večji od velikost
    {
		tabela[indeks] = vrednost;
		return tabela;              
    }
}

int velikost = 5;
double[] arr0 = new double[velikost];
if (null == Tabela.Vstavi(arr0, 6, 0))
	Console.WriteLine("Napaka pri vstavljanju! ");

Spura ::

To je narobe:
      int novaVelikost = tabela.Length+(indeks-tabela.Length);
Kompliciras po nepotrebnem. Rabis tabelo, ki je dovolj velika za ta indeks.
int novaVelikost = indeks + 1;

Taka koda je najbolj zanesljiva. Ker si kompliciral si se zmotil. Pri tvoji kodi se v formuli tabela.Length in -tabela.Length pokrajsata.
Tvoja koda je torej ekvivalentna temu:
      int novaVelikost = indeks;

Kar ne bo delalo. Off by one.
Tole je tut pomojem napacno, ker v novo tabelo ne preprises zadnjega podatka v prejsnji tabeli:
for(int i = 0;i < velikostTabele-1; i++)


Nasplosno bi se dalo kodo ful bolj preprosto in bugfree naredit:

public static double[] Vstavi(double[] tabela, int indeks, double vrednost)
{
    if(indeks >= tabela.Length) // tabela je premajhna
    {
        double novaTabela = new double[indeks + 1];
        for(int i = 0;i < tabela.Length; i++) // grem, čez staro polje in prepišem v novo
            novaTabela[i] = tabela[i];
        novaTabela[indeks] = vrednost; // dodam vrednost v novo, večje polje
        return novaTabela; // vrnem večjo tabelo, z starimi in novo vrednostjo
    }
    else if (indeks < 0 /*|| indeks >= tabela.Length*/)        
    {
        return null;
    }
    else // če ne vstaljam na index večji od velikost
    {
        tabela[indeks] = vrednost;
        return tabela;             
    }
}

Pa v splosnem se pri indeksu manj kot nic mece runtime exceptione, ne pa null vraca.

Cvenemir ::

Hvala za pomoč. Imam še eno drobno vprašanje. Pri naslednji kodi imam v vrstici 134 test za metodo Vrni(), ki bi naj v primeru, da je indeks < 0 ali > od tabela.Lenght vrnila napako NaN. Tabela arr0 je velikosti 5, v testu pa skušam vrniti podatek na indeksu 12, kar bi moralo vrniti NaN. Pomoje je napaka v if stavku, kjer primerjam 23. indeks z double.NaN, čeprav ta indeks ne obstaja.

Kako naj prilagodim test, da preverim, če metoda v primeru napake res vrne NaN?

Aja, pa še tole: Kako naj v metodi Vstavi() - vrstica 87 - vrnem napako NaN, če je metoda tipa double[]. P.S. Definicij metod ne smem spreminjati, samo notranjost.

Celotna koda:


/*
 *  PROSTOR ZA GLAVO
 * (ime in priimek avtorja, vpisna stevilka, besedilo naloge)
--- --- --- --- --- --- ---
 * <ime_datoteke>.<koncnica>
 *
 *       Ustvarjeno: 8.3.2012
 *            Avtor: 
 *  Vpisna stevilka: 
 *  Besedilo naloge:
 *  Implementirajte podatkovno strukturo ,,tabela", kot ste jo spoznali na predavanjih.
 *  V imenskem prostoru [vV]aja2 (C++: vaja2, C#: Vaja2) zagotovite in implementirajte metode:
 *  C#:
 *  Pr ip r a v i ( )
 *  Vrni ( )
 *  Vs t av i ( )
 *  Delovanje metod naj ustreza definiciji ,,tabele", kot ste jo spoznali na predavanjih. Za
 *  signaliziranje napake uporabite vrednost NaN (Not-a-Number). Pomeni, da kadar po
 *  definiciji tabele metoda mora javiti napako, vrnite vrednost NaN
 */

//definicija imenskega prostora(/podrocja)
namespace Vaja2
{
    //uporabljene knjižnice
    using System;

    //razredi
    public class Tabela
    {
        /// <summary>
        /// Metoda kliče metodo Pripravi(tabela, velikost)
        /// </summary>
        /// <param name="tabela"></param>
        /// <returns></returns>
        public static double[] Pripravi(double[] tabela)
        {
            return Pripravi(tabela, tabela.Length);
        }
        /// <summary>
        /// Metoda pripravi izbrise vse podatke v tabeli
        /// </summary>
        /// <param name="tabela">Vhod: tabela podatkov</param>
        /// <param name="velikost">Vhod: velikost tabele</param>
        /// <returns>Vrne: tabelo</returns>
        public static double[] Pripravi(double[] tabela, int velikost)
        {            
            velikost = tabela.Length;  
                                           
            for (int i = 0; i < velikost; i++)
            {
            tabela[i] = double.NaN;
            }
                    
            return tabela;                     
        }
        /// <summary>
        /// Metoda vrne podatek
        /// </summary>
        /// <param name="tabela">Vhod: tabela podatkov</param>
        /// <param name="indeks">Izhod: </param>
        /// <returns>Vrne: Če pride do napake vrne NaN,
        /// drugače vrne podatek</returns>
        public static double Vrni(double[] tabela, int indeks)
        {
            if (indeks < 0 || indeks >= tabela.Length)
            {
                double notANumber = double.NaN;
                return notANumber;//Vrne NaN v primeru napake
            }
            else
            {
                return tabela[indeks];
            }


            //return -1;
        }
        /// <summary>
        /// Metoda vstavi vrednost v tabelo na mestu indeks
        /// </summary>
        /// <param name="tabela">Vhod: tabela podatkov</param>
        /// <param name="indeks"></param>
        /// <param name="vrednost">Vhod: vrednost, ki jo želimo vstaviti</param>
        /// <returns>Vrne: v primeru napake vrne NaN</returns>
        public static double[] Vstavi(double[] tabela, int indeks, double vrednost)
        {
            if (indeks < 0 || indeks >= tabela.Length)
            {
                //double notANumber = double.NaN;
                //return notANumber;
                return null;
            }
            else
            {
                tabela[indeks] = vrednost;
                return tabela;               
            }
        }
    }

    public class Test
    {
        //glavna metoda
        public static void Main(string[] args)
        {
            //test Pripravi()!=NULL
            int velikost = 5;
            double[] arr0 = new double[velikost];
            if (null == Tabela.Pripravi(arr0))
            {
                Console.WriteLine("Pripravi() vrne NULL\n");
            }
            //test Vrni() prav vrne
            double[] arr1 = { -3.0, 4, 2 };
            if (4 != Tabela.Vrni(arr1, 1))
            {
                Console.WriteLine("Vrni() ne vrne pravega elementa\n");
            }

            //test Vstavi()!=NULL          
            if (null == Tabela.Vstavi(arr0, 6, -6))
            {
                Console.WriteLine("Napaka pri vstavljanju!\n ");
            }

            //preveri, da metoda Vrni() resnično vrača pravilen element/vrednost            
            if (-3 == Tabela.Vrni(arr1, 0))
            {
                Console.WriteLine("Metoda vrni vrača pravilen element.\n ");
            }

            //preveri, da metoda Vrni() za novo pripravljeno polje res vrne NaN  
            if (double.NaN == Tabela.Vrni(arr0, 12))
            {
                Console.WriteLine("Metoda 'Vrni' v primeru napake vrne NaN: ---> {0}\n", Tabela.Vrni(arr0, 23));
            }

            //preveri, da metoda Vstavi() pravilno vstavi podano vrednost na pravo mesto
            Tabela.Vstavi(arr0, 2, 8);
            if (8 == Tabela.Vrni(arr0, 2))
            {
                Console.WriteLine("Metoda 'Vstavi' pravilno vstavi vrednost na pravo mesto\n ");
            }

            //preveri, da metoda Vrni() iz j-tega mesta, takoj po vstavljanju podane vrednosti
            //na i-to mesto, vrne vstavljeno vrednost, če je i==j, oz. vrne vrednost na j-tem
            //mestu v tabeli                 
            Console.WriteLine("Vrednost na j-tem mestu je: {0}\n ", Tabela.Vrni(arr1, 0));
            Console.ReadKey(true);
        }
    }
}
//na koncu prazna vrstica

Zgodovina sprememb…

  • spremenil: Cvenemir ()

Spura ::

Ne. Napaka je v if stavku.
if (double.NaN == Tabela.Vrni(arr0, 12))

double.NaN == double.NaN je false. Torej tudi ce ti funkcija vrne NaN bo ta if stavek false. Definicija NaN je to, da ni enako nicemur.
Lahko bi preprosto takole resil.
            double rezultat = Tabela.Vrni(arr0, 12);
            //preveri, da metoda Vrni() za novo pripravljeno polje res vrne NaN 
            if (rezultat != rezultat)
            {
                Console.WriteLine("Metoda 'Vrni' v primeru napake vrne NaN: ---> {0}\n", Tabela.Vrni(arr0, 23));
            }

In najbrz obstaja kaksna isNaN funkcija na kakem Double ali pa Math classu.
Sicer ne vem kdo se je vracanja NaN spomnil, ampak to je semanticno napacna resitev, pravilno bi bilo metanje IndexOutOfRangeException.
Teli profesorji/asistenti majo vcasih dost bizarne programe.

Edit: evo kot sem predvideval:

http://msdn.microsoft.com/en-us/library...

To uporabi, bo najbolj prav.

Zgodovina sprememb…

  • spremenil: Spura ()

Cvenemir ::

Sem upošteval tvoj nasvet, sedaj test pravilno deluje. Kar pa se tiče metode Vstavi(), pa smo po krajšem posvetu s profesorjem prišli do zaključka, da naj metoda v primeru napake vrne nespremenjeno tabelo.

Eno vprašanje še glede metode Pripravi()
public static double[] Pripravi(double[] tabela, int velikost)
        {            
            velikost = tabela.Length;  
                                           
            for (int i = 0; i < velikost; i++)
            {
            tabela[i] = double.NaN;
            }
                    
            return tabela;                     
        }

Metoda bi naj v vsakem primeru inicializirala novo polje, katerega velikost podamo s parametrom "int velikost". Je to pravilna rešitev?

Spura ::

ce je tale komentar merodajen:
/// Metoda pripravi izbrise vse podatke v tabeli

Potem je najboljsa implementacija:
public static double[] Pripravi(double[] tabela)
        {            
            Array.Clear(tabela,0,tabela.Length);
            return tabela;                     
        }

Oziroma ce hoces met NaN v polju potem for stavek.
Na splosno je, ce ni eksplicitno zahtevan nov array, najhitreje povozit starega.
Parameter velikost je odvec ce ne mislis spreminjat velikosti arraya.

Povej bolj specificno kaj je zahtevana funkcionalnost metode.

Zgodovina sprememb…

  • spremenil: Spura ()

Cvenemir ::

Funkcionalnost metode Pripravi() zahteva, da inicializiramo novo tabelo, katere velikost je podana s parametrom "int velikost". Tabela naj bo prazna oz. v tem primeru zapolnjena z vrednostmi "double.NaN". Kako velika mora biti tabela pa ni nikjer napisano.

Spura ::

Potem pa ne rabis parametra double[].
public static double[] Pripravi(int velikost)
{
    double[] ret = new double[velikost];
    for(int i = 0;i < velikost;i++)
    {
        ret[i] = double.NaN;
    }
    return ret;
}

Cvenemir ::

Parametrov metod ne smemo spreminjat. Tak da mi zdej sploh ni več jasno, ka bi radi od nas.


Vredno ogleda ...

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

Java passing

Oddelek: Programiranje
203622 (3275) mihibo5
»

Pomoč pri programiranju z javo

Oddelek: Programiranje
203568 (2495) milc
»

[C#] Reševanje domačih nalog

Oddelek: Programiranje
173283 (2787) krastača
»

C# (strani: 1 2 )

Oddelek: Programiranje
9712094 (8929) Ericssony
»

[C#] izdelava tabele

Oddelek: Programiranje
71998 (1824) majoneza

Več podobnih tem