using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using Newtonsoft.Json; using System.Collections; namespace Misc { /// <summary> /// int范围类, /// </summary> public class Range : INotifyPropertyChanged, Misc.ISaveToXml { #region property /// <summary> /// 开始 /// </summary> public int Begin { get; set; } /// <summary> /// 结束 /// </summary> public int End { get; set; } #endregion #region just get property /// <summary> /// 本范围 中心位置 /// </summary> [JsonIgnore] public int Mid { get { if (Misc.MyBase.ISVALIDATA(Begin)) return (End + Begin) / 2; else return Misc.MyBase.NULL_VALUE; } } /// <summary> /// 本范围宽度 /// </summary> [JsonIgnore] public int Width { get { if (IsValid) return End - Begin + 1; else return Misc.MyBase.NULL_VALUE; } } /// <summary> /// 是否有效 /// </summary> [JsonIgnore] public bool IsValid { get { if (Misc.MyBase.ISVALIDATA(Begin) && Misc.MyBase.ISVALIDATA(End)) return true; else return false; } } #endregion static Range() { Misc.SaveToXmlHepler.Regist(typeof(Range)); } /// <summary> /// 使用无效值初始化 /// </summary> public Range() { Reset(); } #region methods /// <summary> /// 范围 r 在 本范围内 /// </summary> /// <param name="r"></param> /// <returns></returns> public bool Contain(Range r) { if ((Begin <= r.Begin) && (r.End <= End)) return true; else return false; } /// <summary> /// 点 p 在 本范围内 /// </summary> /// <param name="p"></param> /// <returns></returns> public bool Contain(int p) { if ((Begin <= p) && (p <= End)) return true; else return false; } /// <summary> /// 平移 /// </summary> /// <param name="offset"></param> public void Move(int offset) { Begin += offset; End += offset; } /// <summary> /// 复位为无效 /// </summary> public void Reset() { Begin = Misc.MyBase.NULL_VALUE; End = Misc.MyBase.NULL_VALUE; } /// <summary> /// 转换为8个字节 /// </summary> /// <returns></returns> public byte[] ToBytes() { List<byte> buf = new List<byte>(); buf.AddRange(BitConverter.GetBytes(Begin)); buf.AddRange(BitConverter.GetBytes(End)); return buf.ToArray(); } /// <summary> /// 8个字节转换 /// </summary> /// <param name="value"></param> /// <param name="offset"></param> /// <returns></returns> public bool TryParse(byte[] value, int offset) { if (value.Length - offset < 8) return false; Begin = BitConverter.ToInt32(value, offset + 0); End = BitConverter.ToInt32(value, offset + 4); return true; } /// <summary> /// 范围并集 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Range operator |(Range a, Range b) { return new Range() { Begin = (a.Begin < b.Begin) ? a.Begin : b.Begin, End = (a.End > b.End) ? a.End : b.End }; } /// <summary> /// 范围交集 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Range operator &(Range a, Range b) { Range r = new Range() { Begin = (a.Begin > b.Begin) ? a.Begin : b.Begin, End = (a.End < b.End) ? a.End : b.End }; if (r.End < r.Begin) { return new Range(); } else { return r; } } /// <summary> /// 范围 a小于b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool operator <(Range a, Range b) { if (a.End < b.Begin)//[a.b,a.e] [b.b,b.e] { return true; } else { return false; } } /// <summary> /// 范围 a大于b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool operator >(Range a, Range b) { if (b.End < (a.Begin))// [b.b,b.e][a.b,a.e] { return true; } else { return false; } } public static bool operator <(int p, Range r) { if (p < r.Begin) { return true; } else { return false; } } public static bool operator >(int p, Range r) { if (p > r.End) { return true; } else { return false; } } public static bool operator <(Range r, int p) { if (r.End < p) { return true; } else { return false; } } public static bool operator >(Range r, int p) { if (r.Begin > p) { return true; } else { return false; } } /// <summary> /// 是否有交集 /// </summary> /// <param name="r"></param> /// <returns></returns> public bool HasIntersection(Range r) { if (Contain(r.Begin)) return true; if (Contain(r.End)) return true; if (r.Contain(Begin)) return true; if (r.Contain(End)) return true; return false; } /// <summary> /// 可以合并 /// </summary> /// <returns></returns> public bool CanUnion(Range r) { if (HasIntersection(r)) return true; if (End == (r.Begin - 1)) return true; if (Begin == (r.End + 1)) return true; return false; } /// <summary> /// 复制 r 的值到 本范围内 /// </summary> /// <param name="r"></param> public void Copy(Range r) { Begin = r.Begin; End = r.End; } /// <summary> /// 克隆 /// </summary> /// <returns></returns> public Range Clone() { Range r = new Range(); r.Copy(this); return r; } #endregion /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return "[" + Begin.ToString() + "," + End.ToString() + "]=" + Width.ToString(); } #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; #endregion #region ISaveToXml 成员 public string[] GetSavePropertyNames() { return new string[]{ "Begin","End" }; } #endregion } /// <summary> /// Range 比较器 /// </summary> public class RangeEqualityComparer : IEqualityComparer<Range> { /// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool Equals(Range x, Range y) { if ((x.Begin == y.Begin) && (x.End == y.End)) { return true; } else return false; } /// <summary> /// /// </summary> /// <param name="obj"></param> /// <returns></returns> public int GetHashCode(Range obj) { int hashCode = obj.Begin.GetHashCode(); int hashCode2 = obj.End.GetHashCode(); if (hashCode != hashCode2) { hashCode ^= hashCode2; } return hashCode; } } /// <summary> /// Range 辅助类 /// </summary> public static class EListRange { /// <summary> /// rlist 必须是由小到大排列 /// </summary> /// <param name="rlist"></param> /// <param name="r"></param> public static void Union(this List<Range> rlist, Range r) { for (int i = 0; i < rlist.Count(); i++) { Range r_dest = rlist[i]; if (r < r_dest)//在 r_dest 前面 { rlist.Insert(i, r); return;//完成 } else if (r.CanUnion(r_dest)) //r 与 r_dest 有交集 { //r 与 r_dest 合体 r = r | r_dest; rlist.RemoveAt(i); i--; //还需要继续判断 } } //r 在 rlist 的后面 rlist.Add(r); } /// <summary> /// 联合 /// </summary> /// <param name="rlist1"></param> /// <param name="rlist2"></param> public static void Union(this List<Range> rlist1, List<Range> rlist2) { for (int i = 0; i < rlist2.Count(); i++) { rlist1.Union(rlist2[i]); } } } }