Home > OS >  Compare if elements are almost equal in a list in C# .NET
Compare if elements are almost equal in a list in C# .NET

Time:10-14

I am still very beginner in C# and .NET and just need to do this simple test.

var odds = new System.Collections.Generic.List<double>();

// here is a code which adds the values in the list

foreach(var odd in odds)
{
   System.Console.WriteLine(odd);
}

and the output is something like that:

13.098252624859418
14.098252624859349
13.098252624859577
13.098252624853423
14.098252624859398

So I would like to compare all the values inside the list if they are almost equal. That means even if there is a little difference between the numbers (such as 13 and 14) inside the list still to be acceptable so I would like this difference to be maximum of 2.

CodePudding user response:

Check the difference between the maximum value and the minimum value in the list (2 in your case). Using a tolerance value. For example

double delta = 2;

// getting largest element
var maxNum = odds.Max();

// getting smallest element
var minNum = odds.Min();

var almostEqual = maxNum - minNum <= delta;

CodePudding user response:

You'll need to do it manually, as is recommended with every floating point number comparison (because floating point math is unintuitive), doing that is quite simple, something like this:

var a = 13.098252624859418;
var b = 14.098252624859398;
// define your acceptable range, i.e 1.0 means number 1.0 larger and smaller are equal to one another
var delta = 1.0;

var areNearlyEqual = Math.Abs(a - b) <= delta; // true

Now if you want to check if every element in a List is nearly equal to every other element, there is a naïve and more "complicated" solution, I'll start with the naïve one:

(Don't actually use this implementation, this is for illustration purposes of how to check equality of all items in a list which aren't just numbers)

var allAreNearlyEqual = true; // Let's start of assuming all are equal

foreach (var x in odds)
{
    if (!allAreNearlyEqual)
        break;

    foreach (var y in odds)
    {
        if (!Math.Abs(x - y) <= delta)
            allAreNearlyEqual = false;
    }
}

Console.WriteLine(allAreNearlyEqual);

As you can see we need to iterate over every element in the list (x) and compare it to every other element in the list (y), there is an easier to read (and also faster*) version of this:

var max = odds.Max();
var min = odds.Min();

if (Math.Abs(max - min) <= delta)
    Console.WriteLine("All items are nearly equal");
else
    Console.WriteLine("Not all items are nearly equal");

(This takes advantage of the fact that all other elements between the min and max are also close enough to be nearly equal, if the min and max are)

You can check out the implementation for Max here to see how they do it, but basically it's just a foreach loop which returns the highest value found.


*The second version is faster, because it's O(2N) where as the first version is O(N^2), I added the first version to illustrate how you could do the same thing on a list of objects which are not just numbers

  • Related