Nejste přihlášen/a.
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
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í.
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.
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.
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.
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
Č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.
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í
)
" 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.
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.