public BlockSuffixArrayStrategy(BlockSuffixArray array, int idx, ZAlgorithm algorithm, int newSuffixIndex) { this.array = array; this.idx = idx; this.algorithm = algorithm; this.newSuffixIndex = newSuffixIndex; }
private void MoveSuffix(int boundSuffix, int idx, ZAlgorithm zAlgorithm, int index, string str, HashedSet <int> newBoundarySuffix) { int first = BinarySearch.BinarySearch.Instance.BinarySearchFirst(idx + 1, Math.Min(ArrayLength + 1, idx + 1 + CharCollector.GetInt(String[boundSuffix])), new BlockSuffixArrayStrategy(this, idx, zAlgorithm, index)) - 1; if (idx > 0) { Lcp[idx - 1] = Math.Min(Lcp[idx], Lcp[idx - 1]); } CompareResult compare1 = Compare(idx, first, zAlgorithm, index); CompareResult compare2; if (first == ArrayLength - 1) { compare2 = new CompareResult(1, 0); } else { compare2 = Compare(idx, first + 1, zAlgorithm, index); } Array.Move(idx, first); Lcp.Move(idx, first); Lcp[first - 1] = compare1.Lcp; Lcp[first] = compare2.Lcp; //boundary support if (compare2.Lcp == str.Length + ArrayLength - Array[first]) { newBoundarySuffix.Add(boundSuffix); } }
private void BoundarySuffixesProcess(string str, ZAlgorithm zAlgorithm, int index) { HashedSet <int> newBoundarySuffix = new HashedSet <int>(); foreach (int boundSuffix in Sorted(BoundarySuffix)) { BoundarySuffixProcess(str, boundSuffix, zAlgorithm, index, newBoundarySuffix); } UpdateBoundarySuffixes(newBoundarySuffix); }
private void BoundarySuffixProcess(string str, int boundSuffix, ZAlgorithm zAlgorithm, int index, HashedSet <int> newBoundarySuffix) { int idx = Array.GetInverse(boundSuffix); CompareResult compare = Compare(idx, idx + 1, zAlgorithm, index); if (compare.Compare >= 1) { MoveSuffix(boundSuffix, idx, zAlgorithm, index, str, newBoundarySuffix); } else { Lcp[idx] = compare.Lcp; if (compare.Lcp == ArrayLength + str.Length - Array[idx]) { newBoundarySuffix.Add(boundSuffix); } } }
protected void AddNewString(string str) { int position = FindInsertPosisition(str); int index = Array[position]; int currentLength = ArrayLength; ((CustomStringBuilder)String).Append(str); ZAlgorithm zAlgorithm = new ZAlgorithm(str); BoundarySuffixesProcess(str, zAlgorithm, index); ArrayLength += str.Length; InsertSuffixes(str, index, currentLength); UpdateCharCollector(str); }
internal CompareResult Compare(int i, int j, ZAlgorithm zAlgorithm, int newSuffixIndex) { if (i >= j) { throw new ArgumentOutOfRangeException("j"); } int mainLcp = Lcp.Aggregate(i, j - 1); int arrayI = Array[i]; int arrayJ = Array[j]; int lenI = ArrayLength - arrayI; int lenJ = ArrayLength - arrayJ; int newSuffixPosition = Array.GetInverse(newSuffixIndex); if (mainLcp >= lenI) { int lenDeltaIJ = arrayI - arrayJ; if (lenDeltaIJ < 0) { throw new ArgumentOutOfRangeException(); } if (lenDeltaIJ >= zAlgorithm.Str.Length) { int posDeltaIJ = Array.GetInverse(ArrayLength - lenDeltaIJ); int lcp = GetLcp(newSuffixPosition, posDeltaIJ); if (lcp >= lenDeltaIJ) { return(new CompareResult(-1, lenI + zAlgorithm.Str.Length)); } else { if (lcp > zAlgorithm.Str.Length) { return(new CompareResult(-1, lenI + zAlgorithm.Str.Length)); } else { return(new CompareResult(String[newSuffixIndex + lcp].CompareTo(String[ArrayLength - lenDeltaIJ + lcp]), lenI + lcp)); } } } else { int posDeltaIJ = Array.GetInverse(ArrayLength - lenDeltaIJ); int lcp = GetLcp(newSuffixPosition, posDeltaIJ); if (lcp >= lenDeltaIJ) { int zDelta = zAlgorithm.Str.Length - lenDeltaIJ; if (zDelta == 0) { return(new CompareResult(-1, lenI + zAlgorithm.Str.Length)); } else { return(new CompareResult(zAlgorithm.Compare(zAlgorithm.Str.Length - zDelta), lenJ + zAlgorithm.Lcp[zAlgorithm.Str.Length - zDelta])); } } else { return(new CompareResult(String[newSuffixIndex + lcp].CompareTo(String[ArrayLength - lenDeltaIJ + lcp]), lenI + lcp)); } } } return(new CompareResult(-1, mainLcp)); }