Tablica tablic

0

Witam. Mam takie polecenie: Zdefiniuj klasę MacierzTab traktując macierz jako jednowymiarową tablicę obiektów typu Tablica. Obiekty tej klasy powinny móc zapamiętać tablicę dwuwymiarową ( do 10 wierszy i 30 kolumn) liczb całkowitych.

Jak stworzyć tablicę jednowymiarową, której elementem byłaby tablica dwuwymiarowa mająca 10 ort! i 30 kolumn liczb całkowitych? Kombinuję, ale coś nie chce mi wyjść to ;)

Dzięki z góry za pomoc

1

Jeżeli moje czytanie ze zrozumieniem jeszcze nie nawala, to powinno być tak:

public class MacierzTab
{
	private class Tablica
	{
		private int[][] tab = new int[10][30];
	}

	//...

	private Tablica[] macierz;
}
0

Dzieki po raz kolejny :)

0

Teraz maly problem zwiazany z ta wlasnie klasa. Napisalem ja. I teraz musze napisac klase, w ktorej wywolam przykladowe metody ze wszystkich pozostalych 4 klas (bo tyle napisalem ich).

Dla 3 klas bez problemu dalem rade. Jednak z wywolaniem metod z klasy MacierzTab mam problem. Klasa tak w skrocie wyglada jak kolega wyzej podpowiedzial. I teraz pojawia sie pytanie: w jaki sposob wywolac metody tej klasy?

Gdy mialem np. klase Macierz, w ktorej byla tablica dwuwymiarowa to metody wywolywalem w ten sposob:

int [][] tablica3 = new int [10][30];
        Macierz t3 = new Macierz(tablica3);
        System.out.println("Suma elementow macierzy: "+t3.suma());

Jednak nie mam pojecia jak zrobic przy tej klasie, gdy mamy tu sytuacje taka jak napisalem w pierwszym poscie.

Z gory dzieki za wszelka pomoc.

0

Zmień modyfikator klasy Tablica na "public", żeby inne klasy mogły ją (klasę) w ogóle zobaczyć. Wtedy dostęp będzie już otwarty taki jaki sobie stworzysz. Przykład:

import java.util.Random;

public class MacierzTab
{
	public static void main(String[] args)
	{
		Random los = new Random();
		MacierzTab m = new MacierzTab(20);
		//Zapełnienie wszystkiego śmieciami
		for(int n = 0; n < 20; ++n)
			for(int x = 0; x < 10; ++x)
				for(int y = 0; y < 30; ++y)
					m.getTab(n).setSubTabItem(x, y, los.nextInt(500));
		//wyciągnięcie 15 przypadkowych danych
		for(int i = 0; i < 15; ++i)
		{
			int a = los.nextInt(20), b = los.nextInt(10), c = los.nextInt(30);
			Tablica t = m.getTab(a);
			int x = t.getSubTabItem(b, c);
			System.out.printf("Wartość m[%02d][%02d][%02d] = %d%n", a, b, c, x);
		}
	}

	//static, żeby nie była związana istnieniem z MacierzTab
	//może to być zwyczajna klasa zewnętrzna
	public static class Tablica
	{	//konstruktor z automatu
		public int getSubTabItem(final int x, final int y)
		{
			return tab[x][y];
		}

		public int setSubTabItem(final int x, final int y, final int value)
		{
			final int old = tab[x][y];
			tab[x][y] = value;
			return old;
		}
		private int[][] tab = new int[10][30];
	}

	public MacierzTab(final int rozmiar)
	{
		mac = new Tablica[rozmiar];
		for(int i = 0; i < mac.length; ++i)
			mac[i] = new Tablica();
	}

	public Tablica getTab(final int n) { return mac[n]; }
	//...

	private Tablica[] mac;
}
0

Tylko jest pewien problem - mam juz wsrod 4 klas taka o nazwie Tablica...Wiec mamy maly konflikt...

Może dla ułatwienia sprawy wkleję opis wszystkiego jak to wygląda:

Uwaga: Żadna z poniższych klas nie może zawierać metody main. Wywołania poszczególnych metod powinny znaleźć się w osobnej klasie.

  1. Zdefiniuj klasę Tablica. Obiekty tej klasy powinny móc zapamiętać do 100 liczb całkowitych. Liczba aktualnie pamiętanych elementów jest zmienna. Klasa posiada:
    a. Dwa pola prywatne – tablicę oraz liczbę aktualnie zapisanych w niej elementów.
    b. Konstruktory
    i. przyjmujący tablicę liczb całkowitych
    ii. przyjmujący obiekt typu Tablica
    c. Metody pobierzTablice(), pobierzLiczbeElementów() zwracające odpowiednie
    d. Metodę dodaj(int x) dodającą element na koniec tablicy
    e. Metodę dodajNaK(int x, int k) dodającą element na pozycję k w tablicy
    f. Metodę usun() usuwającą ostatni element tablicy
    g. Metodę usunZK(int k) usuwającą element z pozycji k w tablicy
    h. Metodę suma() sumującą wartości elementów tablicy
    i. Metodę maksymalnyEl() znajdującą wartość maksymalna w tablicy
    j. Metodę czyJestX(int x, int k) sprawdzającą czy podana wartość x występuje na którejś z k początkowych pozycji tablicy
    k. Metodę roznowartosciowa() sprawdzającą czy tablica jest różnowartościowa
    l. Metodę tworzenieRoznowartosciowej() która eliminuje wszystkie powtórzenia elementów tablicy
    m. Metodę sortuj() która uporządkuje rosnąco elementy tablicy (wykorzystaj dowolny algorytm sortowania)
    n. Metodę toString() wyświetlającą tablicę na konsoli

  2. Zdefiniuj klasę TablicaUporządkowana (rosnąco). Klasa zawiera:
    a. Dwa pola prywatne – tablicę oraz liczbę aktualnie zapisanych w niej elementów.
    b. Konstruktory
    i. przyjmujący tablicę liczb całkowitych
    ii. przyjmujący obiekt typu Tablica
    iii. przyjmujący obiekt typu TablicaUporządkowana
    c. Metodę dodaj(int x) dodającą element x
    d. Metodę usun(int x) usuwającą element x z tablicy
    e. Metodę usunZK(int k) usuwającą element z pozycji k w tablicy
    f. Metodę roznowartosciowa() sprawdzającą czy tablica jest różnowartościowa
    g. Metodę tworzenieRoznowartosciowej() która eliminuje wszystkie powtórzenia elementów tablicy
    h. Metodę toString() wyświetlającą tablicę na konsoli

  3. Zdefiniuj klasę Macierz. Obiekty tej klasy powinny móc zapamiętać tablicę dwuwymiarową (do 10 wierszy i 30 kolumn) liczb całkowitych.: Klasa zawiera:
    a. Pole prywatne – macierz.
    b. Konstruktory
    i. przyjmujący tablicę dwuwymiarową
    ii. przyjmujący obiekt klasy Macierz
    a. Metodę suma() sumującą wartości elementów macierzy
    b. Metodę maksymalnyElement() zwracającą wartość maksymalną w macierzy
    c. Metodę maksymalnyWiersz() znajdujący wiersz o maksymalnej sumie wartości elementów
    d. Metodę czy istnieje(int x) sprawdzającą czy podana wartość występuje w macierzy
    e. Metodę roznowartosciowa() sprawdzającą czy macierz jest różnowartościowa
    f. Metodę transponuj() transponującą macierz
    Wskazówki : zacznij od macierzy kwadratowej , a następnie spróbuj z macierzą prostokątną ; pewnie przyda się pomocnicza metoda zamieniająca dwa wskazane elementy macierzy
    g. Metodę toString() wyświetlającą macierz na konsoli

  4. Zdefiniuj klasę MacierzTab traktując macierz jako jednowymiarową tablicę obiektów typu Tablica. Obiekty tej klasy powinny móc zapamiętać tablicę dwuwymiarową  ( do 10 wierszy i 30 kolumn)  liczb całkowitych. 
    

a. Dwa pola prywatne – tablicę obiektów oraz liczbę elementów.
b. Konstruktory
i. przyjmujący tablicę obiektów
ii. przyjmujący obiekt klasy MacierzTab
h. Metodę suma() sumującą wartości elementów macierzy
i. Metodę maksymalnyElement() zwracającą wartość maksymalną w macierzy
j. Metodę maksymalnyWiersz() znajdujący wiersz o maksymalnej sumie wartości elementów
k. Metodę czy istnieje(int x) sprawdzającą czy podana wartość występuje w macierzy
l. Metodę roznowartosciowa() sprawdzającą czy macierz jest różnowartościowa
c. Metodę toString() wyświetlającą macierz na konsoli

0

Dorób konstruktor MacierzTab(Tablica[] arg) i do niego wrzuć gotową zainicjowaną tablicę, czyli np. zawartość poprzedniego konstruktora. Jeszcze jeden konstruktor z takim samym obiektem nazywany jest często konstruktorem kopiującym bo zwykle kopiuje pola obiektu przyjmowanego, ale równie dobrze może je zwyczajnie ukraść przez przypisanie własnym polom cudzych pól z obiektu argumentu.
Punkt 4a sugeruje, że pole Tablica[] może nie być cała wypełniona i może zawierać nulle gdy liczba elementów będzie mniejsza od (mac.length - 1).
Pozostałe metody nie powinny być problemem.

0

Dzieki wielkie za pomoc, ale niestety dalej jeszcze mam problem.

Kawałek kodu klasy MacierzTab:

//Pola prywatne
  private Tablica[] macierz; //macierz to tablica jednowymiarowa obiektow typu Tablica
  private int liczbaElementow=0;  
  
  //Konstruktory
  public MacierzTab(MacierzTab macierz) //konstruktor przyjmujacy obiekt klasy MacierzTab
  {liczbaElementow=0;}
    
  public MacierzTab(Tablica tablica) //konstruktor przyjmujacy tablice obiektow
  {liczbaElementow=0;}

Dorzuciłem coś takiego:

 public MacierzTab(Tablica[] arg)
  {macierz=arg;} 

W klasie Glowna (tam wywoluje te przykladowe metody):

Tablica[] tablica4 = new Tablica[100]; 
MacierzTab t4 = new MacierzTab(tablica4);

Ale dostaje blad: "no suitable constructor found for MacierzTab(Tablica[])". Czyli cos robie zle - tylko co?

0

Nie istnieje konstruktor z parametrem Tablica[], czyli z tablicą obiektów "Tablica". A to właśnie próbujesz przekazać do konstruktora. Nie napisałeś konstruktora z takim argumentem, co napisałem w poprzednim poście. Oprócz tego musisz w tablica4 zainicjować elementy bo po utworzeniu zawiera same nulle (np. tablica4[i] = new Tablica(...)). Konstruktor taki powinien przypisywać argument do pola "mac", który - zauważ - też jest typu Tablica[]. Tutaj pomyłki tworzy nazewnictwo bo: Tablica[], to >>tablica obiektów "Tablica"<<.

ps. Zainstaluj sobie Netbeans, Eclipse, albo dowolny inny lepszy IDE, to wszelkie błędy będziesz miał od razu podkreślane w edytorze wraz z komunikatami. A komunikat gdy niezrozumiały pakujesz do tłumacza wujka Googla, wtedy nawet przy kiepskim tłumaczeniu połapiesz się o co chodzi.

0

Hmm próbowałem ale coś nie bardzo wiem jaki to ma być konstruktor. Co do tablicy4 to czy to:

Tablica[] tablica4 = new Tablica[100]; 

nie jest jej inicjalizacją?

Odnosnie IDE to sciagam juz Eclipse'a ;) Dzieki

0

Nie. Zmienna referencyjna tablica4 została zainicjowana, ale komórki obiektu tablicy (referencje do obiektów) już nie.
Co do konstruktora: public MacierzTab(Tablica[] arg)
Gdzie ty go umieściłeś? Kompilator nie umie go znaleźć na głównym poziomie klasy MacierzTab.

0

Klasa MacierzTab wygląda tak:

public class MacierzTab
{
  
  //Klasa prywatna Tablica, w ktorej zdefiniowana zostanie tablica dwuwymiarowa //
  private class Tablica
        { (...) }

//Pola prywatne
  private Tablica[] macierz; //macierz to tablica jednowymiarowa obiektow typu Tablica
  private int liczbaElementow=0;  
  
  //Konstruktory
  public MacierzTab(MacierzTab macierz) //konstruktor przyjmujacy obiekt klasy MacierzTab
  {liczbaElementow=0;}
    
  public MacierzTab(Tablica tablica) //konstruktor przyjmujacy tablice obiektow
  {liczbaElementow=0;}
  
  public MacierzTab(Tablica[] arg) //konstruktor kopiujacy, ktory bedzie mi przydatny w klasie Glowna
  {macierz=arg;}
  
  //Metody

(...)

}

Więc konstruktor wrzuciłem na głównym poziomie (albo tak mi się wydaje...)...Próbowałem skorzystać z porad Eclipse, ale on sam w propozycjach rozwiązania problemu z konstruktorem dał propozycję, że stworzy konstruktor, którego potem nie widzi...

Co do inicjalizacji tablicy4 to powinienem jej przypisać wartość np. tablicy macierz z klasy MacierzTab? Albo po kolei ponadawać wartości dla wszystkich elementów tej tablicy4?

0

Ok mamy już public static class Tablica zamiast private class Tablica

Mamy konstruktor taki jak pisałem w klasie MacierzTab w poprzednim poście.

I niestety mam dalej ten sam problem: The constructor MacierzTab(Tablica[]) is undefined

Dlaczego dalej jest niezdefiniowany skoro...zdefiniowałem go? Klasa Tablica jest publiczna i statyczna...czyżby klasa Tablica zdefiniowana w MacierzTab gryzła się z klasą Tablica (tą osobną, jedną z pięciu "głównych")?

0

Możliwości masz takie:

  1. Próbujesz takich konstruktorów. One nie powinny już konfliktować z publiczną klasą Tablica.
	public MacierzTab(MacierzTab.Tablica tab)
	{
		this.mac[0] = tab;
	}

	public MacierzTab(MacierzTab.Tablica[] macierz)
	{
		this.mac = macierz;
	}
  1. Wyrzucasz w ogóle tę wewnętrzną klasę Tablica. Wpisałem ją do pierwszej odpowiedzi tylko dlatego, że nie wiedziałem, że powinno to być wcześniej wykonane zadanie. Podejrzewam, że na tym etapie w ogóle jeszcze nie mieliście tematu klas wewnętrznych, więc taka klasa nie powinna w ogóle w zadaniu zaistnieć.
0

Hmm to 2. rozwiązanie wydawałoby mi się lepsze. Tylko jak w takim przypadku jeśli wyrzucę tą wewnętrzną klasę Tablica zrobić to o czym pisałem w pierwszym poście tj.:

Witam. Mam takie polecenie: Zdefiniuj klasę MacierzTab traktując macierz jako jednowymiarową tablicę obiektów typu Tablica. Obiekty tej klasy powinny móc zapamiętać tablicę dwuwymiarową ( do 10 wierszy i 30 kolumn) liczb całkowitych.

Jak stworzyć tablicę jednowymiarową, której elementem byłaby tablica dwuwymiarowa mająca 10 wierszy i 30 kolumn liczb całkowitych? Kombinuję, ale coś nie chce mi wyjść to ;)

Zaznaczę, że klasa Tablica (ta którą tworzyłem na początku) ma tylko tablicę jednowymiarową. Czy powinienem w niej dorobić konstruktor dla tablicy dwuwymiarowej i wtedy w klasie Macierz się odwoływać do tej Tablicy?

Nie miałem tematu klas wewnętrznych faktycznie, ale to wszystko co napisałeś mi się na pewno bardzo przyda na przyszłość :)

0

Próbowałem też tych konstruktorów ale niestety efekt ten sam - dalej nie widzi tego konstruktora...

0

Jeżeli wyrzucisz klasę wewnętrzną, to tą, która istnieje jako publiczna musisz przerobić podobnie jak ta wewnętrzna, którą wyrzucisz.
Klasa o nazwie tablica ma odtąd przechowywać wewnętrznie tablicę dwuwymiarową int[10][30].

Być może zamiast przerabiania wcześniejszej klasy Tablica lepsze byłoby przeniesienie tej wewnętrznej do jakiegoś pakietu (np. edu.xxx.zadanie1 i edu.xxx.zadanie4). Dzięki czemu w instrukcji import możesz podać właściwą klasę tablicy (np. import edu.xxx.zadanie1.Tablica;). W ten sposób będzie można łatwo przełączać się między tymi klasami (razem z nazwą pakietu będą wtedy unikalne).
W razie czego wciąż w konkretnym wywołaniu mógłbyś nadal odwołać się do pierwszej wersji Tablica tak jak tu - np.: x = new edu.xxx.zadanie1.Tablica(...);

Dla testu spróbuj tymczasowo zmienić typ parametru konstruktora na TablicaUporządkowana[] i wtedy podstaw taki typ jako parametr i spróbuj skompilować. Ten brak widoczności konstruktora to jakiś bardzo prosty (np. mylnie rozłożone klamry bloków itp.), albo bardzo skomplikowany błąd. Sprawdź za pomocą skrótu klawiaturowego IDE czy klamry i nawiasy są we właściwych miejscach - częsta kombinacja pozwalająca skoczyć do drugiej klamry (lub nawiasu), to ctrl+[.

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