PDA

View Full Version : [JAVA] dividere in range una sequenza di numeri double


JohnMarston
16-10-2015, 09:21
Ciao a tutti. Ho un range dinamico di valori double contenuti in un arraylist, in ordine crescente (sort).
La sequenza dei numeri può essere negativa/positiva, oppure tutti positivi o solo negativi.

Dunque, questa sequenza la devo dividere in range da 0.05 e tirar fuori gli elementi.

Posso avere il primo elemento che parte da -0.12 fino ad arrivare a +0.60.
Quindi dovrei prendere tutto il range partendo da -0.15 e andare avanti... -0.10, -0.05 fino a +0.60.
I valori all'interno del range (0.05) naturalmente li dovrò salvare in un altro arraylist.
Credevo fosse semplice, magari lo è, magari no... Io non riesco..Chi mi da una mano??
Posto una bozzetta...


public static void main( String[] args) {
double range=0.05;
double []val={-0.30688548677199914, -0.29132854259729857, 0.3639495706070589, 0.3740827373060958, 0.39350464014591247, 0.43910389029157854};
double counter[] = new double[val.length];
for (int i=0; i<val.length; i++) {

System.out.println("val " + val[i]);
int idx = (int)(val[i] / range);
idx = Math.min( idx, counter.length-1);
counter[idx]++;
System.out.println( "idx " + idx );
}



for ( int i = 0 ; i < counter.length-1 ; i++ ) {
System.out.println( counter[i] + " fra il range di " + i*range + " e " + (i+1)*range );
}
System.out.println( counter[counter.length-1] + " sono fuori" );
}

Don[ITA]
16-10-2015, 11:38
Se ho capito bene la tua richiesta, puoi prendere spunto da questo codice:

public static void main(String... args) {
double min = -0.15;
double max = 0.60;
double step = 0.05;
double[] data = {-0.30688548677199914, -0.29132854259729857, 0.3639495706070589, 0.3740827373060958, 0.39350464014591247, 0.43910389029157854};
Map<Map, ArrayList<Double>> grouped = group(data, min, max, step);
for(Map.Entry<Map, ArrayList<Double>> group : grouped.entrySet()) {
Map key = group.getKey();
ArrayList value = group.getValue();
System.out.println("min: " + key.get("min") + ", max: " + key.get("max") + ": " + value);
}
}

public static Map<Map, ArrayList<Double>> group(double[] data, double min, double max, double step) {
Map<Map, ArrayList<Double>> result = new HashMap<Map, ArrayList<Double>>();
for(double i = min; i < max; i += step) {
for(int j = 0; j < data.length; j++) {
double number = data[j];
if(number >= i && number < i + step) {
Map<String, Double> key = new HashMap<String, Double>();
key.put("min", i);
key.put("max", i + step);
if(result.get(key) == null) result.put(key, new ArrayList<Double>());
result.get(key).add(number);
}
}
}
return result;
}

sottovento
16-10-2015, 16:00
Supponendo che
- data contenga i tuoi dati (per comodita', lo considero di tipo Double[]);
- esista un ArrayList<Double> intervals, contenente il numero di partenza (il minimo) di ogni intervallo (l'intervallo si estendera' poi fino al numero successivo. Ovviamente intervals e' ordinato).
Per intenderci, intervals nel tuo caso potrebbe essere:

ArrayList<Double> intervals = new ArrayList<>();
for (double v = min; v < max; v += step)
intervals.add(v);


puoi risolvere il problema con una sola linea di codice:

intervals.stream().forEach(m -> System.out.println("[" + m + ", " + (m + step) + ") : " + Arrays.asList(data).stream().filter(v -> m <= v && v < (m+step)).map(el -> el.toString()).reduce("", (a,b) -> a + " " + b)));

JohnMarston
18-10-2015, 04:15
Grazie! Con alcune modifiche son riuscito prendendo spunto dai vostri interventi.