Java: Zadania

Najlepszą metodą nauki programowania jest rozwiązywanie zadań. Poniżej znajduje się kilka problemów programistycznych oraz przykładowych sposobów ich rozwiązania.

Dana jest tablica szarpana tab. Należy na jej podstawie utworzyć tablicę prostokątną w puste miejsca wstawiając wartość -5

W treści zadania nie ma nic na temat pisania funkcji, wyświetlania itp, więc wystarczy stworzyć nową tablicę wypełnioną odpowiednimi wartościami. A więc co trzeba zrobić? Na pewno trzeba stworzyć tablicę. Pytanie tylko o jakich wymiarach. Ilość wierszy będzie taka sama jak w tablicy wejściowej. Ilość kolumn trzeba wyliczyć. Jeśli tablica początkowa jest szarpana a wyjściowa ma być prostokątna, to oczywiste jest że ilość kolum w tablicy wyjściowej musi być taka sama jak w najdłuższym wierszu tablicy początkowej. No to tablica już jest, teraz trzeba ją jakoś wypełnić. Potrzebna będzie na pewno jedna pętla przechodząca wiersz po wierszu.

for(int i = 0; i < tabWejsciowa.lenght ; i++){

W środku tej pętli trzeba najpierw przepisać wszystkie elementy z tablicy wejściowej – mniej wiecej tak:

for(int j = 0; j < tabWejsciowa[i].length ; j++){
   tabWyjsciowa[i][j] = tabWejscjowa[i][j];
}

No i teraz trzeba tylko w pozostałe elementy wpisać -5. Tu będzie trochę liczenia. Na pewno trzeba to zrobić pętlą. Pętla musi zaczynać się od pierwszego elementu ponad wielkość tego wiersza z tablicy początkowej. To znaczy że jeśli ten wiersz w tablicy początkowej miał długość 5, to trzeba zacząć od 5 elementu w tej tablicy (tutaj trzeba pamiętać o przesunięciu w numerowaniu tablic). Pętla ma się kończyć na elemencie o jeden mniejszym niż długość tablicy wyjściowej. Trochę to wygląda skomplikowanie, ale po zapisaniu wygląda już lepiej:

for(int j = tabWejsciowa[i].lenght; j < tabWyjsciowa[i].lenght ; j++){

No i w tej pętli każdemu elementowi przypisujemy wartośc -5:

tabWyjsciowa[i][j] = -5;

Tu trzeba zauważyć, że w przypadku tego najdłuższego wiersza, gdzie żaden z elementów nie ma być wypełniony wartością -5, ta pętla nie wykona się wcale, bo od razu długość tabWejsciowa[i] jest równa tabWyjsciowa[i], więc warunek od razu jest fałszywy. No i to jest w zasadzie koniec zadania.

Dane są dwie tablice kwadratwe i takich samych rozmiarach. Należy zaimplementować mnożenie macierzy traktując tablice wejściowe jako macierze.

Mnożenie macierzy było na wykładach i ćwiczeniach z algebry, więc każdy powinien wiedzieć jak to ma wyglądać. Na początek trzeba sobie zdefiniować jakąś tablicę wyjściową. Wielkość tablicy wyjściowej wylicza się z wielkości tablic wejściowych, ze wzoru na mnożenie macierzy. Ilośc wierszy w tablicy wyjściowej ma być taka jak ilość wierszy w pierwszej tablicy wejściowej, a ilość kolumn w tablicy wyjściowej ma być taka jak ilość kolumn w drugiej tablicy wejściowej. Dalej mnożenie ma być wykonane kilkoma pętlami. Nie jest to najprostsze – trzeba zastanowić się jak po kolei trzeba mnożyć elementy. Powinno to wyglądać mniej więcej tak (nie sprawdzałem czy działa):

for(int i = 0; i < wyjsciowa.lenght ; i++){
   for(int j = 0; i < wyjsciowa[i].lenght ; j++){
      wyjsciowa[i][j] = 0;
      for( int k = 0; i < wejsciowa1.lenght ; k++){
         wyjsciowa[i][j] += wejsciowa1[i][k] * wejsciowa2[k][j];
      }
   }
}

Nie jestem pewien czy to dobrze działa, więc może wyjaśnię jak to ma działać. Po kolei przechodzimy przez całą tablicę wyjściową. Dla pierwszego wiersza i pierwszej kolumny tablicy wyjściowej trzeba wymnażać i dodawać elementy pierwszego wiersza pierwszej tablicy wejściowej z elementami z pierwszej kolumny drugiej tablicy wyjściowej tak, że pierwszy element wiersza jest mnożony z pierwszym elementem kolumny. A więc teoretycznie powinno to działać.

Napisać funkcję int findAll(int wrt, int[][] tab) która policzy ile jest w tablicy tab wartości takich samych jak wrt i zwróci tę informację.

To zadanie jest prawie identyczne jak wyszukiwanie wartości parzystych w przykładach z artykułu Java: Funkcje, z tym, że sprawdzanie czy element jest parzysty trzeba zamienić na sprawdzenie, czy element jest równy wartości wrt. Reszta jest identyczna.

Napisać funkcję void mirror(int[][] tab), która odwróci tablicę tab najpierw względem pionowej osi tablicy, a następnie względem jej osi pionowej.

Nie bardzo wiadomo, co tu trzeba zrobić z tą tablicą, bo funkcja nic nie zwraca ani nic w treści zadania nie jest powiedziane, czy ma ona być wyświetlana, więc załóżmy, że ma być poprostu przekształcona do innej zmiennej. W takim przypadku zadanie polega na napisaniu pętli kopiującej tablicę, ale od końca – najpierw od końca w drugiej pętli, a później od końca w pierwszej pętli. Pętlę od końca pisze się tak jak przy wyświetlaniu stringa od końca. Utrudnieniem jest tutaj to, że wewnątrz jednej pętli jedne wartości rosną a drugie maleją – można to rozwiązać łatwym wyliczeniem: jeśli wartości maleją, to wartość rosnącą oblicz się od maksymalnej odejmuje się tą wartość malejącą. Wyglądać ma to mniej więcej tak:

int[][] out = new int[tab.lenght][tab[0].lenght];
int[][] out2 = new int[tab.lenght][tab[0].lenght];
// Przekształcanie według osi pionowej
for(int i = 0; i < tab.lenght ; i++){
   for(int j = tab[i].lenght - 1; j >= 0; j--){
      out[i][tab[i].lenght - j - 1] = out[i][j];
   }
}

for(int i = tab.lenght - 1; i >= 0 ; i--){
   for(int j = 0; j <= tab.lenght; j++){
      out[tab[i].lenght - i - 1][j] = out[i][j];
   }
}

Napisać funkcję int[][] subTab(int[][] tab, int x, int y, int sizeX, int sizeY), która z wybranej tablicy tab wyekstrachuje od elementu opisanego zmiennymi x, y podtablice o rozmiarach sizeX na sizeY.

Tutaj sprawa polega po prostu na odpowiednim napisaniu pętli kopiującej. Poprostu pierwsza pętla ma się zaczynać od x i trwać do x+sizeX-1 a druga pętla ma zaczynać się od y i trwać do y+sizeY-1. Trzeba jednak pamiętać, że element o indeksie x z tablicy wejściowej ma mieć indeks 0 w tablicy wyjściowej. Tabela wyjściowa ma mieć rozmiary sizeXxsizeY. A pętle mają wyglądać mniej więcej tak:

for(int i = x; i < x + sizeX ; i++){
   for(int j = y; j < y + sizeY ; j++){
      out[i - x][j - y] = tab[i][j];
   }
}

I tyle. Wystarczy teraz zwrócić tablicę out.

Napisać funkcję rekurencyjną void fun1(String str), która odwróci dowolny ciąg znaków

Nie jest napisane co ma się dziać z tym odwróconym ciągiem znaków, więc chyba trzeba go wyświetlić. Jest pewnie kilka sposobów na wykonanie tego zadania, ale ja wymyśliłem takie coś. Jako że ta funkcja ma wykonywać coś od końca, to wywołanie przez funkcję samej siebie musi być dokonane na początku, przed wyświetleniem literki. A więc będziemy upraszczać string co raz bardziej. Jako że mamy wyświetlić tekst od końca, to trzeba dążyć do tego, żeby w stringu była tylko jedna litera – ostatnia. Jeśli w stringu jest więcej niż jedna litera, to trzeba go uprościć, czyli funkcja ma wykonać samą siebię z uproszczonym stringiem, z obciętą pierwszą literą. Czyli:

if(str.lenght() > 1){
   fun1(str.substr(1));
}

A więc dla wywołania funkcji fun1(„test”) funkcja ta będzie się wywoływać rekurencyjnie tak:

fun1("test");
fun1("est");
fun1("st");
fun1("t");

Po dojściu do ostatniego wywołania, funkcja zacznie wykonywać to co jest po tym warunku, który jest napisany wyżej, a później się „zwijać”, a więc najpierw wykona się to co jest po powyższym warunku dla wywołania fun1(„t”), później dla fun1(„st”) i tak dalej. Jak widać, żeby wyświetlić tekst od końca funkcja musi wyświetlać pierwszą literkę stringa który dostała. Jako że najpierw wykona się to co jest w fun1(„t”), to wyświetli się pierwsza literka stringu „t”, później wykona się to co jest w wywołaniu fun1(„st”) i tak dalej. A więc funkcja musi wyświetlić pierwszą literę stringa. Czyli:

System.out.print(str.charAt(0));

I teraz trzeba posklejać tą funkcję:

void fun1(String str){
   if(str.lenght() > 1){
      fun1(str.substr(1));
   }
   System.out.print(str.charAt(0));
}

Autor: leafnode

Architekt oprogramowania webowego, programista, analityk bezpieczeństwa serwisów internetowych, speaker, konsultant. Potrzebujesz pomocy? Skontaktuj się ze mną!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *