Emelt érettségi programozási feladat megoldása C# - ban? Vélemények, tanácsok szeretnék kérni.
Emelt érettségi feladat megoldása. Örülnék pár hasznos tanácsnak és véleménynek.
A kód: [link]
A feladat: [link]
Köszönöm előre is a kommenteket. :)
Előre leszögezem hogy nem szoktam programozni C#-ban, ezért lehet hogy fogok írni ökörséget is.
20-23:
for (; ; )
{
string kerdes = olvaso.ReadLine();
if (kerdes == null) { break; }
[...]
helyett tisztább lenne a következő:
while(string kerdes = olvaso.ReadLine()) {
[...]
27-29:
Nem érdemes létrehozni külön sep változót, add át a szóköz a Splitnek közvetlenül:
temp = temp[0].Split(' ', StringSplitOptions.None);
18:
Feleslegesen tartod számon a beolvasott sorok számát, kerdesek.Count megmondja neked mennyit olvastál be.
48:
Nem kell eltárolni Listában a matematika kérdéseket, csak ellenőrizni. Az egész feladat összevonható 1 ciklusba:
int[] pontok = { 0, 0, 0 };
foreach (Kerdes k in kerdesek) {
if (k.kategoria == "matematika") {
switch (k.pont) {
case 1: pontok[0]++; break;
case 2: pontok[1]++; break;
case 3: pontok[2]++; break;
default: throw new Exception("HIBA AZ ADATOKBAN");
}}}
76:
Megint csak új tömböt hozol létre és másolod le az értékeket amik már egyszer bent vannak a memóriában. Ha így egyszerű neked akkor ok, de rossz szokás. Ha jól tudom a C# Listának van Min és Max metódusa ami paraméterül kaphat lambda kifejezést is:
int min = kerdesek.Min(x => x.valasz);
int max = kerdesek.Max(x => x.valasz);
Nem használok C#-ot, de ennek szerintem működnie kéne.
91:
List.Contains megmondja hogy a listában megtalálható e valamilyen elem. Nézz utána. De leírom a szokásos módszert az ilyen feladatokra.
Amikor egy Listát Halmazzá (Set) alakítasz, akkor csak az egyedi elemek maradnak meg.
int[] szamok = {0,0,1,1,2,3,3,3,3};
var egyedi = new HashSet<int>(szamok);
Ekkor az egyedi tartalma {0,1,2,3} lesz. Persze ha így ajánlanám ebben az esetben ellentmondanék magamnak, hiszen nem számokról hanem egy osztályról van szó. De a Set másra is jó: gyorsan lehet benne keresni.
var valaszok = new HashSet<string>();
foreach (Kerdes k in kerdesek) {
if(!valaszok.Contains(k.valasz))
valaszok.Add(k.valasz);
}
125,146:
Szerintem ide nem kell -1. A Random.Next a paraméterül adott számnál mindig kisebbet ad vissza.
138:
Nem lehet kétszer ugyan az a kérdés -> egyedit elemek -> használj halmazt (HashSet).
A halmaz gyorsabb és egyszerűsít az életeden:
while (kerdesSzamok.Count < 10)
{
int temp = random.Next(kerdesek.Count - 1);
if (!letezik(temp, kerdesSzamok)) { kerdesSzamok.Add(temp); }
}
helyett:
while (kerdesSzamok.Count < 10)
kerdesSzamok.Add(random.Next(kerdesek.Count));
A magyarázat az hogy ha a kerdesSzamok egy halmaz, akkor ha kétszer próbálod berakni ugyan azt az elemet, nem történik semmi. Ezt fokozhatod azzal hogy már nem kell int típusúnak lennie a halmaznak, lehet mindjárt Kerdes típusa is, arra is működik a halmaz tulajdonsága. Amúgy meg Contains matódus.
165-173:
Ugyan már leírtam miért nem kell, de kétszer megírni ugyan azt a metódust nem jó dolog. Az egyetlen különbség a két letezik() között a típus. Erre valóak a templatek:
static bool letezik<T>(T a, List<T> b)
{
foreach (T i in b)
{
if (i == a) { return true; }
}
return false;
}
Így már bármivel lehet használni.
Még annyit hogy 91 írtam hogy
var valaszok = new HashSet<string>();
foreach (Kerdes k in kerdesek) {
if(!valaszok.Contains(k.valasz))
valaszok.Add(k.valasz);
}
Ez természetesen továbbegyszerűsödik 138-as sor magyarázata alapján, csak be akartam mutatni a Contains metódus-t. És sikerült elírnom a változók nevét:
var temakorok = new HashSet<string>();
foreach (Kerdes k in kerdesek) {
temakorok.Add(k.kategoria);
}
Nem kell ellenőrizni a Contains-szel mert nem fogja kétszer hozzáadni ugyan azt a halmazhoz amúgy sem.
Köszönöm a válaszokat főleg az elsőnek :)
while(string kerdes = olvaso.ReadLine()) { }
ez így sajnos nem működik
x => x.valasz és a HashSet -et sem ismertem eddig, most már igen :)
a templateket még nem tanultam, egyszer remélem eljutok odáig
Utolsónak: elég ritka hogy c# ban rakják ki,de főleg az én kódom hibáiról akartam véleményeket.
> ez így sajnos nem működik
Úgy tűnik a C# nem engedi hogy feltételben változót deklarálj, de engedi az értékadás operátort, tehát ez így viszont már kéne hogy működjön:
string kerdes
while(kerdes = olvaso.ReadLine()) { }
Vagy ha nem szereti az implicit tesztelést akkor odatolhatsz neki még egy null-t is:
string kerdes
while((kerdes = olvaso.ReadLine()) != null) { }
Sajnos nem ismerem eléggé a C#-t és nincs módom tesztelni.
Az előző vagyok, gondoltam ha már úgy is ismerem a feladatot, gyorsan összedobom Pythonban, hátha valaki hasznát veszi..
A rengeteg kiíratás a sok, print print hátán, a hasznos kód csak pár sor Pythonban. Nincs tesztelve, remélem nem néztem be semmit.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!