/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.duplications.detector.suffixtree; import java.util.LinkedList; import java.util.Objects; import java.util.Queue; public class StringSuffixTree { private final SuffixTree suffixTree; private int numberOfEdges; private int numberOfInnerNodes; private int numberOfLeaves; public static StringSuffixTree create(String text) { return new StringSuffixTree(text); } private StringSuffixTree(String text) { suffixTree = SuffixTree.create(new StringText(text)); Queue<Node> queue = new LinkedList<>(); queue.add(suffixTree.getRootNode()); while (!queue.isEmpty()) { Node node = queue.remove(); if (node.getEdges().isEmpty()) { numberOfLeaves++; } else { numberOfInnerNodes++; for (Edge edge : node.getEdges()) { numberOfEdges++; queue.add(edge.getEndNode()); } } } numberOfInnerNodes--; // without root } public int getNumberOfEdges() { return numberOfEdges; } public int getNumberOfInnerNodes() { return numberOfInnerNodes; } // FIXME should be renamed getNumberOfLeaves() public int getNumberOfLeafs() { return numberOfLeaves; } public int indexOf(String str) { return indexOf(suffixTree, new StringText(str)); } public boolean contains(String str) { return contains(suffixTree, new StringText(str)); } public SuffixTree getSuffixTree() { return suffixTree; } public static boolean contains(SuffixTree tree, Text str) { return indexOf(tree, str) >= 0; } public static int indexOf(SuffixTree tree, Text str) { if (str.length() == 0) { return -1; } int index = -1; Node node = tree.getRootNode(); int i = 0; while (i < str.length()) { if (node == null) { return -1; } if (i == tree.text.length()) { return -1; } Edge edge = node.findEdge(str.symbolAt(i)); if (edge == null) { return -1; } index = edge.getBeginIndex() - i; i++; for (int j = edge.getBeginIndex() + 1; j <= edge.getEndIndex(); j++) { if (i == str.length()) { break; } if (!Objects.equals(tree.symbolAt(j), str.symbolAt(i))) { return -1; } i++; } node = edge.getEndNode(); } return index; } }