Tablice, losowanie bez powtórzeń - optymalizacja kodu

0

Co poprawić??

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));

    }
}
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

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 :)
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.

  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));

    }
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.

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):


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.

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