Find closest number in a list

1,Problem

There are two ordered list, the list a and the list b, such as:

a=>[1,14,20,36]
b=>[2,7,11,25,32,39]

the result that I want to get is:

result=>[(2,1),(7,null),(11,14),(25,null),(32,null),(39,36)]

Put it into word: find the closest number(which delta between counterpart is less than 5) in list a for each item in list b.

First of all, I decide to divide the problem to:

  1. find closest number for each item in a, since a is less elements than b.
  2. compose a result into a list. if no proper value be found, put it to null.

Because a&b are ordered list, so binary search is fast way to find out corresponding closest value. The complexity of binary search for a ordered list is O(log(N)).Each of item in list a have O(N), so the total complexity is O(N*log(N))。

2,Code

How to use the code:

static void Main(string[] args)
{
    int[] arrTime = { 1, 3, 5, 7, 8, 9, 10, 12, 15, 18, 25 };
    int[] arrAlign = { 3, 6, 11, 15, 22 };

    FindClosestNumber finder = new FindClosestNumber(3);

    var lst = finder.FindClosestAlignment(arrTime, arrAlign);

    foreach (var item in lst)
    {
        Console.WriteLine("{0}\t\t{1}", item.Time, item.Alignment);
    }

    Console.ReadKey();

}

There is the code:

public class Pair
{
    public Pair(int? time, int? alignment)
    {
        Time = time;
        Alignment = alignment;
    }
    public int? Time { set; get; }
    public int? Alignment { set; get; }
}

public class FindClosestNumber
{

    public int Threshold { get; set; }

    public FindClosestNumber()
    {
        this.Threshold = 50;

    }
    public FindClosestNumber(int threshold)
    {
        this.Threshold = threshold;
    }


    public  List<Pair> FindClosestAlignment(int[] arrTime, int[] arrAlignment)
    {
        List<Pair> list = FindClosestTime(arrTime, arrAlignment);

        List<Pair> reslut = new List<Pair>();
        for (int i = 0; i < arrTime.Length; i++)
        {
            Pair pair = new Pair(arrTime[i], null);
            foreach (var p in list)
            {
                if (pair.Time == p.Time)
                    pair.Alignment = p.Alignment;
            }
            reslut.Add(pair);
        }

        return reslut;
    }

    private  List<Pair> FindClosestTime(int[] arrTime, int[] arrAlignment)
    {
        List<Pair> list = new List<Pair>();

        for (int i = 0; i < arrAlignment.Length; i++)
        {
            int el = arrAlignment[i];
            int index = FindClosestIndexInOrderList(el, arrTime, this.Threshold);
            if (index == -1)
            {
                list.Add(new Pair(null, el));
            }
            else
            {
                list.Add(new Pair(arrTime[index], el));
            }
        }

        return list;

    }

    private  int FindClosestIndexInOrderList(int val, int[] arr, int threshold)
    {
        int index = Array.BinarySearch(arr, val);
        if (index >= 0)
        {//found
            return index;
        }
        else
        {
            //bitwise complement for index
            int compl = (~index);
            if (compl == arr.Length)
            {//val is biggest value in the arr

                if (Math.Abs(arr[arr.Length - 1] - val) > threshold)
                    return -1;
                else
                    return (arr.Length - 1);
            }
            else if (compl == 0)
            {//val is smallest value in the arr
                if (Math.Abs(arr[0] - val) > threshold)
                    return -1;
                else
                    return 0;
            }
            else
            {
                int preIndex = compl - 1;

                int deltaToPrevious = Math.Abs(arr[preIndex] - val);
                int deltaToCurrent = Math.Abs(arr[compl] - val);

                if (deltaToPrevious > threshold)
                    return -1;
                if (deltaToCurrent > threshold)
                    return -1;

                return deltaToPrevious <= deltaToCurrent ? preIndex : compl;
            }
        }
    }
}
@ 2012-03-13 08:00

Comments:

Sharing your thoughts: