Programovanie (2) v Jave
1-INF-166, LS 2016/17

Úvod · Pravidlá · Prednášky · Projekt · Netbeans · Odovzdávanie · Test a skúška
· Vyučujúcich môžete kontaktovať pomocou e-mailovej adresy E-prg.png (bude odpovedať ten z nás, kto má príslušnú otázku na starosti alebo kto má práve čas).
· Predvádzanie projektov bude v pondelok 5.6. od 9:00 do 12:00 a v utorok 6.6 od 12:00 do 13:30 (po skúške), oboje v miestnosti M217. Na termín sa prihláste v AIS. Ak robíte vo dvojici, prihlási sa iba jeden člen dvojice.
· Body zo záverečného testu sú na testovači. Poradie príkladov: P1: do šírky, P2: topologické, P3: výnimky, P4: iterátor, P5: testy, P6: strom. Bolo potrebné získať aspoň 20 bodov zo 40.
· Opravný test bude 19.6.2017 od 9:00 v miestnosti M-I. Na termín sa prihláste v AISe.
· Zapisovanie známok a osobné stretnutia ku skúške budú v utorok 13.6. 13:30-14:30 v M163 a v stredu 14.6. 14:00-14:30 v M163.


Cvičenia 8

Z Programovanie
Prejsť na: navigácia, hľadanie

Cieľom týchto cvičení je precvičiť si prácu so súbormi a s načítavaním vstupu a výstupu.

Načítanie jednoduchých výrazov

Napíšte program, ktorý otvorí súbor vyrazy.txt, v ktorom sú na každom riadku tri údaje oddelené medzerami: desatinné číslo, znamienko (jedno z +, -, *, /) a druhé desatinné číslo. Postupne načítavajte tento súbor príkazom fscanf a na konzolu vypisujte výrazy aj s výslednou hodnotu. Na vypisovanie čísel typu double skúste použiť formát %g v príkaze printf. Príklad:

Vstup (uložte do súboru vyrazy.txt v adresári s projektom):

1.5 + 3
-7 - -8.1
3 / 2

Výstup (konzola):

1.5 + 3 = 4.5
-7 - -8.1 = 1.1
3 / 2 = 1.5

Urezanie riadkov

  • Napíšte program, ktorý vypíše súbor vstup.txt na obrazovku tak, že všetky riadky dlhšie ako 80 znakov ureže na 80-tom stĺpci.
    • Váš program by mal fungovať aj pre súbory s veľmi dlhými riadkami

Porovnanie súborov

  • Napíšte program, ktorý od užívateľa načíta názvy dvoch súborov a potom zistí, či tieto dva súbory majú rovnaký obsah.
    • Pozor na prípad, keď súbory nie sú rovnako dlhé

Štatistika

  • Stiahnite si textový súbor [1], ktorý obsahuje frekvenciu, s akou užívatelia vyhľadávali výraz ice cream v Googli v jednotlivých týždňoch rokov 2004 až 2010. Každý riadok obsahuje údaje o jednom týždni: prvé tri slová sú dátum, štvrté relatívna frekvencia.
  • Načítajte tento súbor do poľa záznamov so štruktúrou
struct tyzden {
  char mesiac[4];
  int den;
  int rok;
  double frekvencia;
};
  • Vypíšte na konzolu, v ktorom týždni bola frekvencia vyhľadávania najvyššia.
  • Pre každý rok od 2004 po 2010 spočítajte súčet frekvencií a vypíšte na konzolu v prehľadnom tvare, na dve desatinné miesta:
2004 63.14
2005 62.14
...
2010 72.02

Šifrovanie permutačnou šifrou

  • Napíšte funkciu, ktorá zašifruje vstupný súbor tak, že v každom bloku dĺžky n povymieňa polohu znakov podľa zadaného kľúča. Kľúč je pole A dĺžky n, kde A[i] uvádza, ktoré písmeno z pôvodného bloku má ísť na i-te miesto v zašifrovanom bloku. Napr. pre n=4 a A={3,2,0,1} dostaneme pre blok "ABCD" výsledok "DCAB", lebo na pozíciu 0 vo výsledku sme dali písmeno na pozícii A[0] = 3, t.j. D, atď. Ak v poslednom bloku nemáme dosť písmen, doplníme ich medzerami. Hlavička funkcie: void encryptPermutation(FILE *f, int n, int A[]);
  • Pre dešifrovanie môžeme použiť tú istú funkciu, akurát kľúč musíme zmeniť z pôvodnej permutácie A na novú permutáciu B tak, že B[A[i]]=i pre každé i. Napr. pre príklad vyššie to bude B={2,3,1,0}
  • Vyskúšajte touto šifrou zašifrovať a potom spätne odšifrovať krátky text.

Formátovanie

  • Do súboru vypíšte tabuľku hodnôt funkcie sin(x) pre x od -1 po 1 s krokom 0.2, pričom ich bude vypisovať na 5 desatinných miest a x aj sin(x) budú zarovnané doprava:
-1.0 -0.84147
-0.8 -0.71736
-0.6 -0.56464
-0.4 -0.38942
-0.2 -0.19867
-0.0 -0.00000
 0.2  0.19867
 0.4  0.38942
 0.6  0.56464
 0.8  0.71736
 1.0  0.84147

Riešenia

Riešenie vybraných príkladov v jednom programe.

#include <cstdio>
#include <cmath>
using namespace std;

void spracujVyrazy(FILE *f) {
    while (true) {
        double a, b;
        char operacia;
        if (fscanf(f, "%lf %c %lf", &a, &operacia, &b) == 3) {
            double vysledok;
            switch (operacia) {
            case '+':
                vysledok = a + b;
                break;
            case '-':
                vysledok = a - b;
                break;
            case '*':
                vysledok = a * b;
                break;
            case '/':
                vysledok = a / b;
                break;
            }
            printf("%g %c %g = %g\n", a, operacia, b, vysledok);
        }
        else {
            // nepodarilo sa nacitat
            break;
        }
    }
}

void urezeKoniec(FILE * f, int maxDlzka) {
    int dlzka = 0; // dlzka aktualneho riadku
    int c = getc(f); // nacitame znak
    while (c != EOF) { // spracujeme po znakoch
        if (c == '\n') { // precitali sme koniec riadku
            putchar(c); // vytlacime koniec riadku
            dlzka = 0; // vynulujeme dlzku
        }
        else { // citali sme nejaky znak
            dlzka++; // zvysime pocitadlo dlzky
            if (dlzka <= maxDlzka) putchar(c); // ak sme este nedosiahli maxDlzka znakov, tak vypiseme znak c
        }
        c = getc(f); // nacitame dalsi znak
    }
}


bool porovnajObsah(FILE * subor1, FILE * subor2) {
    int c1 = getc(subor1);
    int c2 = getc(subor2);
    while (c1 != EOF && c2 != EOF) {
        if (c1 != c2) return false;
        c1 = getc(subor1);
        c2 = getc(subor2);
    }
    if (c1 != c2) return false;
    return true;
}


int main() {
    // ULOHA: spracovanie jednoduchych vyrazov
    FILE *vyrazy  = fopen("vyrazy.txt", "r");
    spracujVyrazy(vyrazy);
    fclose(vyrazy);

    // ULOHA: riadky dlhšie ako x znakov ureže
    FILE * uloha1 = fopen("vstup.txt", "r");
    urezeKoniec(uloha1, 10);
    fclose(uloha1);

    printf("\n\n");

    // ULOHA: zistí ci dva súbory majú rovnaký obsah
    char subor1nazov[20], subor2nazov[20]; // pozor na dlhe nazvy :)
    printf("Zadaj nazov suborov: \n");
    scanf("%s %s", subor1nazov, subor2nazov);
    FILE * subor1 = fopen(subor1nazov, "r");
    FILE * subor2 = fopen(subor2nazov, "r");
    if (porovnajObsah(subor1, subor2)) printf("rovnake\n");
    else printf("rozne\n");
    fclose(subor1);
    fclose(subor2);

    printf("\n\n");

    // ULOHA: tabulka hodnot funkcie sin(x)
    for (double i = -1; i <= 1; i += 0.2) {
        double sinx = sin(i);
        printf("% .1lf % .5lf\n", i, sinx);
    }

    return 0;
}