Nejste přihlášen/a.

Přihlásit se do poradny

 

Visual Basic - Select Sort

Od: lukasb* odpovědí: 12 změna:

Dobrý den,

chtěl jsem napsat program, který bude řadit čísla(konkrétně select sort) - částečně funguje, ale né úplně.
Můžete se prosím někdo podívat, kde je chyba?
Děkuji moc

Module Module1

Dim pole(10), pomocna, zacatek, od, doKolika, pole2(10), pomPole, pomocna2, pomCislo As Int64

Sub Main()

Console.Clear()

doKolika = 100

Randomize()

For i As Int64 = 1 To UBound(pole)

pole(i) = CInt(Rnd() * doKolika) vygenerovani cisel

Next

For i As Int64 = 1 To UBound(pole)

Console.WriteLine("Hodnota bunky " & i & ". je " & pole(i)) vypsani puvodnich hodnot

Next

od = 1

pomocna = doKolika - 1

For i As Int64 = 1 To UBound(pole)

For i2 As Int64 = od To UBound(pole) - 1

If pole(i2) < pole(i2 + 1) And pole(i2) < pomocna Then porovnávací algorytmus

pomocna = pole(i2)

End If

For i3 As Int64 = 1 To UBound(pole)

If pole(i3) = pomocna Then zjistí na kolikátém místě bylo nejmenší číslo

pomCislo = i3

End If

Next

Next

pomocna2 = pole(i)

pole(i) = pomocna prohodí nemenší číslo na první, druhou třetí ... pozici

pole(pomCislo) = pomocna2

od = od + 1

pomocna = doKolika + 1

Next

Console.WriteLine()

For i As Int64 = 1 To UBound(pole)

Console.WriteLine("Hodnota bunky po seřezení " & i & ". je " & pole(i)) vypíše nově seřazená čísla

Next

Console.ReadLine()

Main()

End Sub

End Module

 

 

12 odpovědí na otázku
Řazeno dle hodnocení

 

 

hm*
hodnocení

2x

VB neumím, ale přesto mi zapsaný algoritmus připadá hodně neefektivní.

Otázka: Co když bude nejmenší číslo poslední? Mám dojem, že ho algoritmus nenajde, protože porovnává vždy

If pole(i2) < pole(i2 + 1) And ...

a pak případně udělá

pomocna = pole(i2).

Takže když bude to nejmenší až pole(i2 + 1), podmínka se nesplní a "pomocna" se nenastaví.

Pro příště by bylo dobré napsat sem i výpisy pole před rovnáním a po rovnání.

 

dzordz*
hodnocení

0x

Cyklus For i3.. je naprosto zbytečný. Proč to takhle vyhledáváte? Přece když porovnáte dvě čísla, tak víte, kde jste vzal první a kde jste vzal druhé. Dáte jedno do pomocné proměnné, první číslo přepíšete druhým, druhé číslo přepíšete pomocnou.

Ta dvojitá podmínka (s And) je taky nějaká překombinovaná.

A možná někde budou špatně hranice cyklů nebo polí, jak říká Hm.

Kouknul bych na ten algoritmus na wiki a pak ho jednoduše přepsal do VB.

 

lui*
hodnocení

0x

Jestli tomu dobře rozumím, má jít o bublinkové třídění.

První cyklus

nulovat ukazatel BYLOTŘÍDĚNÍ

druhý cyklus

kontroluje celý cyklus tedy POLE1 TO POLEx

třetí cyklus

porovnává POLEhodnota < POLE hodnata+1

platí-li potom NEXT TŘETÍ CYKLUS

neplatí-li

vyměnit POLEhodnota a POLEhodnota+1 třeba přes pomocnou proměnnou

nastavit ukazatel BYLOTŘÍDĚNÍ

NEXT TŘETÍ CYKLUS

NEXT DRUHÝ CYKLUS

NEXT PRVNÍ CYKLUS

doplněno 24.12.11 16:39:

Zapomněl jsem na kontrolu mezi druhý a třetí NEXT musí přijít kontrola na nastavený ukazatel jestli bylo třídění. Pokud proběhl celý cyklus bez třídění tak se ukončí, jinak znovu třídit.

dzordz*

Bubble sort porovnává vedlejší prvky, pokud je větší za menším, prohodí je. Jezdí tak dlouho, než dostane správné pořadí.

Select sort projde rozsah 1-n, najde nejmenší, vymění ho na první pozici; ve druhém kroku projde 2-n, najde nejmenší, vymění ho s prvním (tedy druhá pozice celkem), pak projde 3-n atd.

lui*

Ano tak to jde samozřejmě taky a je to rychlejší, ale to není bublinkové třídění. Krása a jednoduchost bublinkového třídění spočívá v možnosti použít dvě až tři vnořené smyčky a minimum řádků programu. Bohužel při větším množství čísel je asi nejpomalejší. To je daň za jednoduchost.

 

lukasb*
hodnocení

Nějak zjednodušit to asi pude ..
Ae já to beru tak že, první 2 cykly najdou vždy nejmenší číslo v poli a třetí zjistí na kolikátém místě prohazovaná proměná byla.Bohužel to zjednodušit neumím, ale částečně jsem uplravil a nyní již správně řadí. Ale zas je tu ještě jeden problém s to s pomocnou na posledním nebo předposlením místě. Někdy se stane, že vypíše na 9. nebo 10. pozici číslo 101 tj. hodnota vždy proměné ...(přitom by vždy měl vzít menší číslo - proměná je nastavená tak, aby vždy byla větší než nejvyšší prvek v poli )
Upravení:

Module Module1

Dim pole(10), pomocna, zacatek, od, doKolika, pole2(10), pomPole, pomocna2, pomCislo As Int64

Sub Main()

Console.Clear()

doKolika = 100

Randomize()

For i As Int64 = 1 To UBound(pole)

pole(i) = CInt(Rnd() * doKolika) vygenerovani cisel

Next

For i As Int64 = 1 To UBound(pole)

Console.WriteLine("Hodnota bunky " & i & ". je " & pole(i)) vypsani puvodnich hodnot

Next

zacatek = UBound(pole)

od = 1

pomocna = doKolika - 1

For i As Int64 = 1 To UBound(pole)

For i2 As Int64 = od To UBound(pole) - 1

If pole(i2) < pole(i2 + 1) And pole(i2) < pomocna Then porovnávací algorytmus

pomocna = pole(i2)

End If

If pole(i2) > pole(i2 + 1) And pole(i2 + 1) < pomocna Then porovnávací algorytmus

pomocna = pole(i2 + 1)

End If

If pole(i2) = pole(i2 + 1) Then porovnávací algorytmus

pomocna = pole(i2 + 1)

End If

For i3 As Int64 = 1 To UBound(pole)

If pole(i3) = pomocna Then zjistí na kolikátém místě bylo nejmenší číslo

pomCislo = i3

End If

Next

Next

pomocna2 = pole(i)

pole(i) = pomocna prohodí nemenší číslo na první, druhou třetí ... pozici

pole(pomCislo) = pomocna2

od = od + 1

pomocna = doKolika + 1

Console.WriteLine()

For i4 As Int64 = 1 To UBound(pole)

Console.WriteLine("Hodnota bunky po seřezení " & i4 & ". je " & pole(i4)) vypíše nově seřazená čísla

Next

Next

Console.WriteLine()

For i As Int64 = 1 To UBound(pole)

Console.WriteLine("Hodnota bunky po seřezení " & i & ". je " & pole(i)) vypíše nově seřazená čísla

Next

Console.ReadLine()

Main()

End Sub

End Module

hm*

Člověče, už to trochu zcivilizuj. Začíná to být zamotané a blbě se v tom orientuje.

Opravdu to řadí dobře? Řádky

If pole(i2) = pole(i2 + 1) Then porovnávací algorytmus
pomocna = pole(i2 + 1)
End If

bez podmínky "And pole(i2) < pomocna", kterou jsi tam vynechal, ti, podle mne, vždy přepíšou "pomocna". Tzn. když budeš mít ve vstupní posloupnosti za sebou 2 stejné hodnoty, tak se ti na nich vždy zapomene (resp. přepíše) "pomocna", bez ohledu na jejich velikost. To za prvé.

A za druhé jedeš hlavní cyklus a v něm vnořený

For i As Int64 = 1 To UBound(pole)
For i2 As Int64 = od To UBound(pole) - 1

kde i2 začíná na "od", ovšem "od" vlastně kopíruje "i". Při posledním cyklu i=10 se vnořený cyklus už pravděpodobně nevykoná (protože i2 by začínalo 10 ale má jet jen do 9), takže se celý "for i2" až k jeho nextu přeskočí a dojede se jen

pomocna2 = pole(i)
pole(i) = pomocna prohodí nemenší číslo na první, druhou třetí ... pozici
pole(pomCislo) = pomocna2

takže (teď pozorně sleduj): do pomocna2 se dá pole(10), do pole(10) se dá 101 (protože "pomocna" se nezměnila, když se cyklus i2 nevykonával) a nakonec se do pole(pomCislo) dá původní hodnota z pole(10). A teď záleží, kam zůstala nastavená pomCislo z posledního projetého cyklu for i2 a kam se tedy zapíše původní hodnota pole(10). Možná zpátky do pole(10), možná do pole(9) a v pole(10) tak zůstane 101.

Uf. Ale jak by se dostala 101 do pole(9), to teda nevidím. Jo a příště pošli i tu vstupní a výstupní posloupnost, jak jsem už psal.

lukasb*
hodnocení

Ano. Mockrát děkuji!
Nyní už funguje :) Šlo o tom(jak jste psal), že jel jen do 9 a nevykonal ten 10.cyklus ...
Nyní funguje,ale opět za cenu dalších podmínek - pro tu 10. otáčku(
Ještě se na to podívám - také bych to rád zjednodušil - aleprostě zatím jsem jen začátečník :( a nějak se začít musí :))

hm*
Za cenu dalších podmínek? Jakých? Co kdyby se prostě desátý cyklus "for i" vynechal, když už stejně nic nedělá?
For i As Int64 = od To UBound(pole) - 1
doplněno 25.12.11 21:44: eee ... blbě, správně má být
For i As Int64 = 1 To UBound(pole) - 1
To první s "od" sice taky bude nejspíš fungovat, ale je to špatně.
dzordz*

" první 2 cykly najdou vždy nejmenší číslo v poli a třetí zjistí na kolikátém místě prohazovaná proměná byla"

Tomuhle pořád nerozumím. Když něco najdete, tak to přece už máte a nemusíte to hledat znova! Příklad: For (i=1;i<5;i++){if (i = 3){...=i;}} Když při průběhu cyklem je podmínka splněna a skočí vám to dovnitř ifu, tak si jenom zkopírujete aktuální hodnotu řídícího indexu cyklu, u vás asi to i2.

Druhá věc, což už jsem taky říkal - nemá smysl vymýšlet něco od znova a řadící algoritmy už vůbec ne. Kouknete na cs.wikipedia.org/... nebo si najdete vhodný a srozumitelný pseudokód někde jinde, přepíšete ho do VB a máte hotovo, práce na tři minuty.

lukasb*
hodnocení

To určitě ano!
Ale u mě je problém, že nerozumím všem příkazům v "céčku" nebo Javě - tj. něco je podobné nebo stejné, ale něco prostě nevím a proto nemůžu jen otevřít wikipedii a za 3 min to přepsat :(

 

hm*
hodnocení

0x

Jen pro zajímavost:


:)

 

 


 

 

 

Přihlásit se k odběru odpovědí z této otázky:

Neneseme odpovědnost za správnost informací a za škodu vzniklou jejich využitím. Jednotlivé odpovědi vyjadřují názory jejich autorů a nemusí se shodovat s názorem provozovatele poradny Poradte.cz.

Používáním poradny vyjadřujete souhlas s personifikovanou reklamou, která pomáhá financovat tento server, děkujeme.

Copyright © 2004-2025 Poradna Poradte.cz. Všechna práva vyhrazena. Prohlášení o ochraně osobních údajů. | [tmavý motiv]