mali sme zo suboru nacitat csv tabulku - riadky su riadky, bunky v riadku oddelene bodkociarkami.
V bunke moze byt bud cele cislo alebo vzorec zacinajuci znakom '='. Vo vzorci je jednoducha operacia (scitanie, odcitanie, nasobenie, celociselne delenie), teda operator a okolo neho dva operandy. tie mozu byt bud cisla alebo odkazy na ine bunky v tvare $A7. vo vzorci moze byt tiez iba samostatny odkaz =$A7. Stlpce su A az Z, riadky 1 az 99. Ak na nejakom riadku nie su vsetky bunky defnovane, berie sa to, akoze je v nich nula.
Cielom bolo vyhodnotit tabulku, aby boli v bunkach vysledky popisanych vyrazov. V pripade delania nulou mala bunka obsahovat #NAN, v pripade odkazu mimo tabulku (napr. $A120) alebo vobec nespravneho zapisu ($JJ v priklade) mala bunka hodnotu #CHYBA a (to bolo to hlavne) mali sa detekovat cykly medzi bunkami, potom mali mat vsetky bunky v cykle #CYKLUS. Az na tie zapisy odkazov sme mohli pocitat s korektnym vstupom. Doplnim iba, ze operacia bola v bunke maximalne jedna, ziadne zlozite uzatvorkovane vyrazy.
Vystup standardny. Vo vstupe ani na vystupe nie su / nemaju byt biele znaky okrem koncov riadkov. Nepouzite bunky sa na vystup vypisovat nemaju. Ale ked boli na vstupe vyznacene dvomi ; za sebou, tak na vystupe maju byt tiez, vid priklad, ale to nakoniec nevyzadoval.
Teda sa zda, ze ceklom lahke zadanie, len si je treba dat pozor na detaily. Pre uplynutim casu nikto neodovzdaval. Po troch hodinach si skusajuci kazdeho obisiel, komu chybalo uz iba malickost opravit, tak dovolil este zopar minut.
Bolo nas 20, presli sme 4...
K dispozicii bol aj ukazkovy vstup a vystup.
Prikladam aj svoj program. Nefunguje tak ako ma (tie ; za sebou na konci riadku - ked sa podla nich splituje, tak sa to prazdna bunky zmazu) , nejake veci su tam dorobene iba narychlo pred koncom. Ale nakoniec to ako tak stacilo.
Program
Kód: Vybrat vše
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Tabulkovac {
BufferedReader br;
Bunka[][] tabulka;
byte sirka = 26;
byte vyska = 99;
boolean[][] pritomne;
byte pocet_riadkov;
byte[] pocty_stlpcov;
public Tabulkovac( String meno_suboru) {
try {
br = new BufferedReader( new FileReader( meno_suboru));
pritomne = new boolean[sirka][vyska];
String[][] str_tabulka = citaj_subor();
br.close();
vytvor_tabulku( str_tabulka);
for ( byte j = 0; j < pocet_riadkov; j++ ) {
for ( byte i = 0; i < pocty_stlpcov[j]; i++ ) {
if ( pritomne[i][j] ) {
Vysledok vys = tabulka[i][j].spocitaj();
if ( vys.cislo )
System.out.print(vys.hodnota);
else
System.out.print(vys.retazec);
//tabulka[i][j].print_meno();
//System.out.print(tabulka[i][j].obsah);
}
if ( i < pocty_stlpcov[j] -1 )
System.out.print(";");
}
System.out.println();
}
} catch ( FileNotFoundException e ) {
System.out.print( "Chyba: subor sa nenasiel");
} catch ( IOException e ) {
System.out.print( "Chyba pri citani");
}
}
void vytvor_tabulku( String[][] str_tabulka) {
tabulka = new Bunka[sirka][vyska];
for ( byte j = 0; j < vyska; j++ ) {
for ( byte i = 0; i < sirka; i++ ) {
Bunka bunka = new Bunka( i, j);
tabulka[i][j] = bunka;
}
}
for ( byte j = 0; j < vyska; j++ ) {
for ( byte i = 0; i < sirka; i++ ) {
tabulka[i][j].nastav_obsah( str_tabulka[i][j]);
}
}
}
enum Stav { Hotova, Robena, Spiaca };
class Bunka {
Uzol koren;
public byte stlpec;
public byte riadok;
public String obsah;
Stav stav = Stav.Spiaca;
Vysledok vysledok;
public Bunka( byte stlpec, byte riadok) {
this.obsah = obsah;
this.stlpec = stlpec;
this.riadok = riadok;
}
public void nastav_obsah( String obsah) {
if ( obsah == null || obsah.equals( "") )
koren = null;
else
spracuj_obsah( obsah); // nastavi koren
}
public void print_meno() {
if ( koren == null )
System.out.print("null");
else
koren.print();
}
Vysledok spocitaj() {
stav = Stav.Robena;
if ( koren != null )
vysledok = koren.spocitaj();
else
vysledok = new Vysledok( 0);
stav = Stav.Hotova;
return vysledok;
}
void spracuj_obsah( String obsah) { // predopkladame, ze obsah je nenulovy
String[] kusky = obsah.split( "=");
if ( kusky.length == 1 ) {
int cislo = Integer.parseInt( kusky[0]);
koren = new Uzol( cislo);
} else {
String vzorec = kusky[1];
if ( moj_split( vzorec, '+').length > 1 ) {
String[] splitted = moj_split( vzorec, '+');
Uzol lavy = spracuj_operand( splitted[0]);
Uzol pravy = spracuj_operand( splitted[1]);
koren = new Uzol( '+', lavy, pravy);
} else if ( moj_split( vzorec, '-').length > 1 ) {
String[] splitted = moj_split( vzorec, '-');
Uzol lavy = spracuj_operand( splitted[0]);
Uzol pravy = spracuj_operand( splitted[1]);
koren = new Uzol( '-', lavy, pravy);
} else if ( moj_split( vzorec, '*').length > 1 ) {
String[] splitted = moj_split( vzorec, '*');
Uzol lavy = spracuj_operand( splitted[0]);
Uzol pravy = spracuj_operand( splitted[1]);
koren = new Uzol( '*', lavy, pravy);
} else if ( moj_split( vzorec, '/').length > 1 ) {
String[] splitted = moj_split( vzorec, '/');
Uzol lavy = spracuj_operand( splitted[0]);
Uzol pravy = spracuj_operand( splitted[1]);
koren = new Uzol( '/', lavy, pravy);
} else { // bez operacie
koren = spracuj_operand( vzorec);
}
}
}
String[] moj_split( String retazec, char znak) {
char[] znaky = retazec.toCharArray();
String retazec_1 = "";
String retazec_2 = "";
boolean bol = false;
for ( int i = 0; i < znaky.length; i++ ) {
if ( znaky[i] == znak )
bol = true;
else {
if ( ! bol )
retazec_1 = retazec_1 + znaky[i];
else
retazec_2 = retazec_2 + znaky[i];
}
}
String[] vys;
if ( retazec_2.equals(""))
vys = new String[]{ retazec_1 };
else
vys = new String[]{ retazec_1, retazec_2 };
return vys;
}
Uzol spracuj_operand( String retazec) {
char[] znaky = retazec.toCharArray();
Uzol uzol;
if ( znaky.length > 0 ) {
if ( znaky[0] == '$' ) { // odkaz
byte stlpec = (byte)( znaky[1] - 'A' + 1);
if ( stlpec < 1 | stlpec > sirka ) // vadny stlpec
uzol = new Uzol( Typ.Chyba);
else {
if ( znaky.length == 3 | znaky.length == 4 ) {
byte riadok;
if ( znaky.length == 3 ) {
if ( znaky[2] >= '0' & znaky[2] <= '9' )
riadok = (byte)( znaky[2] - '0' );
else
riadok = 0;
}
else {// if ( znaky.length == 4 ) {
if ( znaky[3] >= '0' & znaky[3] <= '9' )
riadok = (byte)( znaky[2] - '0' );
else
riadok = 0;
riadok = (byte)( (znaky[2] - '0') * 10 + (znaky[3] - '0') );
}
if ( riadok < 1 | riadok > vyska ) // vadny riadok
uzol = new Uzol( Typ.Chyba);
else {
Bunka odkaz = tabulka[ stlpec - 1 ][ riadok - 1 ]; // ine indexy, v tabulke od 1, v jave od 0
uzol = new Uzol( odkaz);
}
} else { // vadny cely odkaz
uzol = new Uzol( Typ.Chyba);
}
}
} else { // vzorec s ciselnou hodnotou
int cislo = Integer.parseInt( retazec);
uzol = new Uzol( cislo);
}
}
else
uzol = new Uzol( Typ.Chyba);
return uzol;
}
}
enum Typ { Odkaz, Hodnota, Operator, Chyba };
class Uzol {
public Typ typ;
public Bunka odkaz;
public int hodnota;
public char operator;
public Uzol lavy;
public Uzol pravy;
public Uzol( Bunka odkaz) {
typ = Typ.Odkaz;
this.odkaz = odkaz;
}
public Uzol( int hodnota) {
typ = Typ.Hodnota;
this.hodnota = hodnota;
}
public Uzol( char operator, Uzol lavy, Uzol pravy) {
typ = Typ.Operator;
this.operator = operator;
this.lavy = lavy;
this.pravy = pravy;
}
public Uzol( Typ typ) {
this.typ = typ; // chyba
}
public void print() {
if (typ == Typ.Odkaz) {
//System.out.print(odkaz.stlpec);
System.out.print("odk");
//System.out.print(odkaz.riadok);
} else if (typ == Typ.Hodnota)
System.out.print(hodnota);
else if (typ == Typ.Operator)
System.out.print(operator);
else
System.out.print(typ);
}
public Vysledok spocitaj() {
if ( typ == Typ.Hodnota )
return new Vysledok( hodnota);
else if ( typ == Typ.Operator ) {
Vysledok l = lavy.spocitaj();
Vysledok p = pravy.spocitaj();
Vysledok vys;
if ( l.cislo == false ){
vys = l;}
else if ( p.cislo == false )
vys = p;
else {
int hod;
if ( operator == '+' )
hod = l.hodnota + p.hodnota;
else if ( operator == '-' )
hod = l.hodnota - p.hodnota;
else if ( operator == '*' )
hod = l.hodnota * p.hodnota;
else { // if ( operator == '/' )
if ( p.hodnota == 0 )
return new Vysledok( "#NAN");
hod = l.hodnota / p.hodnota;
}
vys = new Vysledok( hod);
}
return vys;
} else if ( typ == Typ.Odkaz ) {
if ( odkaz == null )
return new Vysledok( "#CHYBA");
else {
if ( odkaz.stav == Stav.Hotova )
return odkaz.vysledok;
else if ( odkaz.stav == Stav.Robena )
return new Vysledok( "#CYKLUS");
else // if ( odkaz.stav == Stav.Spiaca )
return odkaz.spocitaj();
}
} else {// if ( typ == Typ.Chyba )
return new Vysledok( "#CHYBA");
}
}
}
String[][] citaj_subor() throws IOException {
String[][] str_tabulka = new String[sirka][vyska];
String riadok = br.readLine();
byte cislo_riadka = 0;
pocty_stlpcov = new byte[vyska];
while( riadok != null & cislo_riadka < vyska ) {
String[] rozdeleny = riadok.split( ";");
pocty_stlpcov[ cislo_riadka ] = (byte)(rozdeleny.length);
for ( byte i = 0; i < rozdeleny.length & i < sirka; i++ ) {
str_tabulka[ i ][ cislo_riadka ] = rozdeleny[ i ];
if ( ! rozdeleny[ i ].equals("") )
pritomne[ i ][ cislo_riadka ] = true;
}
riadok = br.readLine();
cislo_riadka++;
}
pocet_riadkov = cislo_riadka;
return str_tabulka;
}
class Vysledok {
public boolean cislo;
public int hodnota;
public String retazec;
public Vysledok( int hodnota) {
cislo = true;
this.hodnota = hodnota;
}
public Vysledok( String retazec) {
cislo = false;
this.retazec = retazec;
}
}
public static void main( String[] args) {
if ( args.length == 0 )
System.out.print( "Chyba: nezadane meno suboru!");
else {
String meno_suboru = args[0];
new Tabulkovac( meno_suboru);
}
}
}
Kód: Vybrat vše
5;3;=6+3;=$A1;100
123;;=3+$B1;11;=$C1+$D2;11;;
=$JJ+$B2;=$C3;=$A4
=$B3;=$A1+$B1;=$C1/$B2;=$E1/$F20
Kód: Vybrat vše
5;3;9;5;100
123;;6;11;20;11;;
#CHYBA;#CYKLUS;#CYKLUS
#CYKLUS;8;#NAN;#NAN