• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 278
  • Last Modified:

Order two sets of numbers

Just going to cross link this thread to this one (hope thats allowed)
http://www.experts-exchange.com/Miscellaneous/Math_Science/Q_21873250.html

where I asked the question, just want to post it here to as this has to do with my Delphi application.
(and I doubt that area will get much people visiting it and it's relavent)


Thanks guys :D
0
wildzero
Asked:
wildzero
  • 10
  • 8
2 Solutions
 
BlackTigerXCommented:
just put the numbers in a StringList and sort it

theList:TStringList;
X:Integer;
begin
  theList:=TStringList.Create();
  theList.Add('10=5');
  theList.Add('12=8');
  theList.Add('20=12');
  theList.Add('5=5');
  theList.Add('9=0');
  theList.Sort();
...
0
 
wildzeroAuthor Commented:
When I do
var
theList:TStringList;
begin
  theList:=TStringList.Create();
  theList.Add('10=5');
  theList.Add('12=8');
  theList.Add('20=12');
  theList.Add('5=5');
  theList.Add('9=0');
  theList.Sort();
  listbox1.Items.assign(theList);


it doesn't sem to sort them all (when I see them in the listbox....)
0
 
ginsonicCommented:
I don't understand your algorithm. You want to sort after left part? right part? results from left part minus right part ?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ginsonicCommented:
For difference:

Add a button and a ListView to your form. Set to vsReport the ViewStyle of your form and ad a column to it.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    {}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function Compare(Item1, Item2: TListItem; Data: integer):
  integer; stdcall;
var
  n1, n2: integer;
  s1, s2: string;
begin
  s1 := Trim(Copy(Item1.Caption, 1, Pos('-',Item1.Caption) - 1));
  s2 := Trim(Copy(Item1.Caption, Pos('-',Item1.Caption) + 1, Length(Item1.Caption)));
  n1 := StrToInt(s1) - StrToInt(s2);

  s1 := Trim(Copy(Item2.Caption, 1, Pos('-',Item2.Caption) - 1));
  s2 := Trim(Copy(Item2.Caption, Pos('-',Item2.Caption) + 1, Length(Item2.Caption)));
  n2 := StrToInt(s1) - StrToInt(s2);

  if n1 > n2 then
    Result := -1
  else if n1 < n2 then
    Result := 1
  else
    Result := 0;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 ListView1.CustomSort(@Compare, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
var Itm:TListItem;
begin
 ListView1.Items.BeginUpdate;


  Itm:=ListView1.Items.add;
  Itm.Caption := '10 - 6';

  Itm:=ListView1.Items.add;
  Itm.Caption := '14 - 9';

  Itm:=ListView1.Items.add;
  Itm.Caption := '6 - 9';

  Itm:=ListView1.Items.add;
  Itm.Caption := '6 - 6';

  Itm:=ListView1.Items.add;
  Itm.Caption := '8 - 2';

  ListView1.Items.EndUpdate;
end;

end.
0
 
wildzeroAuthor Commented:
havn't come up with an algorithm yet.
Baically
want to sort the left numbers so they rank highest to lowerst however have to take into consideration the right numbers
like
9-5
and
9-6

it would rank as
9-6
9-5
or

10-8
and 12-11

would rank
10-8
12-11
0
 
ginsonicCommented:
sorting by left:

function Compare(Item1, Item2: TListItem; Data: integer):
  integer; stdcall;
var
  n1, n2: integer;
  s1, s2: string;
begin
  s1 := Trim(Copy(Item1.Caption, 1, Pos('-',Item1.Caption) - 1));
  //s2 := Trim(Copy(Item1.Caption, Pos('-',Item1.Caption) + 1, Length(Item1.Caption)));
  n1 := StrToInt(s1);// - StrToInt(s2);

  s1 := Trim(Copy(Item2.Caption, 1, Pos('-',Item2.Caption) - 1));
  //s2 := Trim(Copy(Item2.Caption, Pos('-',Item2.Caption) + 1, Length(Item2.Caption)));
  n2 := StrToInt(s1);// - StrToInt(s2);

  if n1 > n2 then
    Result := -1
  else if n1 < n2 then
    Result := 1
  else
    Result := 0;
end;
0
 
ginsonicCommented:
Let me understand:

Sort left from highter to lower. If equal sort by right.
0
 
ginsonicCommented:
I want to say from lower to highter to left and from highter to lower to right. This I understand from samples.

This is the code for sorting:


function Compare(Item1, Item2: TListItem; Data: integer):
  integer; stdcall;
var
  n1, n2: integer;
  s1, s2: string;
begin
  s1 := Trim(Copy(Item1.Caption, 1, Pos('-',Item1.Caption) - 1));
  n1 := StrToInt(s1);

  s1 := Trim(Copy(Item2.Caption, 1, Pos('-',Item2.Caption) - 1));
  n2 := StrToInt(s1);

  if n1 < n2 then
    Result := -1
  else if n1 > n2 then
    Result := 1
  else begin
    s2 := Trim(Copy(Item1.Caption, Pos('-',Item1.Caption) + 1, Length(Item1.Caption)));
    n1 := StrToInt(s2);
    s2 := Trim(Copy(Item2.Caption, Pos('-',Item2.Caption) + 1, Length(Item2.Caption)));
    n2 := StrToInt(s2);
    if n1 > n2 then
      Result := -1
    else if n1 < n2 then
      Result := 1
    else
      Result := 0;
  end;


end;
0
 
wildzeroAuthor Commented:
Almost
It's a hard one to understand...

Think of it like this
x - y

x = number of rooms
y = number of kids

y can be greater then x (ie 5 - 15)

What am trying to do is sort the list so
the top item contains the highest number of rooms to the lowest number of kids
So I guess you could look at the x:y as ratios...

the other thing have to look at is
6 - 0
that will rank higher then
8 - 4

That help?
0
 
ginsonicCommented:
Test:

10 - 6
14 - 9
9 - 5
9 - 6
8 - 2

Result:

8 - 2
9 - 6
9 - 5
10 - 6
14 - 9

you can play with < and > to next code part to set your order way. if change the > to <, then must change next < to >.

 if n1 > n2 then
      Result := -1
    else if n1 < n2 then
      Result := 1
    else
      Result := 0;
  end;
0
 
ginsonicCommented:
Next code will return an order from highter to lower left part. If have two or more equal left numbers then will order for right part from lower to hghter.


function Compare(Item1, Item2: TListItem; Data: integer):
  integer; stdcall;
var
  n1, n2: integer;
  s1, s2: string;
begin
  s1 := Trim(Copy(Item1.Caption, 1, Pos('-',Item1.Caption) - 1));
  n1 := StrToInt(s1);

  s1 := Trim(Copy(Item2.Caption, 1, Pos('-',Item2.Caption) - 1));
  n2 := StrToInt(s1);

  if n1 > n2 then
    Result := -1
  else if n1 < n2 then
    Result := 1
  else begin
    s2 := Trim(Copy(Item1.Caption, Pos('-',Item1.Caption) + 1, Length(Item1.Caption)));
    n1 := StrToInt(s2);
    s2 := Trim(Copy(Item2.Caption, Pos('-',Item2.Caption) + 1, Length(Item2.Caption)));
    n2 := StrToInt(s2);
    if n1 < n2 then
      Result := -1
    else if n1 > n2 then
      Result := 1
    else
      Result := 0;
  end;

end;
0
 
ginsonicCommented:
The idea is that you get the value for the left part in s1 and right in s2. After that you can play how you wish with results. Can make any math op. with these. And the results can be compared with

 if n1 < n2 then
      Result := -1
    else if n1 > n2 then
      Result := 1
    else
      Result := 0;

I must go now for one hour. But I will return to see if you need more help.
0
 
wildzeroAuthor Commented:
In that latest code I get this returned after sort
14-9
10-6
8-2
6-6
6-9

when it should be

8-2
14-9
10-6
6-6
6-9

0
 
wildzeroAuthor Commented:
If you do this

x - y

  Itm.SubItems.Add( FormatFloat('',x -((y / x) * y)) );

and then sort that - it almost gets there...
0
 
wildzeroAuthor Commented:
Hmmm I think it's going to be better to  sort by difference and if the difference is the same as another it sorts that one by the count

ie
x - y
c = (x - y)
Order by C DESC
Then loop and find any duplicate c and if so order them

Might code that up
0
 
wildzeroAuthor Commented:
mmm I guess now it's just a list of ratios
like
5:4
2:6

and ordering those
and just have to put in excpetipns for
ones like
5:5
9:9

and
ones like
5:19
 etc
0
 
ginsonicCommented:
It's hard to me to understand what you need. Anyway s1, s2 get the two values (rooms and kids) for first compared item:

  s1 := Trim(Copy(Item1.Caption, 1, Pos('-',Item1.Caption) - 1));
  s2 := Trim(Copy(Item1.Caption, Pos('-',Item1.Caption) + 1, Length(Item1.Caption)));
  n1 := Here you can make any math

same work for second compared item:

  s1 := Trim(Copy(Item2.Caption, 1, Pos('-',Item2.Caption) - 1));
  s2 := Trim(Copy(Item2.Caption, Pos('-',Item2.Caption) + 1, Length(Item2.Caption)));
  n2 := Here you can make any math


and finally order :

    if n1 < n2 then
      Result := -1
    else if n1 > n2 then
      Result := 1
    else
      Result := 0;

or:

    if n1 > n2 then
      Result := -1
    else if n1 < n2 then
      Result := 1
    else
      Result := 0;
0
 
ginsonicCommented:
Problems?
0
 
wildzeroAuthor Commented:
This is what I have done


Function GetWeight(iOccur, iResp : integer) : string;
var
  vO, vR, vFinal : real;
  sResult : string;
Begin
  vO := iOccur;
  vR := iResp;
  vFinal := vO * (( vO - Vr) / (vO + vR));

  Str(vFinal:10:2, sResult);
  Result := sResult;
End;
//==============================================================================

So when the items are added to the listview this happens

  caption := 'Something';
  subitems.add('10');
  subitems.add(5);
  subitems.add(GetWeight(10, 5));

then order the list by that column.
Works good

0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 10
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now