Diskuze: Jak vypsat vsechna prvocisla od 1 do 1000?
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


DarkCoder:6.6.2020 0:24
Proč to odněkud přepisovat, když si to můžeš sám napsat. Celé to navíc lze poskládat z naprosto běžných řídících příkazů. Zde je pro jednoduchost ukázka bez použití optimalizací.
#include <stdio.h>
#define MIN 1
#define MAX 1000
int main(void){
for (int num = MIN; num <= MAX; num++){
int isPrime = 1;
for (int i = 2; i <= num / 2; i++){
if (num % i == 0){
isPrime = 0;
break;
}
}
if (isPrime && (num > 1)) printf("%d ", num);
}
return 0;
}
+20 Zkušeností
+2,50 Kč

David Flieger:6.6.2020 7:43
Chybu máš ve vnořeném cyklu s iterační proměnnou j. V něm přiřadíš všem číslům větším, nebo rovno 2*i nulu. Já bych to zkusil přepsat takto:
For j = 2 To cisla.Length / i
cisla(i * j) = 0
Next
Tohle by mělo přiřadit nulu všem přirozeným násobkům nalezeného prvočísla i.
Další věc není chyba, ale způsob jak se vyhnout zbytečným řadkům. Jak máš
If cisla(i) = 0
Continue For
End If
Tak bych změnil podmínku na cisla(i)=1 a v těle bych nechal ten for cyklus s iterační proměnnou j.
Ondrej Zadrapa:6.6.2020 10:16
Sub Main()
Dim min(1) As Integer, max(1000) As Integer
For num = min.Length To max.Length - 1
Dim prvocislo As Integer = 1
For i = 2 To num / 2
If num Mod i = 0 Then
prvocislo = 0
End If
If prvocislo + num > 1 Then
Console.Write(num & " ")
End If
Next
Next
Console.ReadKey()
Nevim si s tim rady, VB nemá break, navíc mi to v mem podani vypise uplne všechny cisla.
DarkCoder:6.6.2020 12:00
MIN a MAX jsou makra. Nahlížej na to jako na celočíselné konstanty. Není to pole, nemá žádnou délku, pouze hodnotu. Jednoduše na místo kde se nachází MIN a MAX se dosadí místo toho adekvátní hodnota.
řádek:
for (int num = MIN; num <= MAX; num++){
odpovídá:
for (int num = 1; num <= 1000; num++){
Znovu podotýkám, jsou to prosté celočíselné konstanty. Proto v žádném případě přepis do VB nemůže být následující:
For num = min.Length To max.Length - 1
Mělo by to být něco v tomto smyslu:
For num As Integer = 1 To 1000
VB má pro ukončení z cyklů jiný příkaz, ale má. Ve VB se pro ukončení cyklu For používá:
Exit For
Pro další ukončovací příkazy
Nakonec podmínka výpisu prvočísla je tvořena logickým součinem
if (isPrime && (num > 1)) printf("%d ", num);
Kdežto ve tvém případě se jedná o součet dvou celočíselných operandů
If prvocislo + num > 1 Then
Je třeba užít logický součin
AND
Ondrej Zadrapa:6.6.2020 14:03
Sub Main()
For num = 1 To 100
Dim prvocislo As Integer = 1
For i = 2 To Math.Sqrt(num)
If num Mod i = 0 Then
Exit For
End If
If prvocislo And num > 1 Then
Console.Write(num & " ")
End If
Next
Console.WriteLine()
Next
Console.ReadKey()
Vypise to od 5ky všechny cisla o 2 vetsi az do 1000, cisla se opakuji, nevim proc, nerozumim tomu.
DarkCoder:6.6.2020 14:09
Vypisuješ čísla na nesprávném místě, je třeba vypisovat mimo for cyklus. Dále ti chybí nastavování převodovka na 0.
Ondrej Zadrapa:6.6.2020 14:21
Fu, teda, je to fuska, ale uz to dela, co ma, diky.
Ondrej Zadrapa:6.6.2020 14:36
Prosim Te, mam vypsat 10 radku, kdy na prvním radku bude 1, na druhem 12, na tretim 123. Mam k tomu vyuzit vnorenou smycku. Co si z toho mam vyvodit, ze po me profesor chce? Z toho jsem uplne jelen.
DarkCoder:6.6.2020 14:45
Proč fuška? Stačí vědět co který úsek programu dělá a znát možnosti jazyka a umět je využít. Výpis prvočísla mimo cyklus musel být proto, aby se před tím dalo zjistit, zda skutečně prvočíslem je. Bylo třeba zapotřebí provést X iterací. Buď všechny kdy číslo je prvočíslem nebo zkráceně pomocí Exit For kdy číslo není prvočíslem neboť se našel dělitel beze zbytku a další iterace jsou už tak zbytečné.
DarkCoder:6.6.2020 14:48
Chce po tobě cyklus uvnitř cyklu (konkrétně for uvnitř for), podobně jako by si vypisoval 2D pole. U prvního cyklu určuje řídící proměnná konkrétní řádek, u druhého cyklu určuje řídící proměnná aktuálně vypisované číslo.
Ondrej Zadrapa:6.6.2020 14:57
Sub Main()
For i As Integer = 1 To 10
For j As Integer = 1 To 10
Console.Write(j & " ")
Next
Console.WriteLine()
Next
Console.ReadKey()
End Sub
Cili něco takového ano? Jdu spravnym smerem?
DarkCoder:6.6.2020 15:00
Jdeš správným směrem, ale rozsah druhého cyklu závisí na řídící proměnné prvního cyklu. Takto Ti to vypíše tabulku, která ale není v souladu se zadáním. Nemůžeš vypisovat 10 hodnot pro první řádek když máš vypsat pouze jednu hodnotu.
#include <stdio.h>
#define ROWS 10
int main(void) {
for (int i = 1; i <= ROWS; i++) {
for (int j = 1; j <= i; j++) printf("%d", j);
putchar('\n');
}
return 0;
}
Ondrej Zadrapa:6.6.2020 15:06
Sub Main()
For i As Integer = 1 To 10
For j As Integer = 1 To i
Console.Write(j & " ")
Next
Console.WriteLine()
Next
Console.ReadKey()
End Sub
A vystup je
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
Co zas delam spatne?
DarkCoder:6.6.2020 15:08
Nyní to máš správně, tohle se po tobě chce. Zda má být mezera mezi čísly či nikoli je už jen otázkou formátování.
Ondrej Zadrapa:6.6.2020 15:09
Jo tak, ty blaho, ja jsem fakt kokot, to zadani je zavadejici, ja to bral
jako cela cisla.
No do prcic, Ti ucitele mají
smysl pro humor.
DarkCoder:6.6.2020 15:13
Ne? já bych řekl že jo... Jestli to chceš mít přesně tak vypisuj samotnou proměnnou j bez mezery, jak už jsem zde výše napsal. K tomu už nelze víc dodat..
Ondrej Zadrapa:6.6.2020 15:20
Ne, všechno v pohode, to jenom me nenapadlo, ze kdy je napsane 1, potom 12, potom 123, tak je to na jeden radek 1, další radek 1,2, ten další 1,2,3, atd...
DarkCoder:6.6.2020 15:40
To už jsou detaily. Je ovšem třeba být důsledný a řídit se přesně tím co je napsáno. Zde to nevadí, ale jsou programy které využívají jako vstup výstup jiného programu a tam už si nemůžeš dovolit upravovat výstup dle libosti.
Tři hlavní body:
- Umět pochopit zadání a řídit se tím co se požaduje.
- Umět si v hlavě dokázat představit způsob jak to řešit.
- Umět si v hlavě dokázat sestavit a vidět výsledný zdrojový kód.
Ondrej Zadrapa:6.6.2020 17:48
Tak jsem se dostal k dvojrozměrnému poli a chtěl bych se zeptat, jak muzu zobrazit radkove a sloupcove indexy bunek, na kterých se minimum nachazi? Nebo jinak, splnil jsem úkol podle zadani, nebo jsem proste akorát vypsal, kde se to minimum nachazi? Placnu, ze místo toho mělo byt, ze se nachazi 2 indexu 3 radku a na 3 indexu 2 sloupce.
Sub Main()
Dim pole(,) As Integer = {
{6, 8, 6, 4},
{5, 15, 7, 8},
{9, 3, 11, 12},
{13, 14, 15, 16}
}
Dim minimum As Integer = pole(0, 0)
Dim poradiI As Byte = 0
Dim poradiJ As Byte = 0
For i = 0 To pole.GetLength(0) - 1
For j = 0 To pole.GetLength(1) - 1
Console.Write(pole(i, j) & " ")
If pole(i, j) < minimum Then
minimum = pole(i, j)
poradiI = i + 1
poradiJ = j + 1
End If
Next
Console.WriteLine()
Next
Console.WriteLine("Minimum: {0} nalezneme v {1}. radku a {2}. sloupci", minimum, poradiI, poradiJ)
Console.ReadKey()
End Sub
DarkCoder:6.6.2020 18:08
Pozice v 2D poli je jasně daná. Pokud např. minimum bude na pozici pole[1,2], pak říkáme, že X index má hodnotu 1, Y index má hodnotu 2. Je to totéž, jako bychom řekli že minimum se nachází na pozici řádku č. 2 a sloupce č. 3 (z důvodu toho že indexace pole začíná od nuly).
Od klasického 1D pole se to nijak neliší, je akorát přidán další rozměr. A interpretace 2D pole se vytváří vnořeným for cyklem do jiného for cyklu. Řídící proměnná vnějšího for představuje pozici řádku, řídící proměnná vnitřního for představuje pozici sloupce.
Ondrej Zadrapa:6.6.2020 19:51
Muzu se Te zeptat, jak docilim toho, abych dokazal vypsat pozice všech lokálních maxim v poli, cili kazde číslo, které vlevo i vpravo ma nižší hodnotu?
Sub Main()
Dim pole(,) As Integer = {
{10, 20, 3, 4},
{5, 16, 8, 6},
{4, 12, 25, 3},
{0, 18, 16, 2}
}
Dim maximum As Integer = pole(0, 0)
For i = 0 To pole.GetLength(0) - 1
For j = 0 To pole.GetLength(1) - 1
If pole(i, j) > maximum Then
maximum = pole(i, j)
Dim poradi1 = i
Dim poradi2 = j
Console.WriteLine("Cislo {0} na pozici ({1},{2})", maximum, poradi1, poradi2)
End If
Next
Next
Console.ReadKey()
Vypise mi to jen 2 cisla, jak to?
DarkCoder:6.6.2020 20:14
Pokud lpíš striktně na tom, že lokální maximum je dáno vyšší hodnotou nebo stejnou než na pozici vlevo a vpravo, pak to docílíš tak, že vezmeš druhý až předposlední prvek v poli a každý tento prvek porovnáš s hodnotou na indexu vlevo a vpravo. Pokud bude vyšší, pak se jedná o lokální maximum a hodnotu vypíšeš, v opačném případě se o lokální maximum nejedná a pokračuješ n další index. Pokud chceš zahrnout i možnost, že lokální maximum může být první a poslední prvek a jeho hodnota je vyšší než prvek následující u prvního a předcházející u posledního, pak je toto možné udělat také tak, že pro první index provedeš test, poté vnitřní indexy a nakonec poslední. Tyto testy můžeš udělat i po vnitřních testech, ale už nemáš seřazena maxima od začátku pole, respektivě si je musíš ukládat a až nakonec vypsat. To v případě, kdy provedeš test prvního, následovaný testy vnitřními a nakonec posledním, nemusíš. Můžeš maxima vypisovat "za letu".
DarkCoder:6.6.2020 20:32
Zde máš řešení pro určení lokálních maxim v 1D poli.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 20
int main(void) {
int nums[SIZE];
srand((unsigned int)(time(NULL)));
// naplneni pole nahodnymi hodnotami v rozsahu 0-99
for (int i = 0; i < SIZE; i++) nums[i] = rand() % 100;
// kontrolni vypis pole (hodnota a index)
for (int i = 0; i < SIZE; i++) printf("%d[%d] ", nums[i], i);
putchar('\n');
// test lokalniho maxima prvniho prvku
if(nums[0]>nums[1]) printf("%d[%d] ", nums[0], 0);
// test lokalniho maxima vnitrnich prvku
for (int i = 1; i < (SIZE - 2); i++) {
if ((nums[i] > nums[i - 1]) && (nums[i] > nums[i + 1])) {
printf("%d[%d] ", nums[i], i);
}
}
// test lokalniho maxima posledniho prvku
if (nums[SIZE-1] > nums[SIZE-2]) printf("%d[%d] ", nums[SIZE-1], SIZE-1);
return 0;
}
Výstup programu:
92[0] 64[1] 68[2] 29[3] 4[4] 83[5] 80[6] 21[7] 36[8] 33[9] 26[10] 11[11] 41[12] 34[13] 74[14] 57[15] 43[16] 70[17] 58[18] 91[19]
92[0] 68[2] 83[5] 36[8] 41[12] 74[14] 70[17] 91[19]
Ondrej Zadrapa:6.6.2020 20:41
No, zrejme Ti moc nerozumim, jak to myslis s temi prvky, něco jako:
If pole(0,1) And pole(2,2) > maximum Then
maximum = pole(i,j)
poradi1 = i
poradi2 = j
Ja v tom mam ted docela zmatek
DarkCoder:6.6.2020 21:16
Podívej se na příklad který jsem Ti napsal pro určení lokáních maxim v 1D poli. Podívej se jak je tam řešeno porovnání sousedních hodnot. Všimni si, že si nikam neukládám indexy ani hodnoty, vše vypisuji "za letu".
if ((nums[i] > nums[i - 1]) && (nums[i] > nums[i + 1])) {
printf("%d[%d] ", nums[i], i);
}
Slovy řečeno:
Je-li hodnota na indexu i větší nežli hodnota na indexu i-1 (předchozím) a
zároveň je-li hodnota na indexu i větší nežli hodnota na indexu i+1
(následujícím) pak vypiš hodnotu na indexu i jelikož se jedná o lokální
maximum.
If pole(0,1) And pole(2,2) > maximum Then
maximum = pole(i,j)
poradi1 = i
poradi2 = j
Úryvek kódu který si uvedl je v mnoha ohledech chybný.
První chybou je že hodnoty ve 2D poli vůbec spolu nesousedí, První hodnota je v prvním řádku, druhá hodnota je ve třetím řádku. Druhou chybou je že proměnná maximum žádná není, stačí Ti pracovat s hodnotami které jsou už uloženy v poli. Třetí chybou je že podmínka je nesmyslná. Je třeba si uvědomit s jakými hodnotami pracuješ a co je výsledek logických hodnot. Samotné pole(0,1) představuje hodnotu kterou ale s ničím neporovnáváš. Výsledek logického součinu je buď 0 nebo 1 a to porovnávat s nějakým maximem je nesmyslné.
DarkCoder:6.6.2020 21:33
Dám Ti jednu otázku, zkus mi na ni co nejpřesněji odpovědět.
// test lokalniho maxima vnitrnich prvku
for (int i = 1; i < (SIZE - 2); i++) {
if ((nums[i] > nums[i - 1]) && (nums[i] > nums[i + 1])) {
printf("%d[%d] ", nums[i], i);
}
}
Otázka:
Zdůvodni, proč jsem ve výše uvedeném úryvku kódu použil indexy 1 a
SIZE-2 pro rozsah cyklu for.
Ondrej Zadrapa:6.6.2020 21:41
Kvuli druhemu az předposlednímu prvku?
DarkCoder:6.6.2020 22:08
Indexy s čísly 1 a SIZE-2 představují druhý a předposlední prvek, to ano. Ale proč jsem zvolil právě tyto hodnoty, proč ne třeba 0 a SIZE-1? Chci znát důvod. Respektivě dva které spolu úzce souvisí.
Ondrej Zadrapa:6.6.2020 22:15
Protože první a poslední prvek jsi vypsal zvlast? Ja vazne netusim, nechtej po me teorii, kterou bych si strasne rad precetl, ted koukam do skrypt, na vicerozmerna pole a nejsem o nic moudrejsi, co to jsou vicerozmerna pole, jak je setřídit, vic jsem z toho nevycetl, cili pokud Te ma odpověď neuspokoji, tak je mi lito.
DarkCoder:6.6.2020 22:35
Smyslem mé otázky není to že po tobě chci teorii, ta s ní ani nesouvisí, ale získání tvého logického uvážení a pochopení toho jak daný úsek programu funguje. Tím se naučíš snáze řešit problémy a budeš-li toto trénovat, pak i schopnost utvářet programy přímo v hlavě. Když teď napíši odpověď, bude Ti to jasné.
Očekával jsem následující odpověď:
Důvodem, proč byly pro for cyklus použity rozsahy 1 a SIZE-2 (tedy druhý a předposlední prvek) bylo to, že algoritmus uvnitř for pracuje s hodnotami na sousedních indexech (zleva a zprava). Pro první prvek neexistuje žádný soused zleva, pro poslední prvek neexistuje žádný prvek zprava. Výraz podmínky pro použitý index i-1 pro první prvek by vedl k chybě programu z důvodu neplatného rozsahu, stejně tak výraz podmínky pro použitý index i+1 pro poslední prvek by vedl k chybě programu z důvodu neplatného rozsahu. Nelze pracovat s indexy o hodnotách -1 a 20. Proto byly indexy pro cyklus for stanoveny na hodnoty 1 a SIZE-2 aby se dalo pracovat se sousedy všech prvků pokrývající rozsah cyklu for.
Algoritmus pro určení zda lokální maximum leží i na prvním a posledním prvku pole je jiný od vnitřních prvků. Proto bylo zjištění lokálního maxima pro první a poslední prvek odděleno. Aby bylo zachováno logické pořadí lokálních maxim, byl algoritmus pro určení lokálního maxima uveden před algoritmem zjistění lokálního maxima vnitřních prvků a jako poslední byl uveden algoritmus zjišťování maxima pro poslední prvek. Tím je zaručena souslednost lokálních maxim všech prvků pole.
DarkCoder:6.6.2020 22:52
Postupuj systematicky. S 2D polem se pracuje obdobně jako s 1D polem. Je tam akorát navíc jeden rozměr. To hlavní co musíš je pochopit, kdy a za jakých podmínek použít 2D pole. To si můžeš představit jako plochu něčeho (třeba stránka knihy, kde první index udává řádek a druhý index pozici znaku na řádce). Dále třeba využiješ 2D pole když si budeš chtít uchovat teplotu každého dne v roce. Znovu připomínám, důležité je se naučit proč zrovna použít 2D pole. 2D pole se v programování používají velmi často, jejich znalost je pro úspěšné programování bezpodmínečná. Důležité je si pomatovat, že první index udává počet řádků, druhý index počet sloupců. Začni tím že se naučíš jak deklarovat 2D pole, jak inicializovat 2D pole, jak přistupovat k danému prvku pole, jak přečíst hodnotu na konkrétní pozici, jak uložit hodnotu na konkrétní pozici. Jak načíst uživatelská data na konkrétní pozici, jak vypsat celé 2D pole, jak přečíst konkrétní řádek, jak přečíst konkrétní sloupec, jak vypsat hodnotu na konkrétní pozici a další. Naučíš-li se tyto elementární části, nebude Ti 2D pole činit sebemenší problém.
Ondrej Zadrapa:6.6.2020 23:42
Sub Main()
Dim pole(3, 3) As Integer, rnd As New Random
For i = 0 To 3
For j = 0 To 3
pole(i, j) = rnd.Next(100)
Next
Next
For i = 0 To pole.GetLength(0) - 1
For j = 0 To pole.GetLength(1) - 1
Console.Write("{0}({1},{2})", pole(i, j), i, j)
Next
Console.WriteLine()
Next
Console.WriteLine()
If pole(0, 0) > pole(0, 1) Then
Console.WriteLine("Lokalni maximum {0} na pozici({1},{2})", pole(0, 0), 0, 0)
End If
For i = 1 To pole.GetLength(0) - 2
For j = 1 To pole.GetLength(1) - 2
If pole(i, j) > pole(i - 1, j - 1) And pole(i, j) > pole(i + 1, j + 1) Then
Console.WriteLine("Lokalni maximum {0} na pozici({1},{2})", pole(i, j), i, j)
End If
Next
Next
If pole.GetLength(0) - 1 And pole.GetLength(1) - 1 > pole.GetLength(0) - 2 And pole.GetLength(1) - 2 Then
Console.WriteLine("Lokalni maximum {0} na pozici({1},{2})", pole.GetLength(0) - 1 And pole.GetLength(1) - 1, pole.GetLength(0) - 1, pole.GetLength(1) - 1)
End If
Console.ReadKey()
End Sub
Nez na to něco reknes, tak jsem zkusil nejprve vytvořit stejny program s 1D polem a když jsem zjistil, ze funguje bezchybne, tak jsem se pokusil opravdu jenom postupne nejprve vnorit jeden cyklus navíc, zmenil jsem počet promennych tak, aby si to sedelo a vyzkousel jsem to tak, jak jsem zatím pochopil, ze to ma fungovat. Jelikoz každý cyklus vraci dimenzi 0 a 1, radek a sloupec, tak jsem to takhle zkusil vytvořit, no nevypada to, ze by to fungovalo jak by mělo, uz me to alespoň neposila do pryc, ze mam index mimo pole. Navíc ucit se něco o pul noci není moc dobry napad. Ale uz jsem alespoň vykrocil spravnym smerem?
DarkCoder:7.6.2020 0:35
Jdeš správným směrem, je tam několik chyb ale nic co by se nedalo vyřešit. To hlavní co by Ti mohlo pomoci je to že je tu stále rozdíl mezi 1D pole a 2D polem v oblasti ohraničení. Když se podíváš na 1D pole, je to pás jehož krajní hodnoty jsou první a poslední prvek (pole[0] a pole[19] pro pole o velikosti 20). Y hlediska vizuální podoby 2D pole jsou krajní hodnoty všechny v prvním sloupci a posledním sloupci a všechny hodnoty v prvním a posledním řádku. Je tedy třeba vědět z jakého pohledu chceš maxima určit.
Teď ke kódu. Deklaruj 2D pole o velikosti 3x3, naplňuješ ho náhodnými hodnotami a poté si ho pro kontrolu vypisuješ. Až sem to vypadá vše OK.
V další části určuješ zda prvek na pozici 0,0 je maximem v porovnání s prvkem na pozici 0,1. Pokud tedy porovnáváš hodnoty pouze v horizontálním rozměru, pak je to správné. Pro zachování způsobu určování maxima toto budu brát jako důležitý prvek.
V poslední části nejspíš chceš zjistit zda poslední prvek je maximem. Ta je chybně. Pracuješ zde pouze s velikostí pole nikoli s hodnotou. Dále jak jsem v úvodu zmínil, krajních hodnot pro 2D pole z vizuálního hlediska je více. Pokud to budu brát v horizontální rovině, pak jsou to všechny prvky v prvním sloupci a všechny prvky v posledním sloupci. V paměti je ale 2D pole uspořádáno jako 1D pole, po řádcích. Pokud ale chceš brát pouze první a poslední prvek jako hraničíčí, může to udělat. Jelikož máš pole 3x3, pak testuješ maximum pole[2,2]. Pokud chceš používat funkci pro výpočet velikosti pole, musí být výsledek této hodnoty vzat jako index pole.
Zda VB umožnuje vkládat výsledky funkcí jako index pole, netuším. Ale můžeš to zjistit. protože chceš určit zda maximum je i na posledním prvku, tedy pole[2,2], musíš ho porovnat s hodnotou na pozici pole[2,1].
Následující zápis by mohl představovat pozici posledního prvku:
pole(pole.GetLength(0) - 1, pole.GetLength(1) - 1)
a předposledního prvku:
pole(pole.GetLength(0) - 1, pole.GetLength(1) - 2)
Pokud to VB nevezme, pak si výrazy na indexových pozicích musíš předpočítat, uložit do proměnné a tu pak dosadit na pozici indexu.
Musíš stále pracovat s hodnotou na dané pozici:
Tedy vždy musíš používat formát pole[ROW, COL].
Teď k té nejkomplikovanější části. Obtížně se Ti bude určovat zbytek prvního a posledního řádku protože pracuješ se 2 indexy a první a poslední řádek je neúplný.
V úvodu jsem zmínil že způsob hledání maxima děláš ve vodorovné rovině. Pak ale nemůžeš použít jako index hodnoty j-1 a j+1.
Nelze použít stejný způsob hledání maxima pro 2D pole a 1D pole. Pro určení maxima u 2D pole je třeba provést přepočet indexů. Musíš vědět jak to přepočítat. Že např. prvek na pozici 1,0 v 2D poli 3x3 odpovídá 4 prvku pole[3] v 1D poli. Stále se bavíme že pracujeme v hledání maxima v horizontální rovině.
Jak vidíš, je to o dost komplikovanější nežli u 1D pole. Abys tohle zvládl, musíš se o 2D poli dozvědět více. Musíš umět porovnat 1D pole s 2D polem. Jak už jsem zmínil, v paměti je 2D pole uloženo po řádcích a vypadá jako 1D pole. Ale pro práci s konkrétními indexy musíš umět přepočítat indexy.
DarkCoder:7.6.2020 1:27
Abys viděl, o kolik je to ve 2D komplikovanější oproti 1D poli, zde je ukázka hledání lokálního maxima ve 2D poli 4x5.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 4
#define COL 5
int main(void) {
int nums[ROW][COL];
srand((unsigned int)(time(NULL)));
// naplneni 2D pole nahodnymi hodnotami v rozsahu 0-99
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
nums[i][j] = rand() % 100;
}
}
// kontrolni vypis 2D pole (hodnota a index)
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
printf("%d[%d][%d] ", nums[i][j], i, j);
}
putchar('\n');
}
putchar('\n');
// test lokalniho maxima prvniho prvku
if (nums[0][0] >= nums[0][1]) {
printf("%d[%d][%d] ", nums[0][0], 0, 0);
}
// test lokalniho maxima vnitrnich prvku
for (int i = 1; i < (ROW * COL - 1); i++) {
if ((nums[i / COL][i % COL] >= nums[(i - 1) / COL][(i - 1) % COL]) && (nums[i / COL][i % COL] >= nums[(i + 1) / COL][(i + 1) % COL])) {
printf("%d[%d][%d] ", nums[i / COL][i % COL], i / COL, i % COL);
}
}
// test lokalniho maxima posledniho prvku
if (nums[ROW - 1][COL - 1] >= nums[ROW - 1][COL - 2]) {
printf("%d[%d][%d] ", nums[ROW - 1][COL - 1], ROW - 1, COL - 1);
}
return 0;
}
Výstup programu:
19[0][0] 70[0][1] 44[0][2] 54[0][3] 40[0][4]
83[1][0] 64[1][1] 40[1][2] 41[1][3] 66[1][4]
55[2][0] 35[2][1] 74[2][2] 68[2][3] 25[2][4]
76[3][0] 38[3][1] 71[3][2] 63[3][3] 65[3][4]
70[0][1] 54[0][3] 83[1][0] 66[1][4] 74[2][2] 76[3][0] 71[3][2] 65[3][4]
Jak je vidět, určení maxima prvního a posledního prvku je přímočaré. Pro určení maxima vnitřních prvků už je třeba přepočtu z 1D do 2D pro správnou indexaci.
Práce s 2D poli může být zábavná..
Zobrazeno 35 zpráv z 35.