Comparing elements in an array - page 2

 
snjage:

Hi all,

Just to seek for a clarification on how arraybsearch works

In the event that a searched value is not found, Is it meant to return a nearest found value or does it return the nearest found value that is less in value than the searched value?

Did you read the documentation?
 
nicholishen:
Did you read the documentation?

Yes i read. It says '... If the wanted value isn't found, the function returns the index of an element nearest in value.'  This is what i'm trying to achieve in the code below

In the code, array arr[] stores fractal values. Assuming two of the fractal values in the array are 1.12345 and 1.11234, and the value i am searching for is 1.12344, the function returns the lesser value of 1.11234 which is not accurate, instead of the value that is closer, which is 1.12345

Why is it so?

   int a,b=2;
   double val,arr[];
   for(a=50;a>=b;a--)
     {
      if(iFractals(NULL,0,MODE_UPPER,a)>0)
        {
         val=iFractals(NULL,0,MODE_UPPER,a);
         ArrayResize(arr,ArraySize(arr)+1);
         arr[ArraySize(arr)-1]=val;
        }
     }
   ArraySort(arr,WHOLE_ARRAY,0,MODE_ASCEND);
  int d=ArrayBsearch(arr,1.12344,WHOLE_ARRAY,0,MODE_ASCEND); 
  Alert(1.12344,"  ",arr[d]);
 
snjage:

Yes i read. It says '... If the wanted value isn't found, the function returns the index of an element nearest in value.'  This is what i'm trying to achieve in the code below

In the code, array arr[] stores fractal values. Assuming two of the fractal values in the array are 1.12345 and 1.11234, and the value i am searching for is 1.12344, the function returns the lesser value of 1.11234 which is not accurate, instead of the value that is closer, which is 1.12345

Why is it so?


Ok, I see what you're saying now... it should say, "returns a value that's less than or equal to". If you want the closest value then you'll need a custom solution.  Here is an example script with two different options. Personally, I would use the class derived from CArrayDouble over using c-style arrays since it is much safer and requires less hassles. 

#include <Arrays\ArrayDouble.mqh>
class DoubleArray : public CArrayDouble
{
   public: int SearchClosest(const double element)
   {
      Sort();
      int less_equal  = SearchLessOrEqual(element);
      int great_equal = SearchGreatOrEqual(element);
      if(fabs(element-At(less_equal)) <= fabs(At(great_equal)-element))
         return less_equal;
      return great_equal;
   }
};

template<typename T>
int ArraySearchClosest(T &arr[],T element)
{
   ArraySort(arr);
   int index = ArrayBsearch(arr,element);
   if(index+1 >= ArraySize(arr))
      return index;
   if(fabs(element-arr[index]) <= fabs(arr[index+1]-element))
      return index;
   return index+1;
}

void OnStart()
{
   double _arr[]={1.0,1.5,2.5};
   DoubleArray arr;
   arr.AssignArray(_arr);
   Print("ArrayBSearch() index[",ArrayBsearch(_arr,1.26),"]");
   Print("ArraySearchClosest() index[",ArraySearchClosest(_arr,1.26),"]");
   Print("DoubleArray::SearchClosest() index[",arr.SearchClosest(1.26),"]"); 
}

This is how class DoubleArray would be implemented:

void OnStart()
{
   DoubleArray arr;
   for(int a=50;a>=2;a--)
   {
      double fractal = iFractals(NULL,0,MODE_UPPER,a);
      if(fractal>0)
         arr.Add(fractal);
   }
   Alert("1.12334 ",arr[arr.SearchClosest(1.12334)]);
}
 
nicholishen:

Ok, I see what you're saying now... it should say, "returns a value that's less than or equal to". If you want the closest value then you'll need a custom solution.  Here is an example script with two different options. Personally, I would use the class derived from CArrayDouble over using c-style arrays since it is much safer and requires less hassles. 

This is how class DoubleArray would be implemented:


Thank you nicholishen. With you i always learn a lot.

Reason: