Rozszerzenie listy jednokierunkowej

Rozszerzenie listy jednokierunkowej
ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Witajcie, od tygodnia zmagam się z problemem i w końcu nie mam już pomysłów/moja wiedza jest nie wystarczająca.

A więc od początku, JAVY uczę się 5 miesięcy, przerobiłem:
podstawy, wejścia, wyjścia, tabele, stringi, typy enum, no i wprowadzenie w obiektowe i tutaj jest problem. ledwo co nauczyli mnie tworzenia obiektów, już praca na ocenę, która wg mnie wykracza poza obecne możliwości.

Do sedna mam kod:

Kopiuj
class Elementy {
	String dane;
	Elementy nastepny;
	
	void setData(String noweDane) {
		dane = noweDane;
		nastepny = null;
	}
	

	void zalacz(String noweDane) {
		if (nastepny == null) {
			nastepny = new Elementy();
			nastepny.setData(noweDane);
		} else {
			nastepny.zalacz(noweDane);
		}
	}
	
	
	void pokaz() {
		System.out.println(dane);
		if (nastepny != null) {
			nastepny.pokaz();
		}
	}
}



public class Lista {

	public static void main(String[] args) {
		
		Elementy poczatekListy = new Elementy();
		

		poczatekListy.setData("Element 1 ");
		

		for(int i = 2; i < 5; i++) {
			poczatekListy.zalacz("Element " + i);
		}


		poczatekListy.pokaz();
	}

}

i teraz polecenie/a:

  1. Rozszerz program, żeby nie trzeba było cały czas od początku szukać jej końca.
  2. załącz min. 25 elementów
  3. Wyświetl dane od tyłu
    Wskazówki:
  • Musisz obok początku listy, także koniec listy zachować w zmiennej
  • Napisz metodę która zwraca ostatni element listy
  • po wczytaniu danych ustaw koniec listy w zmiennej ostatniElement itd za każdym razem
  • do wyświetlenia od tyłu użyj metody rekurencyjnej

Proszę o pomoc

T0
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:31
1
  1. Rozszerz program, żeby nie trzeba było cały czas od początku szukać jej końca.

W klasie Lista w funkcji main dodaj zmienną koniecListy i po pętli for stwórz Obiekt Elementy dopisz go do zmiennej koniecListy, dodaj mu dane i wykonaj funkcję poczatekListy.zalacz(Elementy) tą funkcję musisz dopisać do Klasy Elementy tak aby można było dodać gotowy obiekt Elementy.

załącz min. 25 elementów

Wystarczy zmienić 5 na 26 w pętli for ale zmień na 25 tak aby po dodaniu elementu koniecListy wyszło 25 elementów.

Wyświetl dane od tyłu

W klasie elementy musisz stworzyć zmienną poprzedni do której będziesz zapisywał poprzedni element podczas dodawania następnego najlepiej zrobić to tak: w funkcji zalacz i funkcji zalacz stworzonej przez ciebie po spełnieniu warunku if pod setData() dodać nastepny.poprzedni = this; Teraz twój program wie który elementy jest przed którym. Następnie stwórz funkcję pokazOdTylu() która będzie działała na tej samej zasadzie co pokaz tylko że musi patrzeć na zmienną poprzedni. no i musisz wykonać ją od końca czyli w klasie Lista w funkcji main dodać koniecListy.pokazOdTylu().

Mam nadzieję że pomogłem jeżeli dalej będziesz miał jakiś problem to wyjaśnię ci to na kodzie który napiszę dla ciebie. Miłej zabawy.

edytowany 1x, ostatnio: Th0ru5
ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Dziękuję za odpowiedź.
Walczyłem z tym kolejne 2h i nic z tego, nie potrafię tego pojąć.
Do rzeczy:

po pętli for stwórz Obiekt Elementy

Jak stworzę go po pętli to wydaje mi się, że poszuka końca dopiero po dodaniu wszystkich danych.
A koniecListy musi być zapamiętywany na bieżąco w osobnej zmiennej (po np. dodaniu elementu), która będzie wykorzystywana w funkcji zalacz() przy dodawaniu kolejnego Elementu.

Następnie stwórz funkcję pokazOdTylu()

Stworzyłem funkcję i próbuję wyświetlić, ale wyświetla mi jedynie "null".
I nie zabardzo rozumiem na jakiej zasadzie zadziała rekurencja wstecz.

Czuję, że krążę wokół rozwiązania a nie mogę go dostrzec.
Mógłbyś mi to wytłumaczyć na podstawie działającego kodu.
Bu muszę to zrozumieć, żeby iść dalej.

Oto próba wyświetlenia:

Kopiuj
package pakiet;

class Elementy {
    String dane;
    Elementy nastepny;
    Elementy poprzedni;
 
    void setData(String noweDane) {
        dane = noweDane;
        nastepny = null;

    }
 
 
    void zalacz(String noweDane) {
        if (nastepny == null) {
            nastepny = new Elementy();
            nastepny.setData(noweDane);
            nastepny.poprzedni = this;
        } else {
            nastepny.zalacz(noweDane);
        }
        nastepny.poprzedni = this;
    }
 
    
    void pokazOdTylu() {
    	 System.out.println(dane);
         if (poprzedni != null) {
             poprzedni.pokazOdTylu();
         }
    }
 
    
    
    void pokaz() {
        System.out.println(dane);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }
}
 
 
 
public class Lista {
 
    public static void main(String[] args) {
 
        Elementy poczatekListy = new Elementy();
        Elementy koniecListy = new Elementy();
        
        poczatekListy.setData("Element 1 ");
 
 
        for(int i = 2; i < 26; i++) {
            poczatekListy.zalacz("Element " + i);
        }
 
        poczatekListy.pokaz();
        koniecListy.pokazOdTylu();
    }
 
}
T0
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:31
1

Usuń z kodu w funkcji zalacz nastepny.poprzedni = this; po else {} zostaw tylko w przypadku gdy warunek w if zostanie spełniony.

Jak stworzę go po pętli to wydaje mi się, że poszuka końca dopiero po dodaniu wszystkich danych.
A koniecListy musi być zapamiętywany na bieżąco w osobnej zmiennej (po np. dodaniu elementu), która będzie wykorzystywana w funkcji zalacz() przy dodawaniu kolejnego Elementu.

W tym przypadku możesz dodać funkcję ostatni do klasy Elementy która będzie sprawdzała czy następny jest null jeżeli tak to zwróci ci this a jeżeli nie to szuka dalej.

Stworzyłem funkcję i próbuję wyświetlić, ale wyświetla mi jedynie "null".
I nie zabardzo rozumiem na jakiej zasadzie zadziała rekurencja wstecz.

Nie działa to poprawnie ponieważ koniecListy jest stworzony ale jako nowy i do niego nie jest nic wpisane.

edytowany 1x, ostatnio: Th0ru5
ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Ok szczeerze mówiąc nie wiem jak mam to zrobić, cały czas krążę bez sensu, doszedłem do tego że:
Zrobiłem funkcje która zwraca adres ostatniego elementu:

Kopiuj
Elementy ostatni() { // znajdz ostatni element
    	
    	if (nastepny != null) {
    		nastepny.ostatni();
        } else {
        	return this;
        }
    	return this;
    }

Ale zwraca go dopiero po tej funkcji:

Kopiuj
void pokaz() {
        System.out.println(dane);
        System.out.println(nastepny);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }

Jak wywołam ostatni() przed nią to nie działa.
Napisałem kod który podaje aktualne adresy:

Kopiuj
package pakiet;

class Elementy {
    String dane;
    Elementy nastepny;
    Elementy poprzedni;
 
    void setData(String noweDane) {
        dane = noweDane;
        nastepny = null;
       
    }
 
 
    void zalacz(String noweDane) {
    	
    	
        if (nastepny == null) {
            nastepny = new Elementy();
            nastepny.setData(noweDane);
            nastepny.poprzedni = this;
        } else {
            nastepny.zalacz(noweDane);
        }
    }
 
    
    Elementy ostatni() { // znajdz ostatni element
    	
    	if (nastepny != null) { // z "poprzedni." tak samo funkcjonuje
    		nastepny.ostatni();
        } else {
        	return this;
        }
    	return this;
    }
    
    
    
    void pokaz() {
        System.out.println(dane);
        System.out.println(nastepny);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }
}
 
 
 
public class Lista {
 
    public static void main(String[] args) {
 
        Elementy poczatekListy = new Elementy();



        
        poczatekListy.setData("Element 1 ");
 
 
        for(int i = 2; i < 11; i++) {
        	
            poczatekListy.zalacz("Element " + i);
            }


        poczatekListy.pokaz();
        
        System.out.println("\n\tTest: obszar z |null| \n\t " 
    			+ "będzie mial adres: |" + poczatekListy.ostatni() + "|");
    System.out.println("###################################");


    
   
        
    }
 
}

I teraz muszę rozbić problem na mniejsze składowe, bo nigdy go nie rozwiążę.

A zatem:

  1. Jak wywołać metodę ostatni(); przed każdym załączeniem nowego elementu. Tak żeby przy załączaniu nowego od razu zapisać go na końcu listy?

Próbuję na różne sposoby ale wynik jest podobny:
Albo załącza mi jedynie 1wszy element i null, albo nic nie robi.

PS: W międzyczasie zacznę od nowa rozdział z tą listą w ćwiczeniach.

edytowany 1x, ostatnio: Stang
T0
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:31
1

Ja zrobiłem to tak.
Główna klasa programu

Kopiuj
public class Main {
	public static void main(String[] args) {
		 
        Elementy poczatekListy = new Elementy();
        Elementy koniecListy = null;
 
        poczatekListy.setData("Element 1");
        
 
        for(int i = 2; i < 26; i++) {
            poczatekListy.zalacz("Element " + i);
        }
        koniecListy = poczatekListy.ostatni(); // <-- pobranie ostatniego elementu z listy.
 
        poczatekListy.pokaz();
        System.out.println("Od tyłu.");
        koniecListy.pokazOdTylu();
    }
}

Klasa Elementy

Kopiuj
class Elementy {
    String dane;
    Elementy nastepny;
    Elementy poprzedni; //<-- zmienna wskazująca na poprzedni Element
 
    void setData(String noweDane) {
        dane = noweDane;
        nastepny = null;
        poprzedni = null;
    }
    Elementy ostatni() // <-- funkcja szukająca ostatniego elementu
    {
    	if(nastepny == null) // <-- jeżeli następny jest null
    		return this;  //<-- zwraca ten obiekt
    	return nastepny.ostatni(); // <-- jeżeli nie szuka dalej
    }
    void zalacz(String noweDane) {
        if (nastepny == null) {
            nastepny = new Elementy();
            nastepny.setData(noweDane);
            nastepny.poprzedni = this; // <-- przypisuje następnemu elementowi zmienną poprzedni jako ten obiekt.
        } else {
            nastepny.zalacz(noweDane);
        }
    }
    void pokaz() {
        System.out.println(dane);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }
    void pokazOdTylu() { // <-- funkcja pokazująca od tyłu zawartość listy
        System.out.println(dane);
        if (poprzedni != null) {
        	poprzedni.pokazOdTylu();
        }
    }

}

Mam nadzieję że teraz już rozumiesz o co chodziło.

ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Ok, dziękuję bardzo za pomoc, jutro rano skomentuje twój kod linijka po linijce i napiszesz mi czy dobrze to pojmuję.
Bo muszę to zrozumieć na 100%.

ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Ok, praktycznie to pojąłem.
Swoją listę miałem napisać teraz w 2ch wersjach

Lista 1:
Pierwsza lista ma załączyć 25 elementów i zawierać:

  1. Zmienną przechowującą ostatni element Elementy koniecListy;
  2. Metodę, która zwraca ostatni element ostatni()
  3. Wywołanie metody przed załączeniem nowego elementu. koniecListy = poczatekListy.ostatni();

Rozwiązanie:

Kopiuj
class Elementy {
    String dane;
    Elementy nastepny;
 
    void setData(String noweDane) {
        dane = noweDane;
        // nastepny = null
        // nastepny jest defaultowo null'em, dlatego mogę to usunąć.
    }
    
    
    Elementy ostatni() // <-- funkcja szukająca ostatniego elementu
    {
        if(nastepny == null) // <-- jeżeli następny jest null
            return this;  //<-- zwraca ten obiekt
        return nastepny.ostatni(); // <-- jeżeli nie szuka dalej
    }
    
    // czy to jest poprawnie wykonane przeze mnie?
    void zalacz(String noweDane, Elementy koniecListy) {
    	koniecListy.nastepny = new Elementy(); // tworze obiekt od razu na końcu listy
    	koniecListy.nastepny.setData(noweDane); // ustawiam dane
    }
    
    
    void pokaz() { // pokazuj aż znajdziesz null
        System.out.println(dane);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }
}

public class ListaX {

	public static void main(String[] args) {

		 Elementy poczatekListy = new Elementy();
	     Elementy koniecListy; // zmienna z ostatnim elementem (defaultowo jest to null)
	 
	     poczatekListy.setData("Element 1"); // ustawienie 1wszego elementu.
	 
	     for(int i = 2; i < 26; i++) {
	        koniecListy = poczatekListy.ostatni(); // Określam ostatni element
	           poczatekListy.zalacz("Element " + i, koniecListy); // przesyłam ostatni element do zalacz()
	     }
	     poczatekListy.pokaz(); // wyświetlenie danych
	}
}

Lista 2:
Wyświetl a dane listy od tyłu używając met. rekurencyjnej.
void pokazOdTylu()

Rozwiązanie:

Kopiuj
class Elementy {
    String dane;
    Elementy nastepny;
    Elementy poprzedni; //<-- zmienna wskazująca na poprzedni Element
 
    void setData(String noweDane) {
        dane = noweDane;
        //poprzedni i nastepny defaultowo są null'ami
    }
    
    
    Elementy ostatni() // <-- funkcja szukająca ostatniego elementu
    {
        if(nastepny == null) // <-- jeżeli następny jest null
            return this;  //<-- zwraca ten obiekt
        return nastepny.ostatni(); // <-- jeżeli nie szuka dalej
    }
    
    
    void zalacz(String noweDane) { //zalaczanie nowych danych
        if (nastepny == null) { // jeśli jest na końcu...
            nastepny = new Elementy(); // ...załącz nowy obiekt
            nastepny.setData(noweDane); //ustaw dane
            nastepny.poprzedni = this; //nastepny = poprzedni (this) - czy tak jest "obrazowo"?
        } else {
            nastepny.zalacz(noweDane); //jeśli nie, od nowa metoda
        }
    }


    void pokaz() {
        System.out.println(dane);
        if (nastepny != null) {
            nastepny.pokaz();
        }
    }
    
    
    void pokazOdTylu() {
        System.out.println(dane);
        if (poprzedni != null) {
            poprzedni.pokazOdTylu();
        }
    }
 
}


public class ListeY {
    public static void main(String[] args) {
 
        Elementy poczatekListy = new Elementy();
        Elementy koniecListy; // null
 
        poczatekListy.setData("Element 1"); // zalączenie 1wszego elemetu
 
        for(int i = 2; i < 26; i++) {
            poczatekListy.zalacz("Element " + i);     
        }
        
        koniecListy = poczatekListy.ostatni(); // <-- pobranie ostatniego elementu z listy.
        //teraz koniecListy wskazuje na ostatni element
        
        poczatekListy.pokaz();
        System.out.println("Od tyłu.");
        koniecListy.pokazOdTylu();
    }
}

Czy masz jakieś podpowiedzi co do składni i wykonania?

edytowany 1x, ostatnio: Stang
T0
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:31
0

Czemu stworzyłeś tą lista 1 ? To też element zadania ? Przecież W lista 2 masz wszystko rozwiązane.

ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Listy są osobno, ponieważ wg zadania mają być 2 osobne projekty.

  1. ma wczytywać dane bezpośrednio na końcu.
  2. ma wyświetlać dane od tylu (jest błąd w liczbie elementów, ma być z powrotem 5 a nie 25)
T0
  • Rejestracja:prawie 14 lat
  • Ostatnio:ponad 8 lat
  • Postów:31
0

no to zrób to tak samo jak w lista 2 tylko usuń odczyt od tyłu a w lista 2 zmień 26 na 5 i powinno być ok

ST
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:75
0

Tak zrobiłem, dziękuję bardzo za pomoc:)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)