Range.cs 10.8 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
潘栩锋's avatar
潘栩锋 committed
6
using Newtonsoft.Json;
7
using System.Collections;
潘栩锋's avatar
潘栩锋 committed
8 9 10

namespace Misc
{
潘栩锋's avatar
潘栩锋 committed
11 12 13
    /// <summary>
    /// int范围类, 
    /// </summary>
潘栩锋's avatar
潘栩锋 committed
14 15
    public class Range : INotifyPropertyChanged, Misc.ISaveToXml
    {
潘栩锋's avatar
潘栩锋 committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
        #region property
        /// <summary>
        /// 开始
        /// </summary>
        public int Begin { get; set; }

        /// <summary>
        /// 结束
        /// </summary>
        public int End { get; set; }
        #endregion

        #region just get property
        /// <summary>
        /// 本范围 中心位置
        /// </summary>
        [JsonIgnore]
潘栩锋's avatar
潘栩锋 committed
33 34 35 36 37 38 39 40 41 42
        public int Mid
        {
            get
            {
                if (Misc.MyBase.ISVALIDATA(Begin))
                    return (End + Begin) / 2;
                else
                    return Misc.MyBase.NULL_VALUE;
            }
        }
潘栩锋's avatar
潘栩锋 committed
43 44 45 46 47

        /// <summary>
        /// 本范围宽度
        /// </summary>
        [JsonIgnore]
潘栩锋's avatar
潘栩锋 committed
48 49 50 51 52 53 54 55 56 57
        public int Width
        {
            get
            {
                if (IsValid)
                    return End - Begin + 1;
                else
                    return Misc.MyBase.NULL_VALUE;
            }
        }
潘栩锋's avatar
潘栩锋 committed
58 59 60 61 62 63 64


        /// <summary>
        /// 是否有效
        /// </summary>
        [JsonIgnore]
        public bool IsValid
潘栩锋's avatar
潘栩锋 committed
65 66 67
        {
            get
            {
潘栩锋's avatar
1  
潘栩锋 committed
68
                if (Misc.MyBase.ISVALIDATA(Begin) && Misc.MyBase.ISVALIDATA(End))
潘栩锋's avatar
潘栩锋 committed
69 70 71
                    return true;
                else
                    return false;
潘栩锋's avatar
潘栩锋 committed
72 73
            }
        }
潘栩锋's avatar
潘栩锋 committed
74 75
        #endregion
        static Range()
潘栩锋's avatar
潘栩锋 committed
76
        {
潘栩锋's avatar
潘栩锋 committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
            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;
潘栩锋's avatar
潘栩锋 committed
130
        }
潘栩锋's avatar
潘栩锋 committed
131 132 133 134 135


        /// <summary>
        /// 复位为无效
        /// </summary>
潘栩锋's avatar
潘栩锋 committed
136 137 138 139 140
        public void Reset()
        {
            Begin = Misc.MyBase.NULL_VALUE;
            End = Misc.MyBase.NULL_VALUE;
        }
潘栩锋's avatar
潘栩锋 committed
141 142


潘栩锋's avatar
潘栩锋 committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
        /// <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;
        }

潘栩锋's avatar
潘栩锋 committed
170 171 172 173 174 175
        /// <summary>
        /// 范围并集
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
176 177 178 179 180 181 182 183 184
        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
            };
        }

潘栩锋's avatar
潘栩锋 committed
185 186 187 188 189 190
        /// <summary>
        /// 范围交集
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
        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;
            }
        }
潘栩锋's avatar
潘栩锋 committed
207 208 209 210 211 212 213

        /// <summary>
        /// 范围 a小于b
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
214 215 216 217 218 219 220 221 222 223 224
        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;
            }
        }
潘栩锋's avatar
潘栩锋 committed
225 226 227 228 229 230 231

        /// <summary>
        /// 范围 a大于b
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
232 233 234 235 236 237 238 239 240 241 242
        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;
            }
        }
潘栩锋's avatar
潘栩锋 committed
243 244


潘栩锋's avatar
潘栩锋 committed
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
        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;
            }
        }
潘栩锋's avatar
潘栩锋 committed
289
        
潘栩锋's avatar
潘栩锋 committed
290 291 292
        /// <summary>
        /// 是否有交集
        /// </summary>
潘栩锋's avatar
潘栩锋 committed
293
        /// <param name="r"></param>
潘栩锋's avatar
潘栩锋 committed
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
        /// <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;
        }
潘栩锋's avatar
潘栩锋 committed
327 328 329 330 331

        /// <summary>
        /// 复制 r 的值到 本范围内
        /// </summary>
        /// <param name="r"></param>
潘栩锋's avatar
潘栩锋 committed
332 333 334 335 336
        public void Copy(Range r)
        {
            Begin = r.Begin;
            End = r.End;
        }
潘栩锋's avatar
潘栩锋 committed
337 338 339 340
        /// <summary>
        /// 克隆
        /// </summary>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
341 342 343 344 345 346
        public Range Clone()
        {
            Range r = new Range();
            r.Copy(this);
            return r;
        }
潘栩锋's avatar
潘栩锋 committed
347 348 349 350 351
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
潘栩锋's avatar
潘栩锋 committed
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
        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


    }
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414

    /// <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;
        }
    }
415 416 417 418

    /// <summary>
    /// Range 辅助类
    /// </summary>
潘栩锋's avatar
潘栩锋 committed
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
    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);
        }

潘栩锋's avatar
潘栩锋 committed
450

潘栩锋's avatar
潘栩锋 committed
451
        /// <summary>
潘栩锋's avatar
潘栩锋 committed
452
        /// 联合
潘栩锋's avatar
潘栩锋 committed
453
        /// </summary>
潘栩锋's avatar
潘栩锋 committed
454 455
        /// <param name="rlist1"></param>
        /// <param name="rlist2"></param>
潘栩锋's avatar
潘栩锋 committed
456 457 458 459 460 461 462 463
        public static void Union(this List<Range> rlist1, List<Range> rlist2)
        {
            for (int i = 0; i < rlist2.Count(); i++)
            {
                rlist1.Union(rlist2[i]);
            }
        }
    }
潘栩锋's avatar
潘栩锋 committed
464 465


潘栩锋's avatar
潘栩锋 committed
466
}