Interval data type for C# .NET?

前端 未结 8 1872
一个人的身影
一个人的身影 2021-01-30 23:07

I\'m looking an interval data type for .NET 4.0. For example the interval (a,b], all point x such that a

What i would like to be able to do are create interv

8条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-30 23:44

    The following allows open ended ranges of any type that implements IComparable. An obvious extension would be to allow you to pass your own comparer (in much the same way that Hashset does.

    The range in this case is a<=x

    It includes overlap and merge. Other functions should be reasonably easy to add.

    public class Interval where T : IComparable
    {
        public T Start { get; private set; }
        public T End { get; private set; }
    
        public bool HasStart { get; private set; }
        public bool HasEnd { get; private set; }
    
        private Interval()
        {
        }
    
        public bool Overlaps(Interval other)
        {
            if (this.HasStart && other.IsInRange(this.Start))
                return true;
            if (this.HasEnd && other.IsInRange(this.End))
                return true;
            return false;
        }
    
        public static Interval Merge(Interval int1, Interval int2)
        {
            if (!int1.Overlaps(int2))
            {
                throw new ArgumentException("Interval ranges do not overlap.");
            }
            bool hasStart = false;
            bool hasEnd = false;
            T start = default(T);
            T end = default(T);
    
            if (int1.HasStart && int2.HasStart)
            {
                hasStart = true;
                start = (int1.Start.CompareTo(int2.Start) < 0) ? int1.Start : int2.Start;
            }
            if (int1.HasEnd && int2.HasEnd)
            {
                hasEnd = true;
                end = (int1.End.CompareTo(int2.End) > 0) ? int1.Start : int2.Start;
            }
            return CreateInternal(start, hasStart, end, hasEnd);
        }
    
        private static Interval CreateInternal(T start, bool hasStart, T end, bool hasEnd)
        {
            var i = new Interval();
            i.Start = start;
            i.End = end;
            i.HasEnd = hasEnd;
            i.HasStart = hasStart;
            return i;
        }
    
        public static Interval Create(T start, T end)
        {
            return CreateInternal(start, true, end, true);
        }
    
        public static Interval CreateLowerBound(T start)
        {
            return CreateInternal(start, true, default(T), false);
        }
    
        public static Interval CreateUpperBound(T end)
        {
            return CreateInternal(default(T), false, end, true);
        }
    
        public bool IsInRange(T item)
        {
            if (HasStart && item.CompareTo(Start) < 0)
            {
                return false;
            }
            if (HasEnd && item.CompareTo(End) >= 0)
            {
                return false;
            }
            return true;
        }
    }
    

提交回复
热议问题