コード例 #1
0
ファイル: DeepFTree.cs プロジェクト: yonglehou/Stact
        public override FTree <T> App2(List <T> ts, FTree <T> rightFT)
        {
            if (!(rightFT is DeepFTree <T>))
            {
                FTree <T> resultFT = this;

                foreach (T t in ts)
                {
                    resultFT = resultFT.PushBack(t);
                }

                return((rightFT is EmptyFTree <T>)
                                        ? resultFT
                                        : resultFT.PushBack(rightFT.LeftView().head));
            }
            else             // the right tree is also a deep tree
            {
                var deepRight = rightFT as DeepFTree <T>;

                var cmbList = new List <T>(backDig.digNodes);

                cmbList.AddRange(ts);

                cmbList.AddRange(deepRight.frontDig.digNodes);

                FTree <T> resultFT =
                    new DeepFTree <T>
                        (frontDig,
                        innerFT.App2(ListOfNodes(cmbList), deepRight.innerFT),
                        deepRight.backDig
                        );

                return(resultFT);
            }
        }
コード例 #2
0
        /// <summary> Get or set the object at a specific point. </summary>
        public object this[Point APoint]
        {
            get
            {
                KDTree.Node LNode = FTree.Query(APoint);
                if (LNode != null)
                {
                    return(LNode.Object);
                }
                else
                {
                    return(null);
                }
            }
            set
            {
                // Remove any item at this spot
                KDTree.Node LNode = FTree.Query(APoint);
                if (LNode != null)
                {
                    FTree.Remove(LNode);
                    FNodes.Remove(LNode.Object);
                }

                // Add the new item at the spot
                if (value != null)
                {
                    LNode = new KDTree.Node(APoint, value);
                    FTree.Add(LNode);
                    FNodes.Add(value, LNode);
                }
            }
        }
コード例 #3
0
                public override void Split(int index, out FTree <TChild> left, out TChild center, out FTree <TChild> right, Lineage lineage)
                {
                    Digit leftDigit, rightDigit;

                    CenterDigit.Split(index, out leftDigit, out center, out rightDigit, lineage);
                    left  = leftDigit == null ? Empty : new Single(leftDigit, lineage);
                    right = rightDigit == null ? Empty : new Single(rightDigit, lineage);
                }
コード例 #4
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
 /// <summary>
 ///     This method will re-initialize this instance using the specified parameters.
 /// </summary>
 private FTree <TChild> _mutate(Digit left, FTree <Digit> deep, Digit right)
 {
     LeftDigit  = left;
     DeepTree   = deep;
     RightDigit = right;
     Measure    = left.Measure + deep.Measure + right.Measure;
     return(this);
 }
コード例 #5
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
 public Compound(Digit leftDigit, FTree <Digit> deepTree, Digit rightDigit, Lineage lineage)
     : base(leftDigit.Measure + deepTree.Measure + rightDigit.Measure, TreeType.Compound, lineage, 3)
 {
     leftDigit.AssertNotNull();
     deepTree.AssertNotNull();
     rightDigit.AssertNotNull();
     _mutate(leftDigit, deepTree, rightDigit);
 }
コード例 #6
0
        public override FTree <T> App2(List <T> ts, FTree <T> rightFT)
        {
            FTree <T> resultFT = rightFT;

            for (int i = ts.Count - 1; i >= 0; i--)
            {
                resultFT = resultFT.PushFront(ts[i]);
            }

            return(resultFT.PushFront(theSingle));
        }
コード例 #7
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
 /// <summary>
 ///     <para>
 ///         This method can mutate the current instance and return it, or return a new instance, based on the supplied
 ///         Lineage.
 ///     </para>
 ///     <para>If the current Lineage allows mutation from the specified Lineage, the instance will be MUTATED and returned.</para>
 ///     <para>Otherwise, the method will return a NEW instance that is a member of the supplied Lineage. </para>
 /// </summary>
 private FTree <TChild> MutateOrCreate(Digit left, FTree <Digit> deep, Digit right, Lineage lineage)
 {
     if (_lineage.AllowMutation(lineage))
     {
         return(_mutate(left, deep, right));
     }
     else
     {
         return(new Compound(left, deep, right, lineage));
     }
 }
コード例 #8
0
        /// <summary> Get all objects within a given range of the plane. </summary>
        public object[] QueryRect(Rectangle ARect)
        {
            ArrayList LNodes = FTree.Query(ARect);

            object[] LResult = new object[LNodes.Count];
            for (int i = 0; i < LResult.Length; i++)
            {
                LResult[i] = ((KDTree.Node)LNodes[i]).Object;
            }
            return(LResult);
        }
コード例 #9
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
                public override void Split(int index, out FTree <TChild> left, out TChild child, out FTree <TChild> right, Lineage lineage)
                {
#if ASSERTS
                    var oldMeasure = Measure;
                    var oldValue   = this[index];
#endif
                    switch (WhereIsThisIndex(index))
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        Digit lLeft, lRight;
                        LeftDigit.Split(index, out lLeft, out child, out lRight, lineage);
                        index -= lLeft == null ? 0 : lLeft.Measure;
                        left   = CreateCheckNull(Lineage.Immutable, lLeft);
                        right  = CreateCheckNull(lineage, lRight, DeepTree, RightDigit);
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        index -= LeftDigit.Measure;
                        FTree <Digit> mLeft, mRight;
                        Digit         mCenter;
                        DeepTree.Split(index, out mLeft, out mCenter, out mRight, lineage);
                        Digit mcLeft, mcRight;
                        index -= mLeft.Measure;
                        mCenter.Split(index, out mcLeft, out child, out mcRight, lineage);
                        index -= mcLeft == null ? 0 : mcLeft.Measure;
                        left   = CreateCheckNull(Lineage.Immutable, LeftDigit, mLeft, mcLeft);
                        right  = CreateCheckNull(lineage, mcRight, mRight, RightDigit);
                        break;

                    case IN_MIDDLE_OF_RIGHT:
                    case IN_START_OF_RIGHT:
                        Digit rLeft, rRight;
                        index -= LeftDigit.Measure + DeepTree.Measure;
                        RightDigit.Split(index, out rLeft, out child, out rRight, lineage);
                        index -= rLeft == null ? 0 : rLeft.Measure;
                        right  = CreateCheckNull(Lineage.Immutable, rRight);
                        left   = CreateCheckNull(lineage, LeftDigit, DeepTree, rLeft);
                        break;

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Index didn't match any of the cases.");
                    }
#if ASSERTS
                    oldMeasure.AssertEqual(left.Measure + child.Measure + right.Measure);
                    oldValue.AssertEqual(child[index]);
#endif
                }
コード例 #10
0
ファイル: DeepFTree.cs プロジェクト: yonglehou/Stact
 public DeepFTree(Digit <T> frontDig, FTree <Node <T> > innerFT, Digit <T> backDig)
 {
     if (frontDig.digNodes.Count > 0)
     {
         this.frontDig = frontDig;
         this.innerFT  = innerFT;
         this.backDig  = backDig;
     }
     else
     {
         throw new Exception("The DeepFTree() constructor is passed an empty frontDig !");
     }
 }
コード例 #11
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
                public override FTree <TChild> Insert(int index, Leaf <TValue> leaf, Lineage lineage)
                {
                    var whereIsThisIndex = WhereIsThisIndex(index);

#if ASSERTS
                    var newMeasure = Measure + 1;
                    var oldValue   = this[index].Value;
#endif
                    FTree <Digit>  newDeep;
                    FTree <TChild> res = null;
                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        Digit leftL, leftR;
                        LeftDigit.Insert(index, leaf, out leftL, out leftR, lineage);
                        newDeep = leftR != null?DeepTree.AddFirst(leftR, lineage) : DeepTree;

                        res = MutateOrCreate(leftL, newDeep, RightDigit, lineage);
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        if (DeepTree.Measure == 0)
                        {
                            goto case IN_START_OF_RIGHT;
                        }
                        newDeep = DeepTree.Insert(index - LeftDigit.Measure, leaf, lineage);
                        res     = MutateOrCreate(LeftDigit, newDeep, RightDigit, lineage);
                        break;

                    case IN_START_OF_RIGHT:
                    case IN_MIDDLE_OF_RIGHT:
                        Digit rightR;
                        Digit rightL;
                        RightDigit.Insert(index - LeftDigit.Measure - DeepTree.Measure, leaf, out rightL, out rightR, lineage);
                        newDeep = rightR != null?DeepTree.AddLast(rightL, lineage) : DeepTree;

                        rightR = rightR ?? rightL;
                        res    = MutateOrCreate(LeftDigit, newDeep, rightR, lineage);
                        break;
                    }
#if ASSERTS
                    res.Measure.AssertEqual(newMeasure);
                    res[index].Value.AssertEqual(leaf.Value);
                    res[index + 1].Value.AssertEqual(oldValue);
#endif
                    return(res);
                }
コード例 #12
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
                FTree <TChild> CreateCheckNull(Lineage lineage, Digit left = null, FTree <Digit> deep = null, Digit right = null)
                {
                    var memberPermutation = left != null ? 1 << 0 : 0;

                    memberPermutation |= (deep != null && deep.Measure != 0) ? 1 << 1 : 0;
                    memberPermutation |= right != null ? 1 << 2 : 0;

                    switch (memberPermutation)
                    {
                    case 0 << 0 | 0 << 1 | 0 << 2:
                            return(Empty);

                    case 1 << 0 | 0 << 1 | 0 << 2:
                            return(new Single(left, lineage));

                    case 1 << 0 | 1 << 1 | 0 << 2:
                            var r2    = deep.Right;
                        var     deep1 = deep.RemoveLast(lineage);

                        return(MutateOrCreate(left, deep1, r2, lineage));

                    case 1 << 0 | 1 << 1 | 1 << 2:
                            return(MutateOrCreate(left, deep, right, lineage));

                    case 0 << 0 | 1 << 1 | 1 << 2:
                            return(MutateOrCreate(deep.Left, deep.RemoveFirst(lineage), right, lineage));

                    case 1 << 0 | 0 << 1 | 1 << 2:
                            return(MutateOrCreate(left, deep, right, lineage));

                    case 0 << 0 | 1 << 1 | 0 << 2:
                            left = deep.Left;
                        deep     = deep.RemoveFirst(lineage);
                        if (deep.Measure != 0)
                        {
                            right = deep.Right;
                            deep  = deep.RemoveLast(lineage);
                            return(MutateOrCreate(left, deep, right, lineage));
                        }
                        return(new Single(left, lineage));

                    case 0 << 0 | 0 << 1 | 1 << 2:
                            return(new Single(right, lineage));

                    default:
                        throw ImplErrors.Invalid_execution_path("Explicitly checked all possible tree permutations.");
                    }
                }
コード例 #13
0
    public void LoadBanWords()
    {
        if (banWordLoaded)
        {
            return;
        }

        banWordLoaded = true;
        byte[] bytes = BinaryLoader(ConfigPath + "/ban_words.txt");
        string text  = Encoding.UTF8.GetString(bytes);

        string[] words = text.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

        FTree tree = null;

        foreach (string word in words)
        {
            string str = word.Trim();
            if (string.IsNullOrEmpty(str))
            {
                continue;
            }

            if (str[0] == '[')
            {
                if (str == "[名字]")
                {
                    tree = nameFTree;
                }
                else
                {
                    tree = commonFtree;
                }
            }

            if (tree != null)
            {
                tree.InsertWord(str);
            }
        }
    }
コード例 #14
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			/// <summary>
			/// Splits the finger tree right before the specified index.
			/// </summary>
			/// <param name="index">The index.</param>
			/// <param name="left">The left.</param>
			/// <param name="right">The right.</param>
			/// <param name="lineage">The lineage.</param>
			public void Split(int index, out FTree<TChild> left, out FTree<TChild> right, Lineage lineage) {
				if (index == Measure) {
					left = this;
					right = Empty;
					return;
				}
#if ASSERTS
				var oldValue = this[index];
				var oldFirst = Left;
				var oldLast = Right;
#endif
				TChild center;
				Split(index, out left, out center, out right, lineage);
				right = right.AddFirst(center, lineage);
#if ASSERTS
				center[0].AssertEqual(oldValue);
				if (left.Measure != 0) {
					left.Left.AssertEqual(oldFirst);
				}
				if (right.Measure != 0) {
					right.Right.AssertEqual(oldLast);
				}
#endif
			}
コード例 #15
0
ファイル: Compound.cs プロジェクト: stjordanis/Imms
                public override FTree <TChild> RemoveAt(int index, Lineage lineage)
                {
                    var            whereIsThisIndex = WhereIsThisIndex(index);
                    Digit          newLeft;
                    FTree <TChild> ret = this;

#if ASSERTS
                    var newMeasure          = Measure - 1;
                    var expectedAtIndex     = index != Measure - 1 ? this[index + 1] : null;
                    var expectedBeforeIndex = index != 0 ? this[index - 1] : null;
#endif
                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        if (LeftDigit.IsFragment)
                        {
                            var fixedTree = FixLeftDigit(lineage);
                            ret = fixedTree.RemoveAt(index, lineage);
                        }
                        else
                        {
                            newLeft = LeftDigit.Remove(index, lineage);
                            ret     = CreateCheckNull(lineage, newLeft, DeepTree, RightDigit);
                        }
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        if (DeepTree.Measure == 0)
                        {
                            goto case IN_START_OF_RIGHT;
                        }
                        var           deep = DeepTree;
                        FTree <Digit> newDeep;
                        if (deep.IsFragment)
                        {
                            newDeep = deep.AddFirst(LeftDigit, lineage);
                            newDeep = newDeep.RemoveAt(index, lineage);
                            newLeft = newDeep.Left;
                            newDeep = newDeep.RemoveFirst(lineage);
                            ret     = MutateOrCreate(newLeft, newDeep, RightDigit, lineage);
                        }
                        else
                        {
                            newDeep = DeepTree.RemoveAt(index - LeftDigit.Measure, lineage);
                            ret     = CreateCheckNull(lineage, LeftDigit, newDeep, RightDigit);
                        }
                        break;

                    case IN_START_OF_RIGHT:
                    case IN_MIDDLE_OF_RIGHT:
                        if (RightDigit.IsFragment)
                        {
                            var fixedTree = FixRightDigit(lineage);
                            ret = fixedTree.RemoveAt(index, lineage);
                        }
                        else
                        {
                            var newRight = RightDigit.Remove(index - LeftDigit.Measure - DeepTree.Measure, lineage);
                            ret = CreateCheckNull(lineage, LeftDigit, DeepTree, newRight);
                        }
                        break;

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all possible index locations already.");
                    }
#if ASSERTS
                    ret.Measure.AssertEqual(newMeasure);
                    if (expectedAtIndex != null)
                    {
                        ret[index].Value.AssertEqual(expectedAtIndex.Value);
                    }
                    if (expectedBeforeIndex != null)
                    {
                        ret[index - 1].Value.AssertEqual(expectedBeforeIndex.Value);
                    }
#endif
                    return(ret);
                }
コード例 #16
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			/// <summary>
			/// concatenates the two trees together. the supplied lineage cannot be shared by any of the trees, or the result will be corrupt!! <br/>
			/// However, you can reuse the lineage after calling this method.
			/// </summary>
			/// <param name="first">The first.</param>
			/// <param name="last">The last.</param>
			/// <param name="lineage">The lineage.</param>
			/// <returns></returns>
			public static FTree<TChild> Concat(FTree<TChild> first, FTree<TChild> last, Lineage lineage) {
				var status = first._kind << 3 | last._kind;
				FTree<Digit> newDeep;
				switch (status) {
					//+ Implementation
					//This should be farily legible. It is a solution I like to call a 'case table'
					//Note that TreeType is *not* an enum but a static class with constants.
					//This is because enums do not support the bitwise << operator.

					/* If either of the trees is empty*/
					case TreeType.Empty << 3 | TreeType.Single:
					case TreeType.Empty << 3 | TreeType.Compound:
						return last;
					case TreeType.Single << 3 | TreeType.Empty:
					case TreeType.Compound << 3 | TreeType.Empty:
						return first;
					case TreeType.Empty << 3 | TreeType.Empty:
						return first;
					/* If both are single... we just create a new Compound with their digits.*/
					case TreeType.Single << 3 | TreeType.Single:
						var single1 = (Single) first;
						var single2 = (Single) last;
						return new Compound(single1.CenterDigit, FTree<Digit>.Empty,
							single2.CenterDigit, lineage);
					case TreeType.Single << 3 | TreeType.Compound:
						var asSingle = (Single) first;
						var asCompound = (Compound) last;
						Digit left, mid, right;
						asSingle.CenterDigit.Fuse(asCompound.LeftDigit, out left, out mid, out right, lineage);
						newDeep = asCompound.DeepTree;
						if (right != null) {
							newDeep = newDeep.AddFirst(right, lineage);
						}
						if (mid != null) {
							newDeep = newDeep.AddFirst(mid, lineage);
						}
						return new Compound(left, newDeep, asCompound.RightDigit, lineage);
					/* If one is single, we push the digit of the Compound into its Deep.*/
					case TreeType.Compound << 3 | TreeType.Single:
						var rightSingle = (Single) last;
						var leftCompound = (Compound) first;
						Digit rLeft, rMid, rRight;
						leftCompound.RightDigit.Fuse(rightSingle.CenterDigit, out rLeft, out rMid, out rRight, lineage);
						Digit rDigit;
						newDeep = leftCompound.DeepTree;
						if (rMid != null) {
							newDeep = newDeep.AddLast(rLeft, lineage);
							if (rRight != null) {
								newDeep = newDeep.AddLast(rMid, lineage);
								rDigit = rRight;
							} else {
								rDigit = rMid;
							}
						} else {
							rDigit = rLeft;
						}
						return new Compound(leftCompound.LeftDigit, newDeep, rDigit, lineage);

					/* This is the most complex case.
				 * First note that when we have two Compounds, we essentially have two inner digits and two outer digits:
				 *		A..B ++ C..D => A..D
				 *	The digits B C must somehow be pushed into the FTree, but the digits A D are going to be its left and right digits.
				 *	What we do with the digits B C is call the function ReformDigitsForConcat on the inner digits
				 *	Because the law is that only digits with 2 or 3 elements can be pushed to become items in the deeper trees
				 *	We need to reform the digits, whatever their current shape, into 2-3 digits.
				 *	Look up the function to see how it's done.
				 */
					case TreeType.Compound << 3 | TreeType.Compound:
						Digit leftmost;
						Digit middle;
						Digit rightmost;
						var compound1 = (Compound) first;
						var compound2 = (Compound) last;
						var innerLeft = compound1.RightDigit;
						var innerRight = compound2.LeftDigit;
						innerLeft.Fuse(innerRight, out leftmost, out middle, out rightmost, lineage);
						FTree<Digit> deep;
						if (compound1.Measure > compound2.Measure)
							//We want to push the small tree into the large one. 
						{
							deep = compound1.DeepTree;
							if (leftmost != null) deep = deep.AddLast(leftmost, lineage);
							if (middle != null) deep = deep.AddLast(middle, lineage);
							if (rightmost != null) deep = deep.AddLast(rightmost, lineage);
							deep = FTree<Digit>.Concat(deep, compound2.DeepTree, lineage);
						} else {
							deep = compound2.DeepTree;
							if (rightmost != null) deep = deep.AddFirst(rightmost, lineage);
							if (middle != null) deep = deep.AddFirst(middle, lineage);
							if (leftmost != null) deep = deep.AddFirst(leftmost, lineage);
							deep = FTree<Digit>.Concat(compound1.DeepTree, deep, lineage);
						}
						return new Compound(compound1.LeftDigit, deep, compound2.RightDigit, lineage);
				}
				throw ImplErrors.Invalid_execution_path("Checked all permutations of finger tree concatenation.");
			}
コード例 #17
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			public FTree<TChild> AddFirstList(FTree<TChild> list, Lineage lineage) {
				return Concat(list, this, lineage);
			}
コード例 #18
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			/// <summary>
			///     Concats the specified ftree to the end of this one. If the lineage is shared by either of the trees, the result is corrupt!
			/// </summary>
			/// <param name="list">The list.</param>
			/// <param name="lineage">The lineage.</param>
			/// <returns></returns>
			public FTree<TChild> AddLastList(FTree<TChild> list, Lineage lineage) {
				return Concat(this, list, lineage);
			}
コード例 #19
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			public abstract void Split(int index, out FTree<TChild> left, out TChild child, out FTree<TChild> right, Lineage lineage);
コード例 #20
0
ファイル: DeepFTree.cs プロジェクト: yonglehou/Stact
        public override FTree <T> Merge(FTree <T> rightFT)
        {
            var emptyList = new List <T>();

            return(App2(emptyList, rightFT));
        }
コード例 #21
0
ファイル: FTree.cs プロジェクト: stjordanis/Imms
			/// <summary>
			///     Constructs a finger tree from the specified array, consisting of the elements at [index..index+count)
			///     A lot faster than adding iteratively without lineages, and quite a bit faster than adding iteratively with
			///     lineages.
			/// </summary>
			/// <param name="arr">The arr.</param>
			/// <param name="index">The index.</param>
			/// <param name="count">The count.</param>
			/// <param name="lin">The lineage.</param>
			/// <remarks>
			///	Related:  
			/// http://cs.stackexchange.com/questions/41081/guessing-the-structure-of-a-finger-tree-from-the-number-of-elements
			/// <br/>
			/// Algorithm: https://hackage.haskell.org/package/containers-0.4.0.0/docs/src/Data-Sequence.html#applicativeTree
			/// </remarks>
			/// <returns></returns>
			public static FTree<TChild> Construct(TValue[] arr, ref int index, int count, Lineage lin) {
				var myChildSize = FastMath.PowN(3, Nesting - 1);
				var divRem = count % myChildSize;
				FTree<TChild> ret;
				var digit = ExampleDigit;
				int number;
				if (divRem == 0 && (number = count / myChildSize) <= 8) {
					switch (number) {
						case 0:
							return Empty;
						case 1:
						case 2:
						case 3:
						case 4:
							var center = digit.ConstructMult(arr, ref index, number, lin);
							ret = new Single(center, lin);
							break;
						case 5:
							var left1 = digit.Construct3(arr, ref index, lin);
							var right1 = digit.ConstructMult(arr, ref index, 2, lin);
							ret = new Compound(left1, FTree<Digit>.Empty, right1, lin);
							break;
						case 6:
							var left2 = digit.Construct3(arr, ref index, lin);
							var right2 = digit.Construct3(arr, ref index, lin);
							ret = new Compound(left2, FTree<Digit>.Empty, right2, lin);
							break;
						case 7:
							var left3 = digit.ConstructMult(arr, ref index, 4, lin);
							var right3 = digit.Construct3(arr, ref index, lin);
							ret = new Compound(left3, FTree<Digit>.Empty, right3, lin);
							break;
						case 8:
							var left4 = digit.ConstructMult(arr, ref index, 4, lin);
							var right4 = digit.ConstructMult(arr, ref index, 4, lin);
							ret = new Compound(left4, FTree<Digit>.Empty, right4, lin);
							break;
						default:
							throw ImplErrors.Invalid_execution_path("An if statement just checked if number <= 8.");
					}

				} else {
					var nextChildSize = myChildSize * 3;
					var nextDivRem = count % nextChildSize;
#if ASSERTS
					//this is guaranteed by previous recursive calls to Construct. count must be divisible by myChildSize
					//and since nextChildSize = myChildSize * 3, then nextDivRem % myChildSize must be within [0,2].
					//we maintain this invariant by the next if-else block, which makes sure that the 'count' for the next invocation
					//really is divisible by nextChildSize. At the topmost level, myChildSize is 1, and nextChildSize is 3. 
					
					(nextDivRem % myChildSize).AssertBetween(0, 2);
#endif
					if (nextDivRem == 0) {
						//If nextDivRem is already divisible by nextChildSize, we should preserve this by removing 2*nextChildSize from it.
						//Since 2*nextChildSize = 0 (mod nextChildSize), the divisibility is preserved.
						var left = digit.Construct3(arr, ref index, lin);
						var deep = FTree<Digit>.Construct(arr, ref index, count - (nextChildSize << 1), lin);
						var right = digit.Construct3(arr, ref index, lin);
						ret = new Compound(left, deep, right, lin);
					} else if (nextDivRem == myChildSize) {
						//In this case, nextDivRem % myChildSize == 1. 
						//In order to make sure 'count' is divisible by nextChildSize, we need to remove 1 myChildSize from it.
						//while also filling the current finger tree level. So we remove 7*myChildSize, which is 
						//7*myChildSize = myChildSize + 2*nextChildSize = myChildSize (mod nextChildSize)
						var left = digit.ConstructMult(arr, ref index, 4, lin);
						var deep = FTree<Digit>.Construct(arr, ref index, count - ((nextChildSize << 1) + myChildSize), lin);
						var right = digit.Construct3(arr, ref index, lin);
						ret = new Compound(left, deep, right, lin);
					} else {
						//like the other cases.
						var left = digit.ConstructMult(arr, ref index, 4, lin);
						var deep = FTree<Digit>.Construct(arr, ref index, count - ((nextChildSize << 1) + (myChildSize << 1)), lin);
						var right = digit.ConstructMult(arr, ref index, 4, lin);
						ret = new Compound(left, deep, right, lin);
					}
				}
#if ASSERTS
				ret.Measure.AssertEqual(count);
#endif
				return ret;
			}
コード例 #22
0
ファイル: EmptyFTree.cs プロジェクト: yonglehou/Stact
 public override FTree <T> Merge(FTree <T> rightFT)
 {
     return(rightFT);
 }
コード例 #23
0
ファイル: Empty.cs プロジェクト: stjordanis/Imms
 public override void Split(int index, out FTree <TChild> left, out TChild child, out FTree <TChild> right, Lineage lineage)
 {
     throw ImplErrors.Invalid_invocation("Empty FingerTree");
 }
コード例 #24
0
 public override FTree <T> Merge(FTree <T> rightFT)
 {
     return(rightFT.PushFront(theSingle));
 }
コード例 #25
0
 /// <summary> Removes the object at a given point. </summary>
 public void Remove(object AObject)
 {
     KDTree.Node LNode = (KDTree.Node)FNodes[AObject];
     FTree.Remove(LNode);
     FNodes.Remove(AObject);
 }