Diskuze: Jak zrušit cyklus z vnořeného switche?
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Ještě jsem zapomněl dodat, že vyhazuju podobné, ale to asi chápete.
Jo, a má to být sbyte, a ne byte .
Petr Štechmüller:28.5.2018 17:32
Ahoj, stačí se správně zeptat strejdy googla a první odkaz je obvykle ten správný...
Pre lenivých: odkaz smeruje na goto, čo je prasácka a strašne stará vec, ktorá by sa dnes v kóde vo väčšine jazykov objavovať nemala, ale ako pozerám na tie vnorené cykly, veľa možností asi nemáš. Používa sa to nejako takto:
for (…)
for (…)
…
goto Label
Label:
// sme vonku z cyklov!
Nie som si 100% istý čo chceš vlastne robiť, ale znie to, ako keby si
chcel dať ten Label dovnútra prvého foru.
Čistejšou alternatívou by mohlo byť spraviť si nejakú rozumnú pomocnú
funkciu, z ktorej by si vyskočil proste returnom.
+20 Zkušeností
+2,50 Kč

Neaktivní uživatel:28.5.2018 17:59
Díky vám oběma, nicméně jsem předtím pročítal alespoň to od MS (už nevím, co všechno), a byl jsem z toho jedině zmatený. Když jsem to zkoušel hodit do kódu, psalo mi to chybu. Hlavně: to Label je jediná možnost, nebo je možný i jiný název či co to vlastně je?
Martin Petrovaj:28.5.2018 18:06
Môžeš to nazvať ako len chceš, je to proste meno nejakej značky, ku ktorej sa pomocou goto vieš dostať. Predstav si to ako názvy kapitol v knihe. Procesor je čitateľ a niekde v knihe vidí odkaz "viď kapitola 3.4 Vnorené cykly." Nájsť následne kapitolu s daným názvom je preňho jednoduché, tak si ju nalistuje a pokračuje v čítaní tam. To slovo "viď" je goto a názov kapitoly je tvoj Label.
Mimochodom, nedalo by sa to vyriešiť jednoduchšie pomocou LINQ?
List<Object> listA = new List<object>();
List<Object> listB = new List<object>();
listA.RemoveAll(objA => listB.Exists( objB => objA.Srovnej(objB) ));
Pravda, trochu upravené pre tvoju metódu Srovnej.
Petr Štechmüller:28.5.2018 18:11
Minimálně v Javě je tato featura známá jako "návěští".
Neaktivní uživatel:28.5.2018 18:15
Díky.
Ne, možností je trochu víc, mám tam nějaký string z čísel a srovnávám jestli:
- je hodnota objektu, která mě zajímá, podobná a součet je větší (odstraním j)
- to samé, ale součet je menší (odstraním i)
- je ta hodnota výrazně jiná
a pokud vím, ty používáš bool, který má pouze dvě možné hodnoty.
A ještě jedna otázka: provede se goto i v případě, že na něj neodkážu? (Teda ten kód v odkaze.)
Martin Petrovaj:28.5.2018 18:17
if (false) { goto znacka; }
znacka:
Console.WriteLine("Áno, toto sa vypíše aj tak. Tá značka proste len označuje nejaké miesto v programe, ale sama o sebe flow programu nijako neovplyvňuje.");
Myslel si to takto?
Neaktivní uživatel:28.5.2018 18:20
Asi jo. Tak ještě jednou díky, v tomto vlákně snad už naposled.
Erik Šťastný:28.5.2018 19:08
Tyhle situace vždy řeším, tak že cykly rozepíšu do metod zvlášť a
použiju v nich return
Martin Dráb:28.5.2018 20:03
for ( . . .) {
. . .
for ( . . .) {
bool stop = false;
if (stop)
break;
}
}
Proměnnou stop můžeš pojmenovat klidně nějak lépe. Já třeba v případě, že ve vnitřním cyklu něco hledám, ji dávám jméno found. Když je true, znamená to, že bylo nalezeno, takže není třeba ve vnitřním cyklu pokračovat.
Pokud potřebuješ vyskočit i z vnějšího cyklu, můžeš tu proměnnou deklarovat tak, aby i z tohoto cyklu byla vidět, takže jen přidáš
if (stop)
break;
Takhle se vyhneš použití goto, a tak zbytečně neumřou
koťátka. Jistě, je to více práce a řádků, ale nestojí život koťátek
za tu námahu?
Neaktivní uživatel:28.5.2018 20:13
Řádek tak jeden oproti tomu co mám teď, asi by to mohlo jít i takhle.
ostrozan:28.5.2018 21:22
taky můžeš nastavit hodnotu
j = list.Count;
čímž padne podmínka j<list.Count a cyklus se sám
přeruší a nemusíš dodávat žádné nové proměnné a koťátka opět
přežijí
Jinak radši dávej na posouzení nějaký skutečný kód - v té
slátanině v úvodu je tolik nesmyslů, že by se ti to červenalo chybama jak
jahodové plantáže v tomto čase
Když už chceš něco "cucat z prstu" tak by to mělo mít hlavu a patu.
Mimochodem celé mi to připadá jaksi postavené na hlavu - termíny "podobné a menší" , nebo
Když se "rovnají", vrátí 1 nebo -1 podle dalších podmínek,
tak buď se rovnají - bez podmínek , nebo ne
nebo chceš porovnávat všechny prvky v kolekci, ale někdy ne - někdy to chceš zrušit právě tím přerušením for cyklu
No ale budiž ti omluvou tvůj věk - pokud ten uvedený na profilu odpovídá skutečnosti
Neaktivní uživatel:29.5.2018 15:34
Zajímavý nápad, tohle mě (záhadně) jaksi nenapadlo.
Původní kód je moc dlouhý, to by určitě číst nikdo nechtěl (i proto, že to je dost podobné), ale jestli chceš, podívej se dolů.
Zapomněl jsem na slova "jsou podobné", ale ty uvozovky tam byly právě proto.
Aspoň něco kladného
(krom těch koťátek). Ano, je jen s odchylkou několika dní
.
Tohle ještě pořád nefunguje jak má, kdyby někdo pochopil, co chci, a našel chybu, budu rád. Věřím, že by se toho dalo i dost zjednodušit.
namespace ctverce {
class Ctverec {
public string Kod { get; private set; }
public byte Soucet { get; private set; }
readonly public byte[][,] barvy;
private byte[,] Vybarvi(string kod) {
byte[,] radek = new byte[4, 4];
for (int i = 0; i < radek.GetLength(0); i++) {
for (int j = 0; j < radek.GetLength(1); j++) {
radek[i, j] = 0;
}
}
byte[] c = new byte[8];
for (int i = 0; i < c.Length; i++) {
c[i] = byte.Parse(kod.Substring(i, 1));
}
for (int i = 0; i < radek.GetLength(1); i++) {
for (int j = 0; j < radek.GetLength(0); j++) {
if (c[j] + c[i + 4] <= 2)
radek[i, j] = Convert.ToByte(c[j] + c[i + 4]);
}
}
return radek;
}
public Ctverec(string kod) {
string[] kody = new string[8];
Kod = kody[0] = kod;
kody[5] = Kod.Substring(4, 4) + Kod.Substring(0, 4);
kody[6] = Kod.Substring(4, 4);
for (int i = 0; i < 8; i++) {
kody[1] += Kod.Substring(7 - i, 1);
if (i < 4) {
kody[2] += Kod.Substring(i, 1);
kody[3] += Kod.Substring(3 - i, 1);
kody[4] += Kod.Substring(3 - i, 1);
kody[6] += Kod.Substring(3 - i, 1);
kody[7] += Kod.Substring(7 - i, 1);
} else {
kody[2] += Kod.Substring(7 - i, 1);
kody[3] += Kod.Substring(i, 1);
kody[4] += Kod.Substring(11 - i, 1);
}
}
kody[7] += Kod.Substring(0, 4);
barvy = new byte[8][,];
for (int i = 0; i < barvy.Length; i++) {
barvy[i] = Vybarvi(kody[i]);
}
Soucet = byte.Parse(Kod.Substring(0, 1));
for (int i = 1; i < Kod.Length; i++) {
Soucet += byte.Parse(kod.Substring(i, 1));
}
}
//ToString() nikdo nepotřebuje. Vrací kód a barvy.
public sbyte Srovnej(Ctverec ctverec) {
for (int i = 0; i < ctverec.barvy.Length; i++) {
if (barvy[0].Equals(ctverec.barvy[i])) {
if (ctverec.Soucet > Soucet) return 1;
else return -1;
}
}
return 0;
}
}
class Program {
static void Main(string[] args) {
Console.Title = "Ctverce";
Console.SetWindowSize(40, 25);
Console.SetBufferSize(40, Int16.MaxValue / 2);
List<Ctverec> ctverce = new List<Ctverec>();
byte a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
for (int i = 0; i < Math.Pow(4, 8); i++) {
ctverce.Add(new Ctverec(a.ToString() + b.ToString() + c.ToString() + d.ToString() + e.ToString() + f.ToString() + g.ToString() + h.ToString()));
h++;
if (h == 4) {
h = 0;
g++;
if (g == 4) {
g = 0;
f++;
if (f == 4) {
f = 0;
e++;
if (e == 4) {
e = 0;
d++;
if (d == 4) {
d = 0;
c++;
if (c == 4) {
c = 0;
b++;
if (b == 4) {
b = 0;
a++;
}
}
}
}
}
}
}
}
Console.WriteLine("Hotovo!!!\n");
bool label = false;
for (int i = 0; i < ctverce.Count; i++) {
label = false;
for (int j = i + 1; j < ctverce.Count; j++) {
switch (ctverce[i].Srovnej(ctverce[j])) {
case 1:
ctverce.RemoveAt(j);
break;
case -1:
ctverce.RemoveAt(i);
i--;
label = true;
goto Label;
}
}
Console.WriteLine("{0} – {1}", i + 1, ctverce.Count);
Label: if(label) Console.WriteLine("{0} – {1}", i + 2, ctverce.Count);
}
Console.WriteLine();
for (int i = 0; i < ctverce.Count; i++) {
Console.WriteLine(ctverce[i].Kod);
}
Console.ReadKey();
}
}
}
…prostě začátečník.
Krystof Matejka:30.5.2018 8:47
Omlouvám se, ale jsem VELKÝ začátečník, co znamená to
readonly public byte[][,] barvy;
Konkrétně to byte[][,]
Neaktivní uživatel:30.5.2018 14:59
To je pole dvourozměrných polí, v seriálu ( https://www.itnetwork.cz/…ozmerna-pole ) to máš popsané. Mohlo by to být i byte[][][] nebo byte[,,], ale takhle je to pro mě srozumitelnější.
ostrozan:30.5.2018 17:22
To fakt nevím co to má vlastně dělat ,ale nejde mi do hlavy proč si s tvary a barvami hraješ v konzoli a ne třeba ve WPF?
ale jedno mně zaujalo
for (int i = 0; i < Math.Pow(4, 8); i++)
v čem je to lepší než i < 65536 ?????????
Neaktivní uživatel:30.5.2018 21:06
Takhle jsem si prostě jistější, však víš, jak jsem na to přišel. Kód má osm míst, kde může být vždy číslo od 0 do 3. Ale krom té jistoty to asi je horší – musím volat další metodu atd.
A s barvama si hraju tady, protože potřebuju hlavně ty kódy. Dostal jsem
jednoduchou MS excel aplikaci, kde jsem měl hledat kód k obrázku, a když
jsem si to zkoušel vytvořit, nechtělo se mi ty kódy vymýšlet.
Zobrazeno 22 zpráv z 22.