Tablice, losowanie bez powtórzeń - optymalizacja kodu

Tablice, losowanie bez powtórzeń - optymalizacja kodu
MA
  • Rejestracja:około 6 lat
  • Ostatnio:ponad 4 lata
  • Postów:30
0

Co poprawić??

Kopiuj
package tablice;

/*
 ZBIOR ZADAN 7
 Zad 5
 Pobierz od użytkownika rozmiar R tablicy jednowymiarowej o elementach typu int, a następnie losuj
 do tablicy elementy z przedziału <0, 2*R> w taki sposób, żeby żaden element tablicy się nie powtórzył.
 Wyznacz największą oraz najmniejszą wartość spośród elementów w tablicy oraz element tablicy
 o najmniejszej sumie cyfr.
*/

import java.util.Arrays;
import java.util.ListIterator;
import java.util.Random;
import java.util.Scanner;

public class Zad2 {


    static int[] createArr() {

        Scanner sc = new Scanner(System.in);
        System.out.println("Podaj rozmiar tablicy");
        String stringSize = sc.nextLine();

        if (!stringSize.matches("[0-9]+")) {
            throw new IllegalArgumentException("size is not correct");
        }

        Integer numberSize = Integer.valueOf(stringSize);

        int[] arr = new int[numberSize * 2];

        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
        }
        return arr;
    }


    static void shuffleArr(int[] arr) {

        if (arr == null) {
            throw new IllegalArgumentException("arr is null");
        }

        Random r = new Random();

        for (int i = arr.length; i > 1; i--) {
            swap(arr, i - 1, r.nextInt(i));
        }
    }

    static void swap(int[] arr, int i, int j) {

        if (arr == null) {
            throw new IllegalArgumentException("arr is null");
        }

        if (i < 0 || i > arr.length || j < 0 || j > arr.length) {
            throw new IllegalArgumentException("Index is not correct");
        }

        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = createArr();
        System.out.println("min: " + arr[0] + " max: " + arr[arr.length - 1]);
        System.out.println("el o najmniejszej sumie cyfr to: " + arr[0]);
        shuffleArr(arr);
        System.out.println(Arrays.toString(arr));

    }
}
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:10 dni
1

Scaner ma metodę do wczytywania liczb, np. nextLong. Po co robić to tak na około? Wywal też to sprawdzanie czy argument jest nullem. To bez sensu unikać NullPoitnerException, żeby rzucić inny wyjątek, którego i tak nigdzie nie łapiesz. :p


edytowany 1x, ostatnio: elwis
K5
  • Rejestracja:około 6 lat
  • Ostatnio:7 minut
  • Postów:1002
1
manifestor napisał(a):

Co poprawić??

Prawie wszystko :)

  1. Rozmiar tablicy ma wynosić R, a Ty dajesz 2R. 2R służy jako prawy kraniec przedziału, z którego masz losować liczby :)
  2. Kompletnie nie rozumiem sensu metod shuffle i swap (pomijam ich pokraczną logikę wewnątrz).
  3. Losujesz liczby ze złego przedziału.

Zmień to na coś takiego:

  1. Tworzysz tablicę o odpowiednim rozmiarze.
  2. Tworzysz zbiór liczb całkowitych. Losujesz liczbę z prawidłowego przedziału. Sprawdzasz czy liczba znajduje się już w zbiorze, jeśli nie, to wrzucasz ją i do zbioru i do Twojej tablicy. Jeśli tak, to ponawiasz losowanie.
  3. Aby wyznaczyć min/max użyj Collections.min oraz Collections.max
  4. Co do najmniejszej sumy cyfr - pogłówkuj :)
MA
  • Rejestracja:około 6 lat
  • Ostatnio:ponad 4 lata
  • Postów:30
0
kixe52 napisał(a):
manifestor napisał(a):

Co poprawić??

Prawie wszystko :)

  1. Rozmiar tablicy ma wynosić R, a Ty dajesz 2R. 2R służy jako prawy kraniec przedziału, z którego masz losować liczby :)
  2. Kompletnie nie rozumiem sensu metod shuffle i swap (pomijam ich pokraczną logikę wewnątrz).
  3. Losujesz liczby ze złego przedziału.

Zmień to na coś takiego:

  1. Tworzysz tablicę o odpowiednim rozmiarze.
  2. Tworzysz zbiór liczb całkowitych. Losujesz liczbę z prawidłowego przedziału. Sprawdzasz czy liczba znajduje się już w zbiorze, jeśli nie, to wrzucasz ją i do zbioru i do Twojej tablicy. Jeśli tak, to ponawiasz losowanie.
  3. Aby wyznaczyć min/max użyj Collections.min oraz Collections.max
  4. Co do najmniejszej sumy cyfr - pogłówkuj :)

Z tym rozmiarem faktycznie się zakręciłem :)
Collections nie używałem bo na razie miałem zrobić to bez tego.

Kopiuj
  static int[] creatArr() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Podaj rozmiar tablicy");
        int size = Integer.MIN_VALUE;

        try {
            size = sc.nextInt();
        } catch (InputMismatchException e) {
            System.out.println("Wprowadziłeś niepoprawne dane");
        }

        int[] arr = new int[size];
        fillArray(arr, size);

        return arr;
    }


    static void fillArray(int[] arr, int r2) {
        Random r = new Random();
        int number;

        for (int i = 0; i < arr.length; i++) {
            do {
                number = r.nextInt(r2 * 2);
            } while (exist(arr, number));

            arr[i] = number;
        }
    }

    static boolean exist(int[] arr, int number) {
        boolean flaga = false;

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == number) {
                flaga = true;
            }
        }
        return flaga;
    }

    static int min(int[] arr) {
        int min = Integer.MAX_VALUE;

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        return min;
    }

    static int max(int[] arr) {
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }

    static int minDigitalSum(int[] arr){
        int minDigitalSum = Integer.MAX_VALUE;

        for(int i=0; i<arr.length; i++){
            if(digitalSum(arr[i]) < minDigitalSum){
                minDigitalSum = arr[i];
            }
        }
        return minDigitalSum;
    }

    static int digitalSum(int number) {
        int digitalSum = 0;
        do {
            digitalSum += number % 10;
            number = number / 10;

        } while (number > 0);
        return digitalSum;
    }


    public static void main(String[] args) {
        int[] arr = creatArr();
        System.out.println(Arrays.toString(arr));
        System.out.println("min: " + min(arr) + " max: " + max(arr));
        System.out.println("Liczb o najmniejszej sumie cyfr: " + minDigitalSum(arr));

    }
Skoq
W celu znalezienia minimalnej/maksymalnej wartości polecam metodę min()/max() z klasy Math :) Bo zakładam, że strumienie jeszcze nie zostały poruszone?
K5
  • Rejestracja:około 6 lat
  • Ostatnio:7 minut
  • Postów:1002
1

JEst lepiej. Rozumiem, że masz narzucone robić to w taki sposób?
Sprawdzanie czy liczba już istnieje w tablicy i ponowne przechodzenie po jej indeksach od 0 do końca nie jest zbyt efektywne. Dalej upieram się by zastosować tutaj kolekcje, np liste bądź zbiór.

MA
Oczywiście masz racje ale na takie zarzuty słyszę: "Poczekaj, kolekcje zaraz będziemy robić". Wierzę, że takie podejście ma sens :)
K5
Mam nadzieję, że to osobisty mentor a nie niedzielna szkółka programowania :)
MA
Osobisty. Face to Face
MA
tzn laptop to laptop ;)
K5
Szanuję. Jakiś koszt możesz zdradzić?
K5
Koszt sporawy w porównaniu do szkółek niedzielnych ( TFU), ale jednak nauka 1vs1 jest nie do porównania z 1 mentorem vs 20 laików. Więc gratuluję udanego wyboru :)
MA
Teoretycznie tak powinno być a czy będzie trudno mi na razie powiedzieć bo to dopiero początek drogi. Jak znajdę pracę to będę polecał :D
K5
Od programowania strukturalnego do pracy w javie długa droga, więc jeszcze o tym nie myśl. Powodzenia ;)
MA
Ile czasu zajmuje dojście do takiego poziomu? Z pewnością jedni wolniej drudzy 2x szybciej. Jednak jakaś górna granica jest prawda?
K5
Ciężko to oszacowąć w godzinach spędzonych nad kodem. Liczy się znajomość "cora" Javy. Gdy opanujesz solidnie te podstawy to przed Tobą więcej niż "trochę" nauki zagadnień webowych. Framerowki + tematyka ogólno webowa tj: zagadnienia sieciowe, REST, testy i wiele innych, których tutaj nie wymieniłem. No i oczywiście ważnym jest Twoj sposób myślenia i prędkość pochłaniania wiedzy/informacji i umiejętność jej prawidłowego zastosowania.
MA
To idźmy tą drogą. Jeśli komuś nie wystarczy na to 5 lat (od zera do junior dev) no to chyba się nie nadaje. Racja?
K5
5 lat? Ja myślałem o około roku nauki z mentorem (dobym mentorem). :) Mówimy o poziomie pozwalającym się załapać na Juniora, a nie regulara.
MA
No i właśnie o takie info mi chodziło :) Czyli jeśli rok nauki pod okiem dobrego specjalisty nie wystarczy to lepiej sobie darować.
K5
Rok regularnej nauki, a nie 5h tygodniowo. Wtedy tak, można przyjąć, że taki wniosek jest prawidłowy.
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
0

@manifestor wersja bez użycia Collections jest upierdliwa, bo musisz napisać własną metodę shuffle, ale da się to zrobić w bardzo prosty sposób (pseudokod):

Kopiuj

public int[] getRandomValues(int R){
  // tworzysz tablicę reprezentującą zakres i wynik
  int[] range = new int[2R];
  int[] result = new int[R];
  // wypełniasz liczbami 
  for(i = 0; i<2R; i++)
    range[i] = i;

  // tasujesz – uzyskujesz losowość
  shuffle(range);

  // kopiujesz wymaganą ilość danych i gotowe
  System.arraycopy(range, result, 0, R);
  return result;
}

To jest wersja dość pamięciożerna, ale praktycznie nie da się szybciej bez zastosowania sztuczek.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
edytowany 1x, ostatnio: Koziołek
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)