All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.citec.tcs.alignment.sequence.IndexingScheme Maven / Gradle / Ivy

Go to download

This module contains the sequence datastructure of the TCS Alignment Toolbox. It defines the possible value sets in the ValueType enum as well as the different KeywordSpecification classes, namely: 1.) StringKeywordSpecification for string type values. 2.) SymbolicKeywordSpecification for values from a discrete alphabet (also refer to the Alphabet class) 3.) VectorialKeywordSpecification for vectors of some length (or for scalars) A NodeSpecification is a vector of such KeywordSpecifications and defines the order of value sets. A node, then, is defined as a vector of values from these value sets (also refer to the Value interface as well as the StringValue, SymbolicValue and VectorialValue classes). Finally a sequence is defined as a list of such nodes.

There is a newer version: 3.1.1
Show newest version
/* 
 * TCS Alignment Toolbox Version 3
 * 
 * Copyright (C) 2016
 * Benjamin Paaßen
 * AG Theoretical Computer Science
 * Centre of Excellence Cognitive Interaction Technology (CITEC)
 * University of Bielefeld
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 */

package de.citec.tcs.alignment.sequence;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import lombok.NonNull;

/**
 * This serves as an abstract superclass for classes that define an indexing
 * scheme for keywords. An indexing scheme is defined as an bijective mapping
 * from n arbitrary (but distinct) strings to the integer range [0,n-1].
 *
 * @author Benjamin Paassen - bpaassen(at)techfak.uni-bielefeld.de
 */
public class IndexingScheme {

	private final HashMap indexMapping;
	private String[] keywords;

	/**
	 * This performs a shallow copy of the given other IndexingScheme,
	 * meaning that only references are copied and manipulations of the
	 * given other IndexingScheme will influence the copy as well.
	 *
	 * @param other another IndexingScheme.
	 */
	public IndexingScheme(@NonNull IndexingScheme other) {
		this.indexMapping = other.indexMapping;
		this.keywords = other.keywords;
	}

	/**
	 * Constructs an IndexingScheme from a mapping of strings to indices.
	 * It is checked whether the given mapping is a valid indexing scheme.
	 * An indexing scheme is defined as an bijective mapping
	 * from n arbitrary (but distinct) strings to the integer range [0,n-1].
	 *
	 * @param indexMapping some mapping of Strings to Integers.
	 */
	public IndexingScheme(@NonNull HashMap indexMapping) {
		this.indexMapping = indexMapping;
		this.keywords = new String[indexMapping.size()];
		final HashSet indexSet = new HashSet();
		for (final Entry indexEntry : indexMapping.entrySet()) {
			if (indexEntry.getValue() < 0) {
				throw new IllegalArgumentException("Keyword " + indexEntry.getKey()
						+ " has an index < 0!");
			}
			if (indexEntry.getValue() >= indexMapping.size()) {
				throw new IllegalArgumentException("Keyword " + indexEntry.getKey()
						+ " has an index that is too large!");
			}
			if (!indexSet.add(indexEntry.getValue())) {
				throw new IllegalArgumentException("Keyword " + indexEntry.getKey()
						+ " has an non-unique index!");
			}
			this.keywords[indexEntry.getValue()] = indexEntry.getKey();
		}
	}

	/**
	 * Constructs an IndexingScheme from a mapping of indices to strings. If a
	 * string occurs multiple times in the array, an
	 * UnsupportedOperationException is thrown.
	 *
	 * @param keywords a mapping of indices to strings
	 */
	public IndexingScheme(@NonNull String[] keywords) {
		this.indexMapping = new HashMap<>();
		this.keywords = keywords;
		for (int i = 0; i < keywords.length; i++) {
			if (this.indexMapping.containsKey(keywords[i])) {
				throw new IllegalArgumentException(keywords[i] + "has a non-unique index!");
			}
			this.indexMapping.put(keywords[i], i);
		}
	}

	/**
	 * Constructor for symbols either encoded as single characters without
	 * delimiter or as strings with | as delimiter. If some symbols occur more
	 * often than once they are ignored in the mapping.
	 *
	 * @param symbols a string specifying the symbols this IndexingScheme should
	 * be initialized with.
	 */
	public IndexingScheme(@NonNull String symbols) {
		//first mode: try to find delimiter.
		if (symbols.contains("|")) {
			final String[] split = symbols.split("\\|");
			//remove empty splits at start and finish.
			int startIdx = 0;
			if (split[startIdx].isEmpty()) {
				startIdx++;
			}
			int endIdx = split.length - 1;
			if (split[endIdx].isEmpty()) {
				endIdx--;
			}

			this.keywords = new String[endIdx - startIdx + 1];
			this.indexMapping = new HashMap();
			int j = 0;
			for (int i = startIdx; i <= endIdx; i++) {
				this.keywords[j] = split[i];
				this.indexMapping.put(split[i], j);
				j++;
			}
		} else {
			//otherwise interpret as char array.
			char[] chars = symbols.toCharArray();
			this.keywords = new String[chars.length];
			this.indexMapping = new HashMap();
			for (int i = 0; i < chars.length; i++) {
				this.keywords[i] = new String(new char[]{chars[i]});
				this.indexMapping.put(this.keywords[i], i);
			}
		}
	}

	/**
	 * Returns true if and only if this keyword is contained in the mapping.
	 *
	 * @param keyword a keyword
	 *
	 * @return true if and only if this keyword is contained in the mapping.
	 */
	public boolean hasKeyword(@NonNull final String keyword) {
		return indexMapping.containsKey(keyword);
	}

	/**
	 * Returns the number of mapped keywords.
	 *
	 * @return the number of mapped keywords.
	 */
	public int size() {
		return keywords.length;
	}

	/**
	 * Returns the keywords that are mapped.
	 *
	 * @return the keywords that are mapped.
	 */
	public String[] getKeywords() {
		return keywords;
	}

	/**
	 * Returns the index of the given keyword.
	 *
	 * @param keyword a keyword.
	 *
	 * @return the index of the given keyword.
	 *
	 * @throws UnsupportedOperationException is thrown if the given keyword is
	 * not contained in this mapping.
	 */
	public int getKeywordIndex(@NonNull final String keyword) throws UnsupportedOperationException {
		final Integer index = indexMapping.get(keyword);
		if (index == null) {
			throw new IllegalArgumentException("The keyword " + keyword + " has not been defined!");
		}
		return index;
	}

	/**
	 * Returns the keyword for the given index.
	 *
	 * @param index a index.
	 *
	 * @return the keyword for the given index.
	 *
	 * @throws ArrayIndexOutOfBoundsException is thrown if the given index is
	 * not used in this mapping.
	 */
	public String getKeyword(final int index) throws ArrayIndexOutOfBoundsException {
		return keywords[index];
	}

	@Override
	public int hashCode() {
		int hash = 5;
		hash = 43 * hash + Arrays.deepHashCode(this.keywords);
		return hash;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final IndexingScheme other = (IndexingScheme) obj;
		if (!Arrays.deepEquals(this.keywords, other.keywords)) {
			return false;
		}
		return true;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy