Poprawność choinki metoda

0

Cześć, (jestem początkujący jak widać po zadaniu... i mam mały problem) Stworzyłem choinkę w osobnej klasie i zapisałem ją do pliku. Teraz odczytuje choinkę w kolejnej klasie w tym przypadku public class OdczytChoinki i musze zweryfikować czy tak choinka ma odpowiednią ilość gwiazdek "*" i odpowiednią ilość spacji " " w wierszu. .
Logicznie wiem jak to ma wyglądać ale nie umiem napisać warunku w javie. W sensie jak odczytać z pliku tą ilość spacji i ilość gwiazdek w każdym wierszu....

 Dla przykładu 
 Wysokość choinki = 4
     *
    ***
   *****
  *******

public class OdczytChoinki {

// Wyobrażam sobie to tak:
// jeśli choinka ma wysokość 2 to liczba wierszy = 2
// jeśli choinka ma wysokość 3 to liczba wierszy= 3
// jeśli choinka ma wysokość 4 to liczba wierszy = 4
//
// jeśli choinka ma wysokość 2 to liczba spacji = to w 1 wierszu są 2 spacje, a w drugim 1.
// jeśli choinka ma wysokość 3 to liczba spacji = to w 1 wierszu są 3 spacje, w drugim 2, a w trzecim 1.
// jeśli choinka ma wysokość 4 to liczba spacji = to w 1 wierszu są 4 spacje, w drugim 3, a w trzecim 2, a w czwartym 1.

 // jeśli choinka ma wysokość 2 to liczba gwiazdek = to w 1 wierszu są 1 gwiazdka, a w drugim 3.
 // jeśli choinka ma wysokość 3 to liczba gwiazdek = to w 1 wierszu są 1 gwiazdka, w drugim 3, a w trzecim 5.
 // jeśli choinka ma wysokość 4 to liczba gwiazdek = to w 1 wierszu są 1 gwiazdka, w drugim 3,  w trzecim 5, a w czwartym 7,.

// Tutaj jest tylko odczyt z pliku tej choinki po znaku, wydaje mi się że to będzie najlepsze rozwiązanie tylko jak ten warunek napisać..

  boolean verifyChristmasTreeFromFile(String file) throws IOException {
     FileReader odczyt = new FileReader(file);
      int znak;
      while ((znak = odczyt.read()) != -1) {
          System.out.println((char) znak);
      }
      odczyt.close();

      if () return true; // nie wiem jak stworzyć te warunki. 
  }

}

1

Zacznij od przetwarzania pliku linia po linii.

1

Ogólnie to weryfikacja choinki jest prosta - tylko trzeba czytać linia po linii.

  1. Choinka ma jeden parametr - wysokość h.
  2. Każda linia (oznaczmy numer linii - l) składa się z:
  • nieujemnej liczby pustych znaków (spacji) - n. Dla linii nr. l n(l) = h-l
  • nieujemnej liczby gwiazdek - k. Dla linii nr. l - k(l) = 2(l-1)+1

Teraz żeby zweryfikować, czy choinka jest narysowana poprawnie:

  1. Czytasz pierwszą linię. Jeśli ma ona więcej niż jedną gwiazdkę - to choinka jest nieprawidłowa. Jeśli ma tylko jedną gwiazdkę - to wyliczasz z tego h, czyli liczysz, ile jest spacji przed gwiazdką i dodajesz 1.
  2. Znając h jesteś w stanie wyznaczyć, ile powinno być najpierw spacji, potem gwiazdek za pomocą podanych wzorów.
  3. Czytasz linie, i sprawdzasz, aż dojdziesz do oczekiwanego dołu.
  4. Jeśli trzeba - to sprawdzasz, czy pod spodem nic nie ma.

Np.


// Choinka #1:
  *
 ***
*****

- zaczynamy z linii nr. 1. Wyznaczamy h -> są dwie puste spacje, więc h=3
- przechodzimy do linii nr. 2. Powinno być n(2) = h-2, czyli 1 spacja, i k(2) = 2*1+1 = 3 gwiazdki. Jest OK
- przechodzimy do linii nr. 3. Powinno być n(3) = h-3, czyli 0 spacji, i k(3) = 2*2+1 = 5 gwiazdek. Jest OK.
0

Mały update. Stworzyłem coś takiego. Wiem wpisane ręcznie te gwizdki... Wszystko działa tylko dużo jest wpisywania ręcznego. Jak można zrobić to lepiej aby działało bardziej automatycznie niż ręcznie ?

   public static boolean verifyChristmasTreeFromFile(String file) throws IOException {
    List<String> lines = Files.readAllLines(Path.of(file));
    int count1 = 0; // pierwsza linijka zliczania spacji.
    for (int i = 0; i < lines.get(0).length(); i++) {
        if (Character.isWhitespace(lines.get(0).charAt(i)))
            count1++;
    }
    int count2 = 0; // druga linijka zliczania spacji.
    for (int i = 0; i < lines.get(1).length(); i++) {
        if (Character.isWhitespace(lines.get(1).charAt(i)))
            count2++;
    }
    int count3 = 0; // trzecia linijka zliczania spacji.
    for (int i = 0; i < lines.get(2).length(); i++) {
        if (Character.isWhitespace(lines.get(2).charAt(i)))
            count3++;
    }

    lines.size(); // To jest h;
    int h = lines.size(); // h = 3.

    if (lines.get(0).contains("*") && count1 == h) {
        h--;
        if (lines.get(1).contains("***") && count2 == h) {
            h--;
            if (lines.get(2).contains("*****") && count3 == h) {
                return true;
            } else return false;
        } else return false;
    } else return false;
}
0

Próbowałem zrobić to w pętli. Czyli pierwszą linijke czytam ile ma spacji a potem tylko odejmuje po jednej spacji. Z gwiazdkami jest tak samo jeśli pierwsza linijka zawiera "*" to potem dodaje kolejne 2 do każdej linijki. Tylko wyskakuje false zamiast true. Podejrzewam że to przez te gwiazdki gdyż
w zmiennej iloscGwiazdekWPierwszejLinii to tutaj zliczam cyfry a nie dosłownie gwiazdki. Jak można to naprawić ? ;/

List<String> lines = Files.readAllLines(Path.of("Choinka.txt"));

       int count1 = 0; // pierwsza linijka zliczania spacji.
       for (int i = 0; i < lines.get(0).length(); i++) {
           if (Character.isWhitespace(lines.get(0).charAt(i)))
               count1++;
       }
       System.out.println(count1);

    lines.size(); // To jest h;
    int h = lines.size(); // h = 3.
    int iloscSpacjiWPierwszejLinii = count1;
    int iloscGwiazdekWPierwszejLinii = 1;

    for (int i = 0; i < lines.size(); i++) {
        if (lines.get(i).equals(iloscSpacjiWPierwszejLinii) && lines.get(i).equals(iloscGwiazdekWPierwszejLinii)){
            iloscSpacjiWPierwszejLinii--;
            iloscGwiazdekWPierwszejLinii++;
            iloscGwiazdekWPierwszejLinii++;
            System.out.println(true);
        }else System.out.println(false);
    }
}
0

@KotAli: rozbij to na czynniki pierwsze, będzie ci łatwiej.

  1. Napisz sobie oddzielne metody, które policzą ci ile jest spacji, a ile gwiazdek w danej linii, oraz ile ich być powinno:
private static int countWhitespacesInLine(String line) {
    // ... kod
}

private static int countStarsInLine(String line) {
    // ... kod
}

private static int calculateWhitespaces(int lineNumber, int height) {
    // ... kod
}

private static int calculateStars(int lineNumber) {
    // ... kod
}
  1. Dopisz metodę, która zweryfikuje ci linijkę:
private static boolean verifyLine(String line, int lineNumber, int height) {
    return calculateWhitespaces(lineNumber, height) == countWhitespacesInLine(line) 
       && calculateStars(lineNumber) == countStarsInLine(line);
}
  1. I potem już normalnie lecisz:

        int height = //... costam;

        for (int i=0; i<lines.size(); i++) {
            if (!verifyLine(lines.get(i), i+1, height)) {
                 System.out.println("Christmas tree invalid");
                 break;
            }
        }

1 użytkowników online, w tym zalogowanych: 0, gości: 1