n个小数待分组,每个数组k个,如果n%k==0,那么组数为n/k个,如果n%k!=0,则最后一组的数量为n%k,组数为n/K+1,要求每个组的均值相等或者相近!
import java.util.*;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
public class GroupTest {
public static void main(String[] args) {
double[] nums = {100.0, 1.0, 20.0, 50.0, 90.0, 91.0, 92.0, 31.0, 32.0, 63.0,
33.0, 45.0, 56.0, 78.0, 88.0, 99.0, 8.0, 13.0, 23.0, 53.0, 67.0};
int k = 8;
group(nums, k);
}
public static void group(double[] values, int countPerGroup) {
// order first, get len%countPerGroup from middle
// the left split to several groups
// calculate the average, get len%countPerGroup numbers which totally to it
// cycle, if min, select the max
Arrays.sort(values);
List<Double> lstNums = new ArrayList<>();
for(double value: values) {
lstNums.add(value);
}
List<Double> middleList = new ArrayList<>();
int midLen = values.length%countPerGroup;
if(midLen != 0) {
middleList = middle(lstNums, midLen, Arrays.stream(values).average().getAsDouble());
}
List<List<Double>> lstGroups = new ArrayList<>();
int groups = values.length/countPerGroup;
for(int i = 0; i < groups; i++) {
lstGroups.add(new ArrayList<>());
}
for(int i = 0; i < countPerGroup; i++) {
lstGroups = lstGroups.stream().sorted((a, b) -> {
double total_a = a.stream().reduce(0.0, Double::sum);
double total_b = b.stream().reduce(0.0, Double::sum);
return Double.compare(total_a, total_b);
}).collect(Collectors.toList());
lstGroups.forEach(group -> {
group.add(max(lstNums));
});
}
if(midLen != 0) {
lstGroups.add(middleList);
}
lstGroups.forEach(group -> {
System.out.println("average:" + group.stream().reduce(0.0, Double::sum)/group.size()
+ ", count:" + group.size()
+ ", elements:" + group.toString());
});
}
public static List<Double> middle(List<Double> values, int count, double average) {
List<Double> middleList = new ArrayList<>();
if(count == 1) {
middleList.add(mostNear(values, average));
} else {
List<Double> tmp = middle(values, count - 1, average);
double total = 0.0;
for(double value : tmp) {
total = total + value;
}
middleList.addAll(tmp);
middleList.add(mostNear(values, average * count - total));
}
return middleList;
}
public static double mostNear(List<Double> values, double average) {
double nearestValue = 0.0;
double gap = values.stream().max(Double::compareTo).get();
for(double value: values) {
if(Math.abs(value - average) < gap) {
gap = Math.abs(value - average);
nearestValue = value;
} else {
break;
}
}
// remove from the list
values.remove(nearestValue);
return nearestValue;
}
public static double max(List<Double> values) {
double maxValue = values.stream().max(Double::compareTo).get();
values.remove(maxValue);
return maxValue;
}
}
最后一组的数量为n-k*(n%k)个 那么前面K个组的数量就不是 n%k个
刚才没仔细看。问题应该是:n个小数待分组,每个数组k个,如果n%k==0,那么每组个数为n/k个,如果n%k!=0,则最后一组的数量为n%k个,要求每个组具有相同或者相近的均值。
不知道你问什么,前面的还能通。。。。
每个数组k个----那么每组个数为n/k个
这两个是重定义了吗-_-!
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class GroupTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 10;
double [] numbers = new double[205];
for (int i = 0; i < numbers.length; i++) {
double number = 2.51 + Math.random() * (3.5 - 2.51);
numbers[i] = number;
}
group(numbers, k);
}
public static void group(double[] values, int countPerGroup) {
Arrays.sort(values);
List<Double> lstNums = new ArrayList<Double>();
for(double value: values) {
lstNums.add(value);
}
List<Double> middleList = new ArrayList<Double>();
int midLen = values.length%countPerGroup;
if(midLen != 0) {
//--获取中间的几个数据
middleList = middle(lstNums, midLen, getAverage(values));
}
List<List<Double>> lstGroups = new ArrayList<List<Double>>();
int groups = values.length/countPerGroup;
for(int i = 0; i < groups; i++) {
lstGroups.add(new ArrayList<Double>());
}
for(int i = 0; i < countPerGroup; i++) {
//---将数组按照从小到大的顺序排列
Collections.sort(lstGroups, new Comparator<List<Double>>() {
public int compare(List<Double> o1, List<Double> o2) {
// TODO Auto-generated method stub
Double sum1 = getSum(o1);
Double sum2 = getSum(o2);
return sum1.compareTo(sum2);
}
});
for (List<Double> list : lstGroups) {
list.add(max(lstNums));
}
}
if(midLen != 0) {
lstGroups.add(middleList);
}
for (List<Double> list : lstGroups) {
for (Double double1 : list) {
System.out.print(double1+" ");
}
System.out.println();
System.out.println("均值为" + getAverage(list));
}
}
public static List<Double> middle(List<Double> values, int count, double average) {
List<Double> middleList = new ArrayList<Double>();
if(count == 1) {
middleList.add(mostNear(values, average));
} else {
List<Double> tmp = middle(values, count - 1, average);
double total = 0.0;
for(double value : tmp) {
total = total + value;
}
middleList.addAll(tmp);
middleList.add(mostNear(values, average * count - total));
}
return middleList;
}
public static double mostNear(List<Double> values, double average) {
double nearestValue = 0.0;
Collections.sort(values);
double gap = values.get(values.size()-1);
for(double value: values) {
if(Math.abs(value - average) < gap) {
gap = Math.abs(value - average);
nearestValue = value;
} else {
break;
}
}
values.remove(nearestValue);
return nearestValue;
}
public static double max(List<Double> values) {
Collections.sort(values);
double maxVaule=values.get(values.size()-1);
values.remove(maxVaule);
return maxVaule;
}
public static double getAverage(double [] arr){
double sum=0.0;
for(int i=0;i<arr.length;i++){
sum+=arr[i];
}
return sum/arr.length;
}
public static double getAverage(List<Double> list){
double sum=0.0;
for(int i=0;i<list.size();i++){
sum+=list.get(i);
}
return sum/list.size();
}
public static double getSum(List<Double> list){
double sum=0.0;
for(Double value:list){
sum+=value;
}
return sum;
}
}