Sort values, but only if they are greater than X of the current order

I searched Google (and the stack overflow, of course!) To sort the list of integers by value, but also an additional factor. I'm looking for some kind of algorithm to implement, I suppose. So far, I have an array in Delphi 2007 that sorts values โ€‹โ€‹from the largest to the smallest, but now I would like it to sort the values โ€‹โ€‹that are only X greater than the previous number in the list.

For example, the values โ€‹โ€‹5, 7, 25, 15 are currently sorted by 25, 15, 7, 5. The order that I am trying to get now, with an X value of 5, is 25, 15, 5, 7. As you can see , 5 and 7 do not switch positions, because there is no difference between them more than 5.

Not sure if I explain this particularly well, but what a general idea.

Another example would be 10, 40, 18, 20, 16, 28. Sorted, they should be 40, 28, 18, 20, 16, 10. 18, 20 and 16 are not moved, because again, between each from numbers no more than 5.

The idea behind this is that the item associated with the number (for example, the number of times when something was ordered) does not change all the time due to a difference of only 1 or 2. For example, if the list of most frequently ordered paper is displayed on the web page at the acquired frequency, then the order of a specific type of paper will be changed only for the user if he was ordered more than five times more than the next most frequent one.

Hope this makes sense and thanks for your time!

+4
source share
8 answers

I think your requirement leads to really strange results. You can ultimately have a sort order, when items are sorted just as wrong, and how they are sorted depends on how they change.

I think you need to set the โ€œclassesโ€ of values โ€‹โ€‹(use percentiles?), And then sort the newspapers alphabetically in each class.

For example: barely ordered (90% of documents are ordered more than this one), lower than the median (50% of newspapers are ordered more than them), higher than the median, top 10 orders (sorted by the number of orders of course).

+3
source

At least you need to use a stable view, i.e. sorting that preserves the order of equivalent values.

Once you do this, you should probably define your comparison as if abs(a - b)<5 , otherwise, do the normal comparison. This makes compare(a, b)==compare(b, a) , which would have to state the best sorting implementations.

If you use C ++, you can use std::stable_sort for this.

+3
source

After thinking about it, I think that sorting bubbles is the only type that will work. This is due to the fact that in the sorting of the bubble the number should be clearly larger (or in this case 5 more) than the numbers located above it so that they can change places. This is exactly what you asked for.

From a high level point of view, here I think you need:

  • An implementation of bubble sorting that accepts a custom comparison function.

  • comparison function that returns equal if the difference is less than 5.

The fusion of these two things should leave you for what you need.

+2
source

Two things are important for this:

1) You need a sorting algorithm that is stable (it should not look like a bubble, although it probably shouldn't), that is, it retains the original order if the comparator returns 0 (= equal). See wikipedia comparisons of sorting algorithms for a good overview.

2) You need a custom comparator that returns 0 exactly in the cases that you mentioned.
+1
source

Try sorting using the special comparison function, you can quickly try this if you populate TList with numbers and call MyList.Sort (myCompareFunc);

 function myCompareFunc(item1,item2:Pointer):Integer; var v1,v2:Integer; begin v1 := (integer)item1; v2 := (integer)item2; if v1 > v2 then result := 1 else if (v1 < v2 ) result := -1 else result := 0 //most important if abs(v1-v2) < 5 result := 0 ; end; 
0
source

It may make sense to apply your sorting principle to an almost sorted list, but you should be aware that it violates the basic assumption of general sorting algorithms: that the elements to be sorted form a complete order. This is very important, the operator behaves as it does for real numbers. If you break this rule, you can get strange effects, and library algorithms may not even stop (or even crash, I saw how it happened for std :: sort in C ++).

One way to change your idea to make it complete is to sort with respect to each number rounded to the nearest multiple of 5.

0
source

I think this requires two passes. On the first pass, determine any values โ€‹โ€‹that are to be sorted, and on the second pass, only those that are identified are actually moved. In the second example, using an Y / N array with sorting Y, you get [Y, Y, N, N, N, Y], and then only by sorting the values โ€‹โ€‹of Y, N will be "ignored, not sortable", you will get your list from [40, 28, 18, 20, 16, 10]. A group from N (always being a definition-based group) should be compared as the highest value in its group.

0
source

TList.Sort will not work because it uses a fast sorting algorithm, as mghie commented.

Bubble's sorting algorithm is not so fast, here is the implementation, so you can try, this time in pascal.

 var I,N,T,D:Integer ; A:array of Integer; Change:Boolean; begin SetLength(A, 4); A[0] := 5; A[1] := 7; A[2] := 25; A[3] := 15; Change := True; N := High(A); while Change do begin Change := false; for I := 1 to N do begin D := A[I]-A[I-1]; if (D > 5) then begin T := A[I-1]; A[I-1] := A[I]; A[I] := T; Change := true; end; end; end; end; 
0
source

All Articles