eMatematikas Prisijunk Forumas Matematikos testai Pradžia

Informatikos VBE 2020 (programa). Užduotis - (1) Gėlės


(C++)Sveiki,
gal galėtumėte įvertinti/patikrinti programą t.y. ar laikomasi reikalavimų, nėra logikos klaidų ir pan. Atsakymai gaunasi geri (patikrinau su duotais duomenų pavyzdžiais NECE), bet ne esu įsitikinęs ar nėra klaidų.

Užduoties sąlyga 6 psl. - https://www.nec.lt/failai/8563_IT_2020_pagr_www.pdf
#include<fstream>
using namespace std;
struct flow{
int num;
int m1,d1;
int m2,d2;
};
void skaitymas(int &n, flow A[]){
int i;
ifstream df("duom.txt");
df>>n;
for(i=0;i<n;i++) df>>A[i].num>>A[i].m1>>A[i].d1>>A[i].m2>>A[i].d2;
df.close();
}
void intervalas(int n, int start[], int end[], int &y, int &t){
int i,j,temp,delta,x=0;
for(i=0;i<n;i++){
temp=start[i];
delta=end[i];
for(j=0;j<n;j++) if(temp>=start[j] and delta<=end[j]) x++;
if(y<x){
y=x;
t=i;
}
x=0;
}
}
void rasymas(int y, int t, flow A[]){
ofstream rf("result.txt");
rf<<y<<"\n";
rf<<A[t].m1<<" "<<A[t].d1<<"\n";
rf<<A[t].m2<<" "<<A[t].d2;
rf.close();
}
int main(){
flow A[20];
int n,start[20],end[20];
skaitymas(n,A);
int i;
for(i=0;i<n;i++){
if(A[i].m1==6) start[i]=A[i].d1;
else if(A[i].m1==7) start[i]=30+A[i].d1;
else  start[i]=61+A[i].d1;
if(A[i].m2==6) end[i]=A[i].d2;
else if(A[i].m2==7) end[i]=30+A[i].d2;
else  end[i]=61+A[i].d2;
}
int y=-1,t;
intervalas(n,start,end,y,t);
rasymas(y,t,A);
return 0;
}

pakeista prieš 3 m

Sąlygoje parašyta "daugiausia skirtingų gėlių", o tu į gėlių rūšį visiškai neatsižvelgi. Taip pat daug nereikalingų if'ų bei kintamųjų prikurta. Pavyzdžiui funkcijoje intervalas:
int i,j,temp,delta,x=0;
for(i=0;i<n;i++){
temp=start[i];
delta=end[i];
for(j=0;j<n;j++) if(temp>=start[j] and delta<=end[j]) x++;
if(y<x){
    y=x;
    t=i;
}
x=0;
}
}

Galėtum pakeist į:
int i,j,x=0;
for(i=0;i<n;i++){
    for(j=0;j<n;j++) if(start[i]>=start[j] and end[i]<=end[j]) x++;
    if(y<x){
        y=x;
        t=i;
    }
    x=0;
}
}


Taip pat galėtum šito išvengti, bei masyvų start, end:
for(i=0;i<n;i++){
if(A[i].m1==6) start[i]=A[i].d1;
else if(A[i].m1==7) start[i]=30+A[i].d1;
else  start[i]=61+A[i].d1;
if(A[i].m2==6) end[i]=A[i].d2;
else if(A[i].m2==7) end[i]=30+A[i].d2;
else  end[i]=61+A[i].d2;
}


Jei susikurtum  masyvą tarkim int prideti[3] ={0,30,61} ir funkcijoje intervalas tada rašytum for(j=0;j<n;j++) if(A[i].d1+prideti[A[i].m1-6]>=A[j].d1+prideti[A[j].m1-6] and A[i].d2+prideti[A[i].m2-6]<=A[j].d2+prideti[A[j].m2-6) x++;
Jeigu nepatinka ilgas if'as, tai tada aišku gali daryti kaip ir dariai. Bet tavo ir pati funkcija ne tą skaičiuoji, ji skaičiuoja, kurios gėlės žydėjimo intervale žydi daugiausiai gėlių, bet intervalo pradžia gali būti vienos gėles žydėjimo laikas, o pabaiga kitos gėlės.

Kadangi sąlygoje užsimenama apie 92 dienų sąrašą, tai siūlau jį ir naudoti. (manau, kad kalbėdami apie sąrašą omenyje turi masyvą, nes sąrašai į mokyklinę programą neįeina). Po duomenų nuskaitymo tada teks patikrinti ar tokios pat rūšies gėlių žydėjimo intervalai nesikerta, pavyzdžiui viena prasideda 06-12 baigiasi 07-12, o kita prasideda 06-13 baigiasi 07-11, tai aišku, kadangi jos tos pačios rūšies, tai tuo metu žydi 1 rūšis, o ne 2, gali dar būti, kad viena prasideda anksčiau nei kita bet baigiasi tuo pat metu ir panašiai, tai reikės koreguoti intervalus vieną ištrinant ar pakeičiant pradžios/pabaigos datą. Na, o tada beliks surasti intervalą kada daugiausiai žydi tiesiog pridedant 1 masyve prie tam tikros datos, randant kiek daugiausiai yra ir randant kada pirma kartas tas didžiausias skaičius pasitaiko ir kada baigiasi.

Taip pat gali prikibti prie punkto "Prasmingai pavadinti kintamieji. Komentuojamos programos dalys, laikomasi rašybos taisyklių." Tad geriau pervadinti x į kiek ir t.t.

pakeista prieš 3 m

Dar taip pat galėtum išvengti for(i=0;i<n;i++){
if(A[i].m1==6) start[i]=A[i].d1;
else if(A[i].m1==7) start[i]=30+A[i].d1;
else  start[i]=61+A[i].d1;
if(A[i].m2==6) end[i]=A[i].d2;
else if(A[i].m2==7) end[i]=30+A[i].d2;
else  end[i]=61+A[i].d2;
}


Jei struktūroje tiesiog turėtum:
struct flow{
int num;
int pradzia;
int pabaiga;
};

Ir nuskaitant iš karto pasiverstum pradžią ir pabaigą į kažkokį tai skaičių

Aš suprantu, kad į gėlių rūšį galime neatsižvelgti, nes duomenų faile(pvz.):
6                      Vasarą žydinčių gėlių skaičius
121 6 15 7 25
102 7  1 8 14
236 6 30 8 31
141 7 31 8 10
111 7  1 7 20
128 6  2 6 3
yra per mažai informacijos, nes jeigu tos pačios gėlės būtu keli intervalai, mes nesugebėtumėme nuskaityti visų duomenų (tikiuosi supratote mintį.)
Manau dabar programa turi būti gera (tik vieno nurodymo vengiau - prasmingai pavadinti kintamieji/komentavimas):

#include<fstream>
using namespace std;
void skaitymas(int &n, int S[]){
int i,j,num,m1,d1,m2,d2,x,y;
ifstream df("duom.txt");
df>>n;
for(i=0;i<n;i++){
df>>num>>m1>>d1>>m2>>d2;
if(m1==6) x=d1;
else if(m1==7) x=30+d1;
else x=61+d1;
if(m2==6) y=d2;
else if(m2==7) y=30+d2;
else y=61+d2;
for(j=x;j<=y;j++){
S[j]++;
}
}
df.close();
}
int fx(int S[]){
int i,delta,max=-1;
for(i=1;i<=92;i++) if(max<S[i]){
max=S[i];
delta=i;
}
return delta;
}
void rasymas(int start, int end, int S[]){
int i;
ofstream rf("result.txt");
rf<<S[start]<<"\n";
if(start<=30) rf<<6<<" "<<start<<"\n";
else if(start>30 and start<=61) rf<<7<<" "<<start-30<<"\n";
else rf<<8<<" "<<start-61<<"\n";
if(end<=30) rf<<6<<" "<<end;
else if(end>30 and end<=61) rf<<7<<" "<<end-30;
else rf<<8<<" "<<end-61;
rf.close();
}
int main(){
int i,S[92];
for(i=1;i<=92;i++) S[i]=0;
int n,start,end;
skaitymas(n,S);
start=fx(S);
int max=S[start],temp=0;
for(i=start;i<=92;i++) if(S[i]==max and temp==0) end=i;
else temp++;
rasymas(start,end,S);
return 0;
}

Taip, nepamačiau, kad parašyta jog jau duoda skirtingų gėlių skaičių.

Bet vistiek skaitymas pakeisciau:

void skaitymas(int &n, int S[]){
int i,j,num,m1,d1,m2,d2,x,y;
ifstream df("duom.txt");
df>>n;
for(i=0;i<n;i++){
df>>num>>m1>>d1>>m2>>d2;
if(m1==6) x=d1;
else if(m1==7) x=30+d1;
else x=61+d1;
if(m2==6) y=d2;
else if(m2==7) y=30+d2;
else y=61+d2;
for(j=x;j<=y;j++){
S[j]++;
}
}
df.close();
}


i:

void skaitymas(int &n, int S[]){
int i,j,num,m1,d1,m2,d2,x,y;
int prideti[3] = {0,30,61};
ifstream df("duom.txt");
df>>n;
for(i=0;i<n;i++){
df>>num>>m1>>d1>>m2>>d2;
x = prideti[m1-6]+d1;
y = prideti[m2-6]+d2;
for(j=x;j<=y;j++){
S[j]++;
}
}
df.close();
}


O sito visiskai nereikia:
for(i=1;i<=92;i++) S[i]=0;
Nes ir taip masyve visi elementai lygus 0.(Bent jau turetu but, gali rasyt tiesiog S[92] = {0};)

O sita:
for(i=start;i<=92;i++) if(S[i]==max and temp==0) end=i;
else temp++;


Turbut taisyklingiau butu rasyt su while, bet skirtumo didelio nera.

Taip pat, kadangi nulines dienos nera, reiketu padidinti S masyva.

pakeista prieš 3 m

Nori sudalyvauti šioje temoje ir parašyti savo pranešimą? Prisijungti »