假如有一个对象有两个属性:name姓名,age年龄,现在有一组数据
按姓名排好序,如下:
name:aaa, age:19
name:aaa, age:20
name:aaa, age:21
name:aaa, age:22
name:aaa, age:23
name:aaa, age:24
name:aaa, age:25
name:bbb, age:21
name:bbb, age:22
name:bbb, age:23
name:bbb, age:24
name:bbb, age:25
name:bbb, age:26
现在我数据一个年龄:23
那么获得的新的排序如下:
name:aaa, age:23
name:aaa, age:22
name:aaa, age:24
name:aaa, age:21
name:aaa, age:25
name:aaa, age:20
name:aaa, age:19
name:bbb, age:23
name:bbb, age:22
name:bbb, age:24
name:bbb, age:21
name:bbb, age:25
请教大神们如果用java怎么实现这个算法?
是一大一小轮流排序的,不是直接从大到小,或者从小到大排序
int len = array.length();
for ( int i = 0 ; i < len ; i++ )
{
for(int j = i ; j < len ; j++)
{
if ( array[i].name < array[j].name || (array[i].name == array[j].name && array[i].age < array[j].age) )
{
swap(array[i],array[j]);
}
}
}
伪代码
?你的数据是不是反了,如果你要规范排序的话应该是先按姓名排序相同的按年龄排序,可以了解一下Comparable接口
按姓名分成Map<\String,\List>,list根据年龄排序后,从中间取,+1,-1循环取出来放到一个新的集合,
public static void main(String[] args) throws CloneNotSupportedException {
Student s1 = Student.of("aaa",20);
Student s2 = Student.of("aaa",23);
Student s3 = Student.of("aaa",21);
Student s4 = Student.of("aaa", 24);
Student s5 = Student.of("bbb",22);
Student s6 = Student.of("bbb",23);
Student s7 = Student.of("bbb",21);
Student s8 = Student.of("bbb", 24);
Student s9= Student.of("bbb",25);
List<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
list.add(s6);
list.add(s7);
list.add(s8);
list.add(s9);
list.sort((o1, o2) -> {
int c1 = o1.getName().compareTo(o2.getName());
if (c1 != 0){
return c1;
}
return o1.getAge()-o2.getAge();
});
//第一次按姓名+年龄排序的结果
System.out.println(JSON.toJSONString(list));
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
Map<String,List<Student>> map = list.stream().collect(Collectors.groupingBy(Student::getName));
//转成treemap按名字排序
TreeMap<String, List<Student>> treeMap = new TreeMap<>();
for (Map.Entry<String, List<Student>> entry : map.entrySet()) {
String key = entry.getKey();
List<Student> value = entry.getValue();
List<Student> newList = new ArrayList<>();
value.sort(Comparator.comparing(Student::getAge));
int size = value.size();
int targetIndex = halfSearch(age, value,0, size);
//targetIndex=-1这边要结束,报错
newList.add(value.get(targetIndex));
//得到要遍历的次数
int interval = Math.max(targetIndex,size-1-targetIndex)+1;
for (int i = 1; i < interval; i++) {
int min = targetIndex - i;
int max = targetIndex + i;
if (min >= 0){
newList.add(value.get(min));
}
if (max<size){
newList.add(value.get(max));
}
}
treeMap.put(key, newList);
}
List<Student> finalList = new ArrayList<>();
for (List<Student> students : treeMap.values()) {
finalList.addAll(students);
}
System.out.println(JSON.toJSONString(finalList));
}
/**
* 查询满足输入的年龄的同学的位置下标
* @param age
* @param list
* @return
*/
private static int halfSearch(int age, List<Student> list, int left, int right){
if (left > right){
//-1表示没找到,如果想正常运行,可以根据需求返回left或者right
return -1;
}
int mid = left + (right - left) / 2;
int midAge = list.get(mid).getAge();
if (midAge > age){
return halfSearch(age,list,left, mid-1);
}
if (midAge < age){
return halfSearch(age,list, mid + 1, right);
}
return mid;
}
//list 就是数据集合 DatasBean就是你的类
Collections.sort(list, new Comparator<DatasBean>() {
@Override
public int compareDatasBean datasBean, DatasBean t1) {
return datasBean.getName().compareTo(t1.getName());
}
});
Collections.sort(list, new Comparator<DatasBean>() {
@Override
public int compare(DatasBean datasBean,DatasBean t1) {
return datasBean.getAge()-datasBean.getAge();
}
});
//最后得到的结果就是先用名称排序,再用年龄排序
@Data
@AllArgsConstructor
public class Student implements Comparator {
private String name;
private Integer age;
@Override
public int compare(Student o1, Student o2) {
if(0==o1.name.compareTo(o2.name)){
if(o1.age==o2.age){
return 0;
}else if (o1.age>o2.age){
return 1;
}else {
return -1;
}
}
return o1.name.compareTo(o2.name);
}
public static void main(String[] args) {
List<Student> sList = new ArrayList<>();
Student s1 = new Student("aaa",19);
Student s2 = new Student("aaa",25);
Student s3 = new Student("bbb",24);
Student s4 = new Student("bbb",21);
Student s5 = new Student("ccc",19);
Student s6 = new Student("ccc",23);
Student s11 = new Student("ccc",25);
Student s7 = new Student("ccc",12);
Student s8 = new Student("ddd",21);
Student s9 = new Student("ddd",25);
Student s10 = new Student("ddd",29);
sList.add(s1);
sList.add(s2);
sList.add(s3);
sList.add(s4);
sList.add(s5);
sList.add(s6);
sList.add(s7);
sList.add(s8);
sList.add(s9);
sList.add(s10);
sList.add(s11);
sList.sort((Student o1, Student o2)-> {
if(0==o1.name.compareTo(o2.name)){
if(o1.age==o2.age){
return 0;
}else if (o1.age>o2.age){
return 1;
}else {
return -1;
}
}
return o1.name.compareTo(o2.name);
});
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
Map<String,List<Student>> resultMap = sList.stream().collect(Collectors.groupingBy(Student::getName));
Set<String> keySet = resultMap.keySet();
List<Student> s = new ArrayList<>();
for (String key:keySet){
List<Student> list = resultMap.get(key);
Map<Integer,List<Student>> map = list.stream().collect(Collectors.groupingBy(Student::getAge));
if(map.get(age)!=null){
s.addAll(map.get(age));
list = list.stream().filter(stu->age!=stu.getAge()).collect(Collectors.toList());
s.addAll(list);
}else {
s.addAll(list);
}
}
s.sort((Student o1, Student o2)-> {
return o1.name.compareTo(o2.name);
});
s.stream().forEach(stu->System.out.println(stu));
}
}
比较规则改为如下就行
bool isLesser(T a, T b, age c){
int da = a.age >= c ? a.age : c + ( c - a.age ) - 0.5;
int db = b.age >= c ? b.age : c + ( c - b.age ) - 0.5;
if(a.name != b.name)
return a.name < b.name;
return da <= db;
}
//23 22 24 21 25 20 19
//对应
//23 23.5 24 24.5 25.5 26.5 27.5
//这样再按正常的方法排序就行了
对应的情况是a排在b前面