protected void addSequenceToProjection(Sequence sequence) { // keeps record of encountered items in the sequence // to adding sequence more than once HashSet<Item> seen = new HashSet<Item>(Item.EqComp); for (int i = 0; i < sequence.NumTransactions; i++) { for(int k = 0; k < sequence[i].NumItems; k++) { Item item = sequence[i][k]; // already processed if (seen.Contains(item)) continue; else seen.Add(item); var pSeq = new PseudoSequence(); pSeq.Init(_nextPseudoSequenceIndex, i, k); // point to the next item // in the sequence pSeq.PointToNextItem(sequence); // add pseudo sequence to the list of projections // for the current item List<PseudoSequence> itemProjection; if (!_projections.TryGetValue(item, out itemProjection)) { itemProjection = new List<PseudoSequence>(); _projections.Add(item, itemProjection); } if (pSeq.IsValid) itemProjection.Add(pSeq); } } _nextPseudoSequenceIndex++; }
public bool IsPrefixOf(Dictionary <Item, int> fDict, Sequence seq, PseudoSequence pSeq, out PseudoSequence suffix) { suffix = new PseudoSequence(); if (seq.IsEmpty) { return(false); } if (seq.NumTransactions - pSeq.TransactionIndex < 0) { return(false); } // current transaction index in prefix var prefixTransactionIndex = 0; // current item index in current prefix transaction var prefixItemIndex = 0; // current transaction index in suffix var suffixTransactionIndex = pSeq.TransactionIndex; // current item index in current suffix transaction var suffixItemIndex = pSeq.ItemIndex; // whether or not only last item needs to be matched to form a prefix // e.g. prefix=<(abc)> suffix=<(_c)> only item c needs to be checked // to validate new prefix if (pSeq.ItemIndex != 0 || this.LastTransaction.NumItems == 1) { // only check last item since prefix already established // from previous rounds prefixTransactionIndex = this.NumTransactions - 1; prefixItemIndex = this[prefixTransactionIndex].NumItems - 1; if (pSeq.ItemIndex != 0 && this.LastTransaction.NumItems == 1) { suffixTransactionIndex++; suffixItemIndex = 0; } } for (int i = suffixTransactionIndex; i < seq.NumTransactions; i++) { int k = (i == suffixTransactionIndex) ? suffixItemIndex : 0; for (; k < seq[i].NumItems; k++) { // if the current prefix item does not equal suffix item at [i, k] if (!this[prefixTransactionIndex][prefixItemIndex].Equals(seq[i][k])) { // to form a prefix, all items in the last transaction of the prefix // must be alphabetically AFTER all previous items in the transaction. // The sorting step takes care of that, however, need to check for cases // where two items have the same support making their ordering arbitrary int support; if (pSeq.ItemIndex == 0 || (fDict.TryGetValue(seq[i][k], out support) && support == fDict[this[prefixTransactionIndex][prefixItemIndex]])) { // items have same support, continue continue; } // prefix not found in this transaction break; } // items matched, continue to next item in prefix (if any) prefixItemIndex++; // no more items in current prefix transaction // continue to next transaction (if any) if (prefixItemIndex >= this[prefixTransactionIndex].NumItems) { // move to next transaction in prefix prefixTransactionIndex++; prefixItemIndex = 0; // no more transactions, DONE! if (prefixTransactionIndex >= this.NumTransactions) { // add the suffix pseudo sequence suffix.Init(pSeq.SequenceIndex, i, k); suffix.PointToNextItem(seq); return(suffix.IsValid); } } } // reset the prefix transaction in the case that // the transaction contains more than 1 item // making a full transaction match necessary if (this[prefixTransactionIndex].NumItems != 1) { prefixTransactionIndex = 0; prefixItemIndex = 0; } } return(false); }