Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Finding smallest number 1

Status
Not open for further replies.

pierrotsc

Programmer
Nov 25, 2007
358
US
I am trying to see if there's a more efficient algoritm to find the smallest and biggest number in an array.
I have an array that has a size of 101.
Right now i am doing a loop and comparing each values to locate the smallest and largest but the code looks heavy to me and not very efficient.

what would be a good way to do that?
Thanks.
P
 
If adding information to your array is not done in bulk, but one by one, via user input, then it may be better to keep track of the min and max as they are put into the array.

create one method that is responsible for inserting information into your array, and before you insert it, check the value against the current min and max values, replace if needed.

Code:
  ...
  private
    min, max: integer;
    First: Boolean;
    procedure AddToArray(value: Integer);
  public
  ..
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   First := True;
   ...
end;

procedure TForm1.AddToArray(value: Integer);
begin
   if First then
   begin
      min := value;
      max := value;
      //first time, no values are selected as min or max
   end
   else
   begin
      if value > max then
         max := value
      else if value < min then
         min := value;
   end;
end;

This will add time to to adding to the array, so if you are looking for overall efficiency, this will probably slow things down, but if the values are entered by a user, the time difference at that point is minimal.
 
Sorry, forgot to set First to False;
Code:
if First then
begin
   min := value;
   max := value;
   //first time, no values are selected as min or max
   First := False;
end;
 
The data are entered in bulk. There's no user input.
Right now, i am oing through all the values comparing one to another. If i find a lower value than the one already memorized, then i swap.

Thanks for your input.
P
 
An alternative is to use the functions MinValue and MaxValue, or MinIntValue and MaxIntValue.
These functions belong to the Math unit.

I hope this help.


Imobiliarias em Suzano
 
That is a great idea, but i do not think it will tell me which index has the lowest or highest values. It would only give me the values.

Thanks for the feedback...
P
 
just sort your array, the first and last values are your min & max...

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
but if i do that, index 0 is the lowest and 100 is the highest. i need to find out which index has the lowest and the highest value. it could be 6 and 89.
Maybe i am thinking wrong...
i am scanning 101 gray scale patches and get a gray value for each patch.
i store all the values in an array, then i need to find out which patch has the lightest value and which one has the darkest. i may also get duplicate values for certain patches so i need the highest patch index value for the darkest patch and the lowest index value for the lightest patch. i am scanning from dark to light.

the way i am doing it now is working but the code is heavy i think. looking for a more efficient way to do it.
Thanks.
 
Without sorting the array (which would increase the time to load the array), I just don't see how you can get away from iterating through every single element of the array.
Code:
type
   MyArray = array [0..100] of integer;
   ArrayMinMax = record
      Min, Max: Integer;
   end;

Function FindMinMax(A: MyArray): ArrayMinMax;
begin
   //finds the index of the min and max element
   Result.Min := 0;
   Result.Max := 0;
   for I := (Low(A)+1) to High(A) do
      if A[I] < A[Result.Min] then
         Result.Min := I
      else if A[I] > A[Result.Max] then
         Result.Max := I;
end;

usage
   
var
   MyMinMax: ArrayMinMax;
   MyArrayInstance: MyArray;
begin
   MyMinMax := FindMinMax(MyArrayInstnace);

   //MyMinMax.Min holds the index to the min value.
   //MyMinMax.Max holds the index to the max value.
end;
 
I like your code a lot better than mine so i am going to use it..
Really appreciate it.
P
 
How do i input my values in Myarray? I tried myarray:= some value;
But it is giving me an error.
Thanks.
 
It gives me the error on the [ and says it expects a (
P
 
Can you paste your code?

Also, forgot to add the declaration for I in

Function FindMinMax(A: MyArray): ArrayMinMax;
var
I: Integer; <--These two lines

 
here you go:

type
MyArray = array[0..100] of Double;
ArrayMinMax = record
Min, Max: Integer;
end;

procedure TFrm_SuggestedC.Initializevariables;
var
i: Integer;
begin
if EmbeddedDM.nxTable_Projects.FieldByName('Project_Method').AsString =
'Densitometer' then
begin
for i := 0 to 100 do
begin
MyArray := EmbeddedDM.nxTable_trials.fields.fields[i +
8].AsFloat;
end;
end;
end;
 
Never mind..I got it to work. I was assigning it the wrong way.
It works great...
P
 
A word of warning, I thought the values held in the array were integer, as per your example, they are double instead.

Comparing doubles is not as straight forward as comparing floating point values, so you should add the Math and types units to your uses clause and change the code to the function to:
Code:
Function FindMinMax(A: MyArray): ArrayMinMax;
var
   I: Integer;
begin
   //finds the index of the min and max element
   Result.Min := 0;
   Result.Max := 0;
   for I := (Low(A)+1) to High(A) do
      case (CompareValue(A[I], A[Result.Min])) of 
         LessThanValue:  Result.Min := I;
         GreaterThanValue:  Result.Max := I;
      end;
end;
 
Ok, maybe i am using the wrong stuff. My values go from 0 to 4 with 0.1 increment. They are 0.00 format.
Should i use float or double?
I do store them as float in the database though.

Thanks for the advice.
P
 
No, that's not the point. You are ok with Double.

But comparing non-integer types is not reliable using > or < or = because of the way computers hold the fractional part of a floating point number.

That's why they have the CompareValue() function that returns back 3 possible answers...

from types unit
LessThenValue (or -1)
EqualsValue (or 0)
GreaterThanValue (or 1)
 
i have the math unit declared but i get a red line saying undeclared identifier under lesthanvalue and greaterthanvalue.

why?
p
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top