Trójwymiarowa tablica

0

Witam wszystkich,
Chciałbym prosić o pomoc w naprowadzeniu mnie na rozwiązanie ćwiczenia. Nie umiem sobie wyobrazić jak dokładnie ma wyglądać ta tablica. Uczę się javy i zadanie jest takie:

Utwórz trójwymiarową tablicę dla wartości typu int (będzie to struktura, którą można
sobie wyobrazić jako prostopadłościan składający się z sześcianów; każdy sześcian będzie
pojedynczą komórką). Powinna umożliwiać przechowywanie trzydziestu wartości.
Poszczególne komórki wypełnij liczbami od 30 do 59. Zawartość wyświetl na ekranie.

Ja zacząłem tak:

int tab[][][]=new int[31][30][30];
int wypelniacz=30;

		for (int i=0; i<tab.length; i++)
		{
			
			for (int j=0; j<tab[j].length; j++)
			{	wypelniacz=30;
				for (int k=0; k<tab[k].length; k++)
				{
				tab[i][j][k]=wypelniacz++;

					
				}				
			}
			
		}
		for (int i=0; i<tab.length; i++)
		{
			
			for (int j=0; j<tab[j].length; j++)
			{	
				for (int k=0; k<tab[k].length; k++)
				{wypelniacz=30;
				tab[i][j][k]=wypelniacz++;
System.out.println("Rząd "+i+" komórka 1 "+j+" komórka2 "+k+" "+tab[i][j][k]);
					
				}				
			}
			
		}

Będę wdzięczny za pomoc

0

Skoro tablica ma pomieścić 30 wartości to przykładowe rozmiary: new int[2][3][5].

1

Jak powyżej, Poprawione również granice pętli:

int tab[][][]=new int[5][3][2];
int wypelniacz=30;
  System.out.println(tab.length); // -> 5
   System.out.println(tab[0].length); // -> 3
    System.out.println(tab[0][0].length); // -> 2
        for (int i=0; i<tab.length; i++)
        {

            for (int j=0; j<tab[j].length; j++)
            {   
                for (int k=0; k<tab[k][j].length; k++)
                {
                tab[i][j][k]= wypelniacz++;
                }               
            }

        }
  
          for (int i=0; i<tab.length; i++)
        {

            for (int j=0; j<tab[j].length; j++)
            {   
                for (int k=0; k<tab[k][j].length; k++)
                {
                
System.out.println("Rząd "+i+" komórka 1 "+j+" komórka2 "+k+" "+tab[i][j][k]);

                }               
            }

        }
0

Dzięki wielkie za odpowiedź :) Pytanie, dlaczego rozmiar w 3 pętli jest j i k?

1

Tak to jest w trójwymiarowych tablicach, wydrukowałem Ci nawet, dydaktycznie, kolejne rozmiary:) Jak sobie to Wyobrazisz, jako pięć ułożonych na sobie prostokątów 3 x 2, zaimplementowane jest to tak, że nazwa tablicy to pierwszy wymiar (5), pierwszy bok prostokąta (tab[0]) to 3 i drugi bok (tab[0][0] lub tab[j][k], nieważne byleby w zasięgu) to 2.

0
lion137 napisał(a):

Tak to jest w trójwymiarowych tablicach, wydrukowałem Ci nawet, dydaktycznie, kolejne rozmiary:) Jak sobie to Wyobrazisz, jako pięć ułożonych na sobie prostokątów 3 x 2, zaimplementowane jest to tak, że nazwa tablicy to pierwszy wymiar (5), pierwszy bok prostokąta (tab[0]) to 3 i drugi bok (tab[0][0] lub tab[j][k], nieważne byleby w zasięgu) to 2.

Miałbym jeszcze jedno pytanie, ale jeśli można to bez pisania kodu, po prostu nie do końca rozumiem jak ma wyglądać ta tablica. Polecenie jest takie:

Utwórz tablicę dwuwymiarową, w której liczba komórek w kolejnych rzędach będzie
równa dziesięciu kolejnym wartościom ciągu Fibonacciego, poczynając od elementu
o wartości 1 (1, 1, 2, 3, 5 itd.). Wartość każdej komórki powinna być jej numerem w danym
wierszu w kolejności malejącej (czyli dla wiersza o długości trzech komórek kolejne
wartości to 3, 2, 1). Zwartość tablicy wyświetl na ekranie.

Czy ja mam wyświetlić wszystkie wartości komórek w każdym rzędzie, do wartości ciągu Fibonacciego? (czyli kolejne rzędy mają mieć długosć 1,1,2,3,5,8, itd)?

1

Tak, tylko, że to nie będzie tablica dwuwymiarowa n x m, bo w każdym (prawie) wierszu będzie inna ilość elementów; to będzie lista list;
[[1], [1], [2, 1], [3, 2, 1], [5, 4, 3, 2, 1], [8, 7, ....., 1], ..., [55, 54, ..., 1]]

0
lion137 napisał(a):

Tak, tylko, że to nie będzie tablica dwuwymiarowa n x m, bo w każdym (prawie) wierszu będzie inna ilość elementów; to będzie lista list;
[[1], [1], [2, 1], [3, 2, 1], [5, 4, 3, 2, 1], [8, 7, ....., 1], ..., [55, 54, ..., 1]]

Czyli chodzi o coś takiego?

tab [0] = 1
tab [1] = 1
tab [2] = 1 2
tab [3] = 1 2 3
tab [4] = 1 2 3 4 5
tab [5] = 1 2 3 4 5 6 7 8

Tylko tutaj deklarowałem długość wierszy na początku, a rozumiem że muszę to zrobić "automatycznie"

0

Poddaję się, nie wiem jak zrobić żeby kolejne długości rzędów były sumą dwóch poprzednich. Zrobiłem jedynie z deklaracją długości, na razie do 6 rzędu

int tab[][]=new int[6][];
		tab[0]=new int[1];
		tab[1]=new int[1];
		tab[2]=new int[2];
		tab[3]=new int[3];
		tab[4]=new int[5];
		tab[5]=new int[8]; 
		int b;
		int wypelniacz=1;
		/* dla rzędu 0: */ 
		for (int i=0; i<tab.length; i++)
		{ 
			
			wypelniacz=tab[i].length;
			for (int j=0; j<tab[i].length; j++)
			{ 
				if (i==1||i==2)
				{
					
					tab[i][j]=1;	
				}
			
					tab[i][j]=wypelniacz--; 
							
				}
			}
		
		for (int i=0; i<tab.length; i++)
		{
			System.out.print("tab ["+i+"] = ");
			for (int j=0; j<tab[i].length; j++)
			{
			
				if (wypelniacz==1||wypelniacz==2)
				{
					tab[i][j]=1;
					System.out.print(tab[i][j]+" ");
				}
				
			
				System.out.print(tab[i][j]+" ");
								
			}
			System.out.print("\n");
		}
		
		
	}
}
0

Zrób to po ludzku - poszukaj gotowca na n-ty wyraz ciągu Fibonacciego.

int fib(int n) { 
   if (n <= 1) 
      return n; 
   return fib(n-1) + fib(n-2); 
} 

Ta funkcja wyżej zwraca ci n-ty element ciągu. Użyj sobie tej funkcji.

0
szweszwe napisał(a):

Zrób to po ludzku - poszukaj gotowca na n-ty wyraz ciągu Fibonacciego.

int fib(int n) { 
   if (n <= 1) 
      return n; 
   return fib(n-1) + fib(n-2); 
} 

Ta funkcja wyżej zwraca ci n-ty element ciągu. Użyj sobie tej funkcji.

Tak właśnie zrobiłem, ale nie umiem tego zapisać dla rozmiaru rzędu tablicy. tab[i].length=?

0

Pewnie takie coś:

int[][] arr = new int[10][];
   for(int i = 0; i < 10; i++) {
      arr[i] = new int[fib(i+1)];
}

robi to co chcesz, ale nie wiem jak bardzo głupie jest to rozwiązanie, bo głupie na pewno jest.


edytowane bo to rzeczywiście java miała być :]

0

Ja to widzę tak: Trzeba by w pętli od 1 do 10 tworzyć listy o długości kolejnego elementu ciągu Fibonacciego i dodawać je do wynikowej listy, jakiś pseudokod:

def fibo(n):
	if n == 0: return 0
	if n == 1: return 1
	else:
		return fibo(n - 1) + fibo(n - 2)

def fibo_list():
	out = []
	from n = 1 to 10:
		out.append(nth_list(fibo(n)))
	return out

def nth_list(n):
	return list of length n in form: n, n -1, n - 2, 1

Napisanie funkcji nth_list nie powinno sprawić problemów. Proof of concept, że to działa w Pythonie (Wciśnij run): https://repl.it/repls/UnsightlySympatheticRepository

0
lion137 napisał(a):

Ja to widzę tak: Trzeba by w pętli od 1 do 10 tworzyć listy o długości kolejnego elementu ciągu Fibonacciego i dodawać je do wynikowej listy, jakiś pseudokod:

def fibo(n):
	if n == 0: return 0
	if n == 1: return 1
	else:
		return fibo(n - 1) + fibo(n - 2)

def fibo_list():
	out = []
	from n = 1 to 10:
		out.append(nth_list(fibo(n)))
	return out

def nth_list(n):
	return list of length n in form: n, n -1, n - 2, 1

Napisanie funkcji nth_list nie powinno sprawić problemów. Proof of concept, że to działa w Pythonie (Wciśnij run): https://repl.it/repls/UnsightlySympatheticRepository

Do takich funkcji jeszcze nie doszedłem, niemniej dzięki za odpowiedzi :)

0

Powracam z kolejnym pytaniem, bo nie rozumiem polecenia. Polecenie jest takie:

W klasie Punkty2 z listingu 3.8 zmień kod metod ustawX i ustawY, tak aby zwracały one poprzednią
wartość zapisywanych pól. Zadaniem metody ustawX jest więc zmiana wartości
pola x i zwrócenie jego poprzedniej wartości. Metoda ustawY ma wykonywać analogiczne
czynności w stosunku do pola y.

kod z tego listingu (po mojej modyfikacji) jest taki:

class Punkty2
{
	int x;
	int y;
	
	void ustawX(int wspX)
	{
		x=wspX;
	}
	void ustawY(int wspY)
	{
		y=wspY;
	}
	
	void ustawXY(Punkty2 wywolanie1)
	{
		x=wywolanie1.x;
		y=wywolanie1.y;
	}
	
	Punkty2 pobierzWspolrzedne()
	{
		Punkty2 wywolanie1= new Punkty2();
		wywolanie1.x=x;
		wywolanie1.y=y;
		return wywolanie1;
	}
	void wyswietlWspolrzedne()
	{
		System.out.println("X: "+x);
		System.out.println("Y: "+y);
	}
}

Co ja tu muszę zmienić, jakie poprzednie wartości? Tam są jedne wartości ustalane na końcu. Jeśli można, proszę o odpowiedź bez kodu

1

W razach zadanie musisz zmienić Punkty2 tak, żeby można było zrobić coś takiego:

public static void main(String... strings){
    Punkty2 punkty2 = new Punkty2();
    punkty2.ustawX(5);
    punkty2.ustawY(2);

    int poprzednieX = punkty2.ustawX(33);
    int poprzednieY = punkty2.ustawY(26);

    System.out.println("Poprzednie X: " + poprzednieX);
    System.out.println("Poprzednie Y: " + poprzednieY);
    System.out.println("Obecne X: " + punkty2.x);
    System.out.println("Obecne Y: " + punkty2.y);
}

Ma się wyświetlić:

Poprzednie X: 5
Poprzednie Y: 2
Obecne  X: 33
Obecne Y: 26
0
Tyvrel napisał(a):

Dzięki za odpowiedź, to właśnie chciałem zrobić. A czy poprawne jest też to, czy to nie o to chodziło?

public class cw144
{
	public static void main(String[]args)
	{
	Punkty wywolanie1 = new Punkty();
	Punkty wywolanie2 = new Punkty();
	
	wywolanie1.ustawX(4);
	wywolanie1.ustawY(5);
	wywolanie2.ustawX(12);
	wywolanie2.ustawY(15);
	
	wywolanie1.wyswietlXY();
	wywolanie2.wyswietlXY();
	}
}
1

Nie. W treści zadanie jest, że ustawX i ustawY ma zwracać stare wartości.
Traktuj mój post jako test. Musisz zmienić Punkty2 tak, żeby ten test przeszedł

0
Tyvrel napisał(a):

Nie. W treści zadanie jest, że ustawX i ustawY ma zwracać stare wartości.
Traktuj mój post jako test. Musisz zmienić Punkty2 tak, żeby ten test przeszedł

Poddaję się, doszedłem do tego ale nie wiem jak zadeklarować x i y w klasie main:

class Punkty
{
	int x;
	int y;
	
	int ustawX(Punkty wywolanie1)
	{
		int old=this.x;
		wywolanie1.x=this.x;
		return old;
	}
	int ustawY(Punkty wywolanie1)
	{
		int old=this.y;
		wywolanie1.y=this.y;
		return old;
	}
		
	void wyswietlXY()
	{
		System.out.println(x);
		System.out.println(y);
	}
}
0

Nie wiem jak wygląda twój main i co chcesz w nim zrobić. Podaj więcej danych, to może się uda pomóc bez podawania gotowego kodu (tak jak chciałeś)

W twojej implementacji dziwne jest, to że do metody ustawX przekazujesz cały obiekt punkty

Z tego wynika, że masz dwa obiekty punkty:

Punkty punktA= new Punkty();
punktA.x = 1
punktB.y = 2;

Punkty punktB= new Punkty();
punktA.x = 3;
punktB.y = 4;

punktA.wyswietlXY(); //1, 2
punktA.wyswietlXY(); //3, 4

przyjmijmy teraz, że wywołujesz metodę:
punktA.ustawX(punktB));

Co robi twoja metoda?

    int ustawX(Punkty wywolanie1) //wywołanie1 to punktB, czyli (3,4)
    {
        int old=this.x; //tworzysz zmienną lokalną odczytując z obecnego obiektu x. this to punktA, czyli this.x to 1. Czyli old wynosi 1
        wywolanie1.x=this.x; // this to punktA, czyli this.x to 1. wywołanie1 to punktB, czyli wywolanie1.x to 3. W tej linijce zmieniasz wywolanie1.x z 3 na 1. Czyli punktA zmienia się z (3,4) na (1,4)
        return old; //zwracasz z metody old, czyli 1
        //Zwróć uwagę, że nigdzie nie zmieniasz niczego z this, czyli nie zmieniasz punktA. Ten obiekt dalej zostaje równy (1,2)
    }

Nawiasem mówiąc jesteś prawie u celu:

  1. Twoja metoda zwraca stare X, zgodnie z poleceniem
  2. Niestety, wskutek zmian, twoja metoda ustawX przestała ustawiać x
0

Przerobiłem to żeby ustawX i ustawY zwracały inta:

class Punkty
{
	int x;
	int y;
	
	public int ustawX(int old)
	{
		Punkty wywolanie1=new Punkty();
		old=this.x;
		this.x=wywolanie1.x;
		return old;
	}
	public int ustawY(int old)
	{
		Punkty wywolanie1=new Punkty();
		old=this.y;
		this.y=wywolanie1.y;
		return old;
	}
	
	void wyswietlXY()
	{
		System.out.println(x);
		System.out.println(y);
	}
}

Ale zwraca mi same zera. Jako 'main' użyłem Twojego test:

public class cw144
{
	public static void main(String[]args)
	{
	Punkty wywolanie1 = new Punkty();
			
	wywolanie1.ustawX(4);
	wywolanie1.ustawY(5);
	
	int oldX=wywolanie1.ustawX(34);
	int oldY=wywolanie1.ustawY(46);
	
	
	System.out.println("Poprzednie X: "+oldX);	/* ma być 4 */
	System.out.println("Poprzednie Y: "+oldY);	/* ma być 5 */
	System.out.println("Obecne X: "+wywolanie1.x);/* ma być 34 */
	System.out.println("Obecne Y: "+wywolanie1.y);/* ma być 46 */
	
	}
}
0

Poddaję się =P
Masz tu rozwiązanie, może załapiesz o co chodzi.

Generalnie masz problem ze zrozumieniem co to jest ten ów magiczny this i co to są pola

class Punkty
{
    int x;
    int y;

    public int ustawX(int noweX)
    {
        int poprzednieX = this.x;
        this.x=noweX;
        return poprzednieX ;
    }
    public int ustawY(int noweY)
    {
        int poprzednieY = this.Y;
        this.y=noweY;
        return poprzednieY ;
    }

    void wyswietlXY()
    {
        System.out.println(x);
        System.out.println(y);
    }
}
1

Odpowiadając na twoje pytania przesłane na priv:

A byłbyś w stanie mi napisać dlaczego ja robiłem to źle? Też jako argument przyjąłem int. To źle że Twoją klasę test przyjąłem jako main?

oraz

A bardzo chętnie będę pytał, bo często się z czymś męczę. Chciałem stworzyć obiekt w klasie Punkty żeby wywołać za jego pomocą x i y, to zły tok myślenia?

Punkt jak obiekt może być nieco zbyt abstrakcyjny. Może spróbuj sobie wyobrazić, że masz klasę Pionek, który reprezentuje ci tego zwykłego pionka szachowego.
Wyobraź sobie, że kładziesz te pionki na szachownicy, tylko zmiast pól 1-8 i A-H masz je określone za pomocą liczb. 1-8 to u ciebie oś X, która może przyjmować wartości od 0 do 7 (bo liczymy od zera =P), a A-H to u ciebie oś Y, która może przyjmować wartości też od 0 do 7.
Masz tą klasę pionka, która ma dwa pola: x i y. One mówią w jakim miejscu znajduje się pionek na szachownicy.
Zrobisz tak:

Pionek pionek1 = new Pionek();
pionek1.x = 3;
pionek1.y = 4;

To stworzysz nowego pionka, który będzie znajdował się na pozycji (3,4);

Zrobisz tak:

Pionek pionek1 = new Pionek();
pionek1.x = 3;
pionek1.y = 4;
Pionek pionek2 = new Pionek();
pionek2.x = 6;
pionek2.y = 2;

To stworzysz dwa nowe pionki, z których pierwszy będą znajdował się na pozycji (3,4), a drugi (6,2);

Zrobisz tak:

Pionek pionek1 = new Pionek();
pionek1.x = 3;
pionek1.y = 4;
Pionek pionek2 = new Pionek();
pionek2.x = 3;
pionek2.y = 4;

To też stworzysz dwa nowe pionki, ale uwaga będą stały na dokładnie tym samym polu szachownicy: (3,4). Nie zmienia to faktu, że to są dwa różne pionki i możesz przesunąć jednego, a zostawić na tym polu drugiego.

Zrobisz tak:

Pionek pionek1 = new Pionek();

To też stworzysz nowego pionka. I gdzie on będzie siedział? Nie, wcale nie poza szachownicą. W twojej klasie pola x i y to są typu int. Jeśli pól nie zainicjalizujesz, to mają domyślne wartości. W przypadku inta jest to zero. Więc Pionek pionek1 = new Pionek(); stworzy ci pionka i położy go na polu (0,0).

Mając tą wiedzę możemy się przyglądnąć bliżej operacji:

1. Pionek pionek1 = new Pionek();
2. pionek1.x = 3;
3. pionek1.y = 4;

Stworzenie i położenie pionka na polu (3,4) składa się z trzech oddzielnych operacji.
W pierwszym kroku tworzysz nowy pionek i układasz go na domyślnym polu, czyli (0,0)
W drugim kroku przesuwasz ten pionek na oś x=3, więc twój pionek znajduje się na pozycji (3,0)
W trzecim kroku przesuwasz ten pionek na oś y=4, więc twój pionek znajduje się na pozycji (3,4)

Rozwijając program dalej stworzyłeś sobie metody ustawX i ustawY. Powinny one analogicznie zmieniać x i y, więc powinieneś móc bez problemu zamienić powyższy przykład z poniższym i efekt powinien być taki sam:

1. Pionek pionek1 = new Pionek();
2. pionek1.ustawX(3);
3. pionek1.ustawY(4);

Dodatkowo metody ustaw mają zwracać ci stare położenie pionka:

Pionek pionek1 = new Pionek();
int stareX = pionek1.ustawX(3); //stareX wynosi 0
int stareY = pionek1.ustawY(4); //stareY wynosi 0

Dlaczego akurat 0? Bo taka jest domyślna i pierwsza wartość pól x i y

Pionek pionek1 = new Pionek();
int najstarszeX = pionek1.ustawX(3); //najstarszeX wynosi 0
int najstarszeY = pionek1.ustawY(4); //najstarszeY wynosi 0
int stareX = pionek1.ustawX(5); //stareX wynosi 3
int stareY = pionek1.ustawY(2); //stareY wynosi 4

Mam nadzieje, że do teraz jest wszystko jasne. Teraz dlaczego twoja implementacja nie działa?

0. public int ustawX(int old) {
1.    Punkty wywolanie1=new Punkty();
2.    old=this.x;
3.    this.x=wywolanie1.x;
4.    return old;
}

Wywołujesz int stareX = pionek1.ustawX(5); (czyli chcesz przesunąć pionek z pola (3,4) na pole (5,4)) i wchodzisz do środka metody ustawX

  • W kroku 0. jesteśmy przed wszystkim co się dzieje. Znajdujemy się w środku obiektu pionek1, więc this to jest pionek1. Przekazaliśmy jako parametr 5 więc old wynosi 5. Wartość pionek1.x (czyli this.x) wynosi 3, a wartość pionek1.y (czyli this.y) wynosi 4

  • W kroku 1. tworzysz nowy pionek, nazywasz go wywołanie1 i kładziesz na domyślnym polu na szachownicy. W tej chwili masz dwa pionki: pionek1 na polu (3,4) i wywolanie1 na polu (0,0)

  • W kroku 2. zmieniasz zmienną old na this.x. this.x, to to samo co pionek1.x więc wynosi 3. Zmieniasz wartość old z 5 na 3.

  • W kroku 3. zmieniasz pole this.x (czyli pionek1.x) na wywołanie1.x. wywołanie1 to twój nowy pionek, który właśnie stworzyłeś i położyłeś go na domyślnym polu (0,0), więc wywołanie1.x wynosi 0. Zmianiasz wartość this.x (czyli pionek1.x) na 0. Czyli przesuwasz pionek1 na pole (0,4) z pola (3,4)

  • W kroku 4 zwracasz wartość old, która wynosi 3. Czyli do stareX przypisujesz wartość 3.

Po całej operacji masz następujący wynik:

  • zmienna stareX wynosi 3, czyli sukces, bo tyle wynosiło poprzednie x pionka1
  • przemieściłeś pionek z (3,4) na (0,4), czyli źle, bo chciałeś (5,4)
  • stworzyłeś całkowicie nowy, niepotrzebny pionek i położyłeś go na polu (0,0)

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