What .NET dictionary supports a “find nearest key” operation?

后端 未结 8 693
[愿得一人]
[愿得一人] 2020-12-18 23:08

I\'m converting some C++ code to C# and it calls std::map::lower_bound(k) to find an entry in the map whose key is equal to or greater than k. However, I don\'t see any way

8条回答
  •  自闭症患者
    2020-12-18 23:56

    You can try the code i wrote below. it using binary search, therefore assuming the list/array is pre-sorted.

    public static class ListExtensions
    {
        public static int GetAtMostIndex(/*this*/ IList list, TValue value, Func comparer)
        {
            return GetAtMostIndex(list, value, comparer, 0, list.Count);
        }
    
        public static int GetAtLeastIndex(/*this*/ IList list, TValue value, Func comparer)
        {
            return GetAtLeastIndex(list, value, comparer, 0, list.Count);
        }
    
        public static int GetAtMostIndex(/*this*/ IList list, TValue value, Func comparer, int index, int count)
        {
            if (count == 0)
            {
                return -1;
            }
    
            int startIndex = index;
            int endIndex = index + count - 1;
            int middleIndex = 0;
            int compareResult = -1;
    
            while (startIndex < endIndex)
            {
                middleIndex = (startIndex + endIndex) >> 1; //  / 2
                compareResult = comparer.Invoke(list[middleIndex], value);
    
                if (compareResult > 0)
                {
                    endIndex = middleIndex - 1;
                }
                else if (compareResult < 0)
                {
                    startIndex = middleIndex + 1;
                }
                else
                {
                    return middleIndex;
                }
            }
    
            if (startIndex == endIndex)
            {
                compareResult = comparer.Invoke(list[startIndex], value);
    
                if (compareResult <= 0)
                {
                    return startIndex;
                }
                else
                {
                    int returnIndex = startIndex - 1;
    
                    if (returnIndex < index)
                    {
                        return -1;
                    }
                    else
                    {
                        return returnIndex;
                    }
                }
            }
            else
            {
                //todo: test
                return startIndex - 1;
            }
        }
    
        public static int GetAtLeastIndex(/*this*/ IList list, TValue value, Func comparer, int index, int count)
        {
            if (count == 0)
            {
                return -1;
            }
    
            int startIndex = index;
            int endIndex = index + count - 1;
            int middleIndex = 0;
            int compareResult = -1;
    
            while (startIndex < endIndex)
            {
                middleIndex = (startIndex + endIndex) >> 1; //  / 2
                compareResult = comparer.Invoke(list[middleIndex], value);
    
                if (compareResult > 0)
                {
                    endIndex = middleIndex - 1;
                }
                else if (compareResult < 0)
                {
                    startIndex = middleIndex + 1;
                }
                else
                {
                    return middleIndex;
                }
            }
    
            if (startIndex == endIndex)
            {
                compareResult = comparer.Invoke(list[startIndex], value);
    
                if (compareResult >= 0)
                {
                    return startIndex;
                }
                else
                {
                    int returnIndex = startIndex + 1;
    
                    if (returnIndex >= index + count)
                    {
                        return -1;
                    }
                    else
                    {
                        return returnIndex;
                    }
                }
            }
            else
            {
                return endIndex + 1;
            }
        }
    }
    

提交回复
热议问题