Witam.
Jestem tutaj nowy i nie wiem czy we właściwym dziale dałem temat. Jest on bardziej algorytmiczny.
Chodzi mi o losowanie punktów 2D z zadanej przestrzeni tak, aby się nie powtarzały aż do wyczerpania puli.
Oto, co napisałem w Javie:
import java.util.*;
/**
* Losowanie bez zwracania punktu z przestrzeni 2D.
*/
public class UniquePoint2DGenerator {
private final List<Integer> xCoords = new LinkedList<Integer>();
private final List<List<Integer>> yCoords = new LinkedList<List<Integer>>();
private final List<Integer> indexes = new LinkedList<Integer>();
private final int X_MIN, Y_MIN, X_MAX, Y_MAX, MAX_POINTS;
private final Random rand = new Random();
private int counter;
/**
* @param xMax rozmiar przestrzeni 2D w kierunku X
* @param yMax rozmiar przestrzeni 2D w kierunku Y
*/
public UniquePoint2DGenerator(int xMin, int yMin, int xMax, int yMax){
X_MIN = xMin;
Y_MIN = yMin;
X_MAX = xMax;
Y_MAX = yMax;
MAX_POINTS = (X_MAX - X_MIN) * (Y_MAX - Y_MIN);
counter = MAX_POINTS;
initializeCoords();
}
private void initializeCoords(){
for(int i=X_MIN, k=0; i<X_MAX; i++, k++){
xCoords.add(i);
indexes.add(k);
List<Integer> tmp = new LinkedList<Integer>();
for(int j=Y_MIN; j<Y_MAX; j++){
tmp.add(j);
}
yCoords.add(tmp);
}
}
private void removeEmptyList(){
for(int i=0; i<indexes.size(); i++){
int index = indexes.get(i);
if(yCoords.get(index).isEmpty()){
indexes.remove(i);
return;
}
}
}
/**
* @return unikalny punkt z przestrzeni 2D lub null jeśli pula
* punktów została wyczerpana. Resetowanie generatora następuje
* po wywołaniu metody reset()
*/
public Point nextPoint(){
if(counter == 0){
return null;
}
counter--;
removeEmptyList();
int indexPos = rand.nextInt(indexes.size());
int xPos = indexes.get(indexPos);
int x = xCoords.get(xPos);
int yPos = rand.nextInt(yCoords.get(xPos).size());
int y = yCoords.get(xPos).remove(yPos);
return new Point(x, y);
}
/**
* Resetowanie generatora. Po wywołaniu metoda nextPoint() ponownie
* będzie zwracała punkty zamiast wartości null.
*
*
*/
public void reset(){
xCoords.clear();
yCoords.clear();
indexes.clear();
initializeCoords();
counter = MAX_POINTS;
}
//test case
public static void main(String... args){
Matrix m = new Matrix();
m.print();
System.out.println();
UniquePoint2DGenerator rand = new UniquePoint2DGenerator(10,9,19,18);
Point p;
int a = 0;
while( (p = rand.nextPoint()) != null ){
if(a%2 == 0)m.put(p);
a++;
}
m.print();
}
}
class Matrix{
char[][] tab = new char[20][20];
public Matrix(){
for(int i=0; i<20; i++){
for(int j=0; j<20; j++){
tab[i][j]='o';
}
}
}
public void print(){
for(int i=0; i<20; i++){
for(int j=0; j<20; j++){
System.out.print(tab[i][j] + " ");
}
System.out.println();
}
}
public void put(Point p){
tab[p.getX()][p.getY()] = 'x';
}
}
Czy da się to napisać ładniej, wydajniej?
Metoda ta będzie krytyczna dla aplikacji.
Z góry dziękuję za wskazówki i sugestie!