java - Sorting of two-dimensional array based on two parameters -


the following code performs 'hierarchical' sorting of two-dimensional matrix. firstly, sorts elements based on values of ranks. secondly, takes sorted matrix, searches elements have same values of ranks, , sorts them based on dist. in descending order.

question 1: possible achieve same result in easier way? tried create comparator, provided incorrect result particular case.

question 2: how indexes of unsorted elements after sorting?

import java.util.arraylist;  public class test {      public static void main(string args[]) {          arraylist<arraylist<double>> values = new arraylist<arraylist<double>>();          arraylist<double> ranks = new arraylist<double>();         arraylist<double> dist = new arraylist<double>();          ranks.add(8.0);         ranks.add(3.0);         ranks.add(8.0);         ranks.add(1.0);          dist.add(1.8);         dist.add(2.8);         dist.add(1.9);         dist.add(2.1);          values.add(0,ranks);         values.add(1,dist);          int len = ranks.size();          arraylist<arraylist<double>> sortedranks = new arraylist<arraylist<double>>();          sortedranks = order(values,0,ranks.size());          boolean swapped = true;         int j = 0;         double tmp1, tmp2;         while (swapped) {               swapped = false;               j++;               (int = 0; < len - j; i++) {                     double val1 = sortedranks.get(0).get(i);                   double val2 = sortedranks.get(0).get(i+1);                   if (val1==val2) {                     if (sortedranks.get(1).get(i) < sortedranks.get(1).get(i+1)) {                             tmp1 = sortedranks.get(1).get(i);                         tmp2 = sortedranks.get(1).get(i+1);                         sortedranks.get(1).remove(i);                         sortedranks.get(1).remove(i);                         sortedranks.get(1).add(i,tmp2);                         sortedranks.get(1).add(i+1,tmp1);                         swapped = true;                     }                   }               }                         }          (int = 0; < len; i++) {             system.out.println("ranks " + + " : " + sortedranks.get(0).get(i)                     + ", distances : " + sortedranks.get(1).get(i));         }       }      public static arraylist<arraylist<double>> order(arraylist<arraylist<double>> values, int i_start, int i_fin) {         boolean swapped = true;         int j = 0;         int i_rank = 0;         int i_dist = 1;         double tmp1_rank, tmp2_rank, tmp1_dist, tmp2_dist;         while (swapped) {               swapped = false;               j++;               (int = i_start; < i_fin - j; i++) {                                                            if (values.get(i_rank).get(i) < values.get(i_rank).get(i+1)) {                                                     tmp1_rank = values.get(i_rank).get(i);                           tmp2_rank = values.get(i_rank).get(i+1);                           tmp1_dist = values.get(i_dist).get(i);                           tmp2_dist = values.get(i_dist).get(i+1);                           values.get(i_rank).remove(i);                           values.get(i_rank).remove(i);                           values.get(i_dist).remove(i);                           values.get(i_dist).remove(i);                           values.get(i_rank).add(i,tmp2_rank);                           values.get(i_rank).add(i+1,tmp1_rank);                           values.get(i_dist).add(i,tmp2_dist);                           values.get(i_dist).add(i+1,tmp1_dist);                           swapped = true;                     }               }                         }         return values;     } } 

the code uses comparator (does not work case):

public class myentry implements comparable<myentry> {      private double rank;     private double dist;      public myentry(double rank, double dist) {          this.rank = rank;         this.dist = dist;      }      public static comparator<myentry> valuecomparator = new comparator<myentry>() {          public int compare(myentry value1, myentry value2) {              double rfirst = value1.rank;             double rsecond = value2.rank;              double dfirst = value1.dist;             double dsecond = value2.dist;              if (rsecond != rfirst) {                 return (int) (rsecond - rfirst);             }              else {                 return (int) (dsecond - dfirst);             }          }      }; } 

your comperator approach work, has few bugs. first of replace doubles in myentry double.

comparing double not same comparing double example:

double = 1.0; double b = 1.0; system.out.println(a == b); system.out.println(a.equals(b)); system.out.println(a.doublevalue()== b.doublevalue()); 

will return

false true true 

then in comparison cast int, implies flooring data. (int) (2 - 1.9) give 0 better compare using < , return -1 or 1.

  public static comparator<myentry> valuecomparator = new comparator<myentry>() {      public int compare(myentry value1, myentry value2) {          double rfirst = value1.rank;         double rsecond = value2.rank;          double dfirst = value1.dist;         double dsecond = value2.dist;          if (rsecond != rfirst) {             return rsecond < rfirst?-1:1;         }          else if(dsecond!=dfirst){             return dsecond < dfirst ?-1:1;         }         return 0;      } } 

for second question require index. done in 2 ways. first option include index in myentry this:

 public class myentry implements comparable<myentry> {  private double rank; private double dist; private int index; private static int nextindex = 0;  public myentry(double rank, double dist) {      this.rank = rank;     this.dist = dist;     this.index = nextindex++;  } 

this way able retain index not flexible.

a more flexible approach have index in separate array, , sort that.

    class indexedarraycomparator implements comparator<integer>{      myentry[] array;      public indexedarraycomparator(myentry[] entries){         this.array=entries;     }      public integer[] createindexes(){         integer[] index = new integer[array.length];         for(int =0;i<index.length;i++){             index[i]=i;         }         return index;     }      public int compare(integer i0, integer i1) {         double rfirst = array[i0].rank;         double rsecond = array[i1].rank;          double dfirst = array[i0].dist;         double dsecond = array[i1].dist;          if (rsecond != rfirst) {             return rsecond > rfirst?-1:1;         }          else if(dsecond!=dfirst){             return dsecond > dfirst ?-1:1;         }         return 0;      }  } 

you can use this:

 myentry[] entries = new myentry[5];  entries[0]= new myentry(1.1,5);  entries[1]= new myentry(1.1,4);  entries[2]= new myentry(2.1,5);  entries[3]= new myentry(0.1,3);  entries[4]= new myentry(3.1,1);   indexedarraycomparator comp = new indexedarraycomparator(entries);  integer[] index = comp.createindexes();  arrays.sort(index,comp);  for(int =0;i<index.length;i++){      myentry e = entries[index[i]];      system.out.println(string.format("%2d:r= %3.1f, d= %3.1f" ,index[i],e.rank,e.dist));  } 

which give:

 3:r= 0.1, d= 3.0  1:r= 1.1, d= 4.0  0:r= 1.1, d= 5.0  2:r= 2.1, d= 5.0  4:r= 3.1, d= 1.0 

the second way of sorting while maintaining index described here. credits jon skeet


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -