Zliczanie powtórzen w liscie

0

Próbuje utworzyć metodę która z utworzonej listy cyfr policzy ile razy powtórzyła się ilość oczek w danym rzucie. Chciałbym zrobić jak najprostsza metoda bo mam bardzo małe doświadczenie w programowaniu. Aktualnie klasa wygląda ja poniżej:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Rzuty {

	private int ilosc_rzutow;
	private int ilosc_kosci;
	private int ilosc_scian;

	GeneratorRzutow generatorRzutow = new GeneratorRzutow();

	List<List<Integer>> rzuty = new ArrayList<List<Integer>>();
	List<List<Integer>> powtorzenia = new ArrayList<List<Integer>>();

	public void NowyRzut() {

		this.ilosc_rzutow = 2;
		this.ilosc_kosci = 3;
		this.ilosc_scian = 6;

		for (int rzut = 0; rzut < ilosc_rzutow; rzut++) {

			List<Integer> kostki = new ArrayList<Integer>();

			rzuty.add(rzut, kostki);

			for (int kostka = 0; kostka < ilosc_kosci; kostka++) {

				kostki.add(kostka, generatorRzutow.rzut(ilosc_scian));

			}

		}

	}

	public void WywietlRzuty() {

		for (int rzut = 0; rzut < ilosc_rzutow; rzut++) {

			for (int kostka = 0; kostka < ilosc_kosci; kostka++) {

				System.out.print(rzuty.get(rzut).get(kostka) + ";");

			}

			System.out.print("\n");
		}
	}

	public void IlePowtorzen() {

		/*
		 * metoda zwarcajaca ilosc takich samych oczek w kazdym rzucie. Format
		 * to: wartość | ilośc powtórzeń
		 */

		int ilosc_oczek;
		
		for (int rzut = 0; rzut < ilosc_rzutow; rzut++) {

			System.out.println("rzut: " + rzut);

			List<Integer> ilosc_powtorzen = new ArrayList<Integer>();
			powtorzenia.add(rzut, ilosc_powtorzen);

			for (int kostka = 0; kostka < ilosc_kosci; kostka++) {

				System.out.println("kostka: " + kostka);

				for (ilosc_oczek = 1; ilosc_oczek <= ilosc_scian; ilosc_oczek++)

					System.out.println("wartosc oczka " + ilosc_oczek);

				if (rzuty.get(rzut).get(kostka).equals(ilosc_oczek)) {
					System.out.println("mamy oczko " + ilosc_oczek);
					ilosc_powtorzen.add(ilosc_oczek, ilosc_oczek);
				}

			}

		}

		System.out.println(powtorzenia);

	}

}

Nie wiem jak to zrobić. czy ktoś mógłby mi podsunąć pomysł? Bardziej zależy mi na "wędce" niż na "rybie".

import java.util.Random;


public class GeneratorRzutow {
	Random kostka = new Random();
	
	
	public int rzut(int sciany){			
	return kostka.nextInt(sciany)+1;
	
	}
	
}
1

Generalne rady: NIE UŻYWAJ gołych standardowych typów danych. Bo sam jutro nie będziesz wiedział czym jest twoje List<List<Integer>>. A jakby było jakieś List<DiceRoll> to byłoby chyba jednak czytelniej, czy nie?
Używaj foreach a nie iteracji za pomocą indeksów. Mniejsza szansa że się program wysypie. List wie ile ma elementów...
Lekcja na dziś: Map<K,V> czyli kontener asocjacyjny.

0
Dice{
    Dice(wallsAmount)
    topWall()->Wall(aka int)
    roll()
}

Przeiteruj po liście rzuconych kostek, zwiększając liczbę wystąpień ścian w mapie map<Wall, amount(aka int)>

0

Jeśli ilość ścian jest mała to zamiast pamiętać kolejne rzuty wystarczy zliczać na bieżąco ile razy dana ściana wypadła.

0

Chciałbym żeby w przyszłości dynamicznie podawać ilość rzutow, ilość kostek, ilość ścian. Jest możliwe ze bedę używał kości 100 ściennej.

0

Trochę magii javy 8:

List<Integer> input = Arrays.asList(6, 6, 1);
Map<Integer, Long> result = input.stream().collect(Collectors.groupingBy(roll -> roll, Collectors.counting()));

Na wejściu masz listę oczek które wypadły. Mapa którą uzyskujesz mapuje liczbę oczek na ilość kostek na których wypadły. Tzn result.get(1) zwróci 1 a result.get(6) zwróci 2.

A dla twojego List<List<Integer>> możemy zrobić:

        Stream<Map<Integer,Long>> rollsStream = rzuty.stream().
                map(rolls -> rolls.stream().
                    collect(Collectors.groupingBy(roll -> roll, Collectors.counting()))
                );
        List<Map<Integer,Long>> result = rollsStream.collect(Collectors.toList());
//z niewiadomych przyczyn IntelliJ ma problem ze sparsowaniem tego jeśli collect jest w tym samym wyrażniu ;]

Gdzie w wynikowej liście dla kolejnych rzutów mamy mapę jak powyżej, czyli liczba_oczek -> liczba_wystąpień.
Na przykład dla danych:

List<List<Integer>> rzuty = new ArrayList<List<Integer>>();
rzuty.add(Arrays.asList(1, 1, 2));
rzuty.add(Arrays.asList(1, 2, 3));
rzuty.add(Arrays.asList(6, 6, 6));

zwróci nam to listę:

[{1=2, 2=1}, {1=1, 2=1, 3=1}, {6=3}]
0
sojkin napisał(a):

Chciałbym żeby w przyszłości dynamicznie podawać ilość rzutow, ilość kostek, ilość ścian. Jest możliwe ze bedę używał kości 100 ściennej.

100 = mała liczba.

    public void NowyRzut(int ilosc_rzutow, int ilosc_kosci, int ilosc_scian) {
        for (int rzut = 0; rzut < ilosc_rzutow; rzut++) {
            List<Integer> sciany = new ArrayList<Integer>();
            for (int i = 0; i < ilosc_scian; ++i) {
            	sciany.add(0);
            }
 
            rzuty.add(rzut, sciany);
 
            for (int kostka = 0; kostka < ilosc_kosci; kostka++) {
                int wypadlo = generatorRzutow.rzut(ilosc_scian);
                sciany.set(wypadlo, sciany.get(wypadlo) + 1);
            }
        }
    }
0
Shalom napisał(a):

Używaj foreach a nie iteracji za pomocą indeksów. Mniejsza szansa że się program wysypie.

próbuje zacząć od zmiany iteracji na foreach ale przy

for  (int _roll : Throws)

mam błąd "incompatible types"

public class Throws {

    private int _dice_throws;
    private int _dice_quantity;
    private int _dice_walls;

    Dice Dice = new Dice();

    List<List<Integer>> Throws = new ArrayList<List<Integer>>();
    List<List<Integer>> Repetition = new ArrayList<List<Integer>>();

    public void newRoll() {

        this._dice_throws = 2;
        this._dice_quantity = 3;
        this._dice_walls = 6;

        for  (int _roll : Throws) {

            List<Integer> Dices = new ArrayList<Integer>();

            Throws.add(_roll, Dices);

            for (int _dice : Dices) {

                Dices.add(_dice, Dice.newRoll(_dice_walls));

            }

        }

    }

tu jest cała klasa
http://4programmers.net/Pastebin/3322

jak prawidłowo uzupełnić ta pętle? Druga działa chyba prawidłowo.

1

Nie możesz lecieć po elementach Throws gdy ta lista jest pusta! Poza tym jej elementy to listy intów, a nie same inty.

0
Shalom napisał(a):

Trochę magii javy 8:

List<Integer> input = Arrays.asList(6, 6, 1);
Map<Integer, Long> result = input.stream().collect(Collectors.groupingBy(roll -> roll, Collectors.counting()));

Na wejściu masz listę oczek które wypadły. Mapa którą uzyskujesz mapuje liczbę oczek na ilość kostek na których wypadły. Tzn result.get(1) zwróci 1 a result.get(6) zwróci 2.

próbując użyć tego kodu mam błąd "Lambda expressions are not supported at this languade level". JDK mam ustawione na jdk1.8.0_20

jak to zrobić nie używając takich zaawansowanych technik? Chce żeby do tego była osobna metoda.

0

Jakie IDE? Bo musisz też w ustawieniach IDE dać że projekt ma source code zgodny z Java 8.

0

http://stackoverflow.com/questions/505928/how-to-count-occurrence-of-an-element-in-a-list
Collections.frequency wygląda na to, czego potrzebujesz.

0
Shalom napisał(a):

Jakie IDE? Bo musisz też w ustawieniach IDE dać że projekt ma source code zgodny z Java 8.

IntelliJ Idea 13 wersja darmowa

1

No to wejdź sobie w File->Project Settings -> Project -> Language level i ustaw tam 8.0
A na przyszłość naucz się używac IDE...

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