Zadanie z choinką w Javie

0

Mam za zadanie zrobić rekurencyjnie choinkę z gwiazdek, o podanej przez użytkownika podstawie. Ostatecznie liczba * w podstawie ma być wpisywana w pliku In.txt, na razie user wpisuje w terminalu. Bardziej martwi mnie to, że gdy chcę, aby choinka była rysowana w pliku, a nie w terminalu. Wychodzi tak:
screenshot-20211104222109.png
zamiast:
screenshot-20211104222233.png

Co robię źle?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Choinka {
    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("In0101.txt");
        PrintWriter zapis = new PrintWriter("Out0101.txt");
        Scanner in = new Scanner(file);
        System.out.println("Podaj liczbe gwiazdek w podstawie: ");
        int podstawa = getInt();
        int gora = podstawa % 2 == 0 ? 2 : 1;
        for (int rzad = gora;
             rzad <= podstawa;
             rzad += 2) {
            int liczbaSpacji = (podstawa - rzad) / 2;
            for (int i = 0; i < liczbaSpacji + rzad; i++) {
                System.out.print(i < liczbaSpacji ? " " : "*");
            }
            System.out.println();
        }
        zapis.close();
    }
    public static int getInt() {
        return new Scanner(System.in).nextInt();
    }
}
1

Początkowo myślałem, że System.out.print dodaje nową linię na końcu, bo tak wynika z Twojego postu, ale odpaliłem ten program i choinka zrobiła się dobrze w terminalu. Możliwe, że jest to jakaś kwestia systemowa i Twój terminal inaczej wyświetla output lub przetwarza znaki końca linii. Nie wiem, czy nieprawidłowy output masz w pliku, czy w terminalu. Jeśli tylko w pliku, to po prostu posklejaj całego stringa z choinką i zamiast używać funkcji System.out.print i println, a potem wstaw tego stringa do pliku. Zamiast system.out.println użyj znaku nowej linii, tj. \n. Jak korzystasz z windowsa, to będzie to bodajże \r\n.

1

Gdzie tutaj jest rekurencja?

0

@wiciu: Przepraszam, trochę namieszałem, co innego napisałem, nieco inny kod wkleiłem. Tak jak piszesz, w terminalu jest ok. Ale jak zmienię System.out.print na zapis.println, to w pliku gwiazdki są pionowo, tak jak na screenie wyżej

2

O takie coś sobie popełniłem ;)

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        //O to pytasz usera - czyli szerokość podstawy
        int maxWidth = 20;

        int initialWidth = 1;
        int initialLevel = 1;
        int maxLevel = (maxWidth + 1) /2;
        int freeSpace = maxLevel - 1;

        printChristmasTree(initialWidth, initialLevel, maxLevel, freeSpace);
    }

    static void printChristmasTree(int width, int level, int maxLevel, int freeSpace){
        if(level < maxLevel){
            System.out.print(Stream.generate(() -> " ").limit(freeSpace).collect(Collectors.joining()));
            System.out.print(Stream.generate(() -> "*").limit(width).collect(Collectors.joining()));
            System.out.println();
            printChristmasTree(width= width + 2, ++level, maxLevel, --freeSpace);
        } else {
            System.out.print(Stream.generate(() -> " ").limit(freeSpace).collect(Collectors.joining()));
            System.out.print(Stream.generate(() -> "*").limit(width).collect(Collectors.joining()));
        }
    }
}
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
0

W kodzie @.andy dodałem opcję odczytu z pliku (podstawy) i zapisu choinki do pliku. Jest jeden problem - choinka nie wygląda prawidłowo - przypomina bardziej trójkąt prostokątny.
Co poszło nie tak?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class Main {

    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("In0103.txt");
        Scanner in = new Scanner(file);
        int maxWidth = in.nextInt();
        int initialWidth = 1;
        int initialLevel = 1;
        int maxLevel = (maxWidth + 1) / 2;
        int freeSpace = maxLevel - 1;

        printChristmasTree(initialWidth, initialLevel, maxLevel, freeSpace, null);
    }

    static void printChristmasTree(int width, int level, int maxLevel, int freeSpace, PrintWriter save) throws FileNotFoundException {
        if (save == null) {
            save = new PrintWriter("Out0103.txt");
        }
        if (level < maxLevel) {
            save.println(Stream.generate(() -> " ").limit(freeSpace).collect(Collectors.joining()));
            save.println(Stream.generate(() -> "*").limit(width).collect(Collectors.joining()));
            save.println();
            printChristmasTree(width = width + 2, ++level, maxLevel, --freeSpace, save);
        } else {
            save.println(Stream.generate(() -> " ").limit(freeSpace).collect(Collectors.joining()));
            save.println(Stream.generate(() -> "*").limit(width).collect(Collectors.joining()));
            save.close();
        }

    }
}
1

Na szybko:

        if (save == null) {
            save = new PrintWriter("Out0103.txt");
        }

A wcześniej przekazujesz mu nulla zamiast referencji na PrintWritera:

printChristmasTree(initialWidth, initialLevel, maxLevel, freeSpace, null);

Dlaczego od razu nie przekazać mu referencji do tego gdzie ma pisać? Po co tworzyć plik wyjściowy w tej metodzie jeżeli nie istnieje?

Dlaczego zmieniłeś print na println?
save.println(Stream.generate(() -> " ").limit(freeSpace).collect(Collectors.joining()));

W ten sposób po wydrukowaniu spacji dodawany jest znak nowej linii i potem drukowane są gwiazdki w nowej linii i dlatego choinka nie wygląda jak powinna.

Tak wygląda choinka po tych drobnych poprawkach:
screenshot-20211109210647.png

PS Ten kod generuje tylko choinki z jedną gwiazdką na czubku ;) Trzeba to poprawić.

Ogólnie przy zapisie do pliku to bym to zrobił inaczej niż jest teraz, ale nie chce mi się już dzisiaj tego robić.

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