    001    /*
    002     * Factor.java
    003     *
    004     * Copyright 2003 Sergio Anibal de Carvalho Junior
    005     *
    006     * This file is part of NeoBio.
    007     *
    008     * NeoBio is free software; you can redistribute it and/or modify it under the terms of
    009     * the GNU General Public License as published by the Free Software Foundation; either
    010     * version 2 of the License, or (at your option) any later version.
    011     *
    012     * NeoBio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    013     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    014     * PURPOSE. See the GNU General Public License for more details.
    015     *
    016     * You should have received a copy of the GNU General Public License along with NeoBio;
    017     * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    018     * Boston, MA 02111-1307, USA.
    019     *
    020     * Proper attribution of the author as the source of the software would be appreciated.
    021     *
    022     * Sergio Anibal de Carvalho Junior             mailto:sergioanibaljr@users.sourceforge.net
    023     * Department of Computer Science               http://www.dcs.kcl.ac.uk
    024     * King's College London, UK                    http://www.kcl.ac.uk
    025     *
    026     * Please visit http://neobio.sourceforge.net
    027     *
    028     * This project was supervised by Professor Maxime Crochemore.
    029     *
    030     */
    031
    032    package neobio.alignment;
    033
    034    /**
    035     * This class is used by {@linkplain FactorSequence} to create a linked list of factors of
    036     * a text as induced by its Lempel-Ziv (LZ78) factorisation.
    037     *
    038     * <P>Each instance of this class represent a string composed of its an ancestor factor's
    039     * string plus one character, and contains:
    040     *
    041     * <UL>
    042     * <LI>a pointer to its ancestor factor (the longest factor previously seen in the text
    043     * during its LZ78 factorisation);
    044     * <LI>the new character;
    045     * <LI>a serial number (which represents its order in the text)
    046     * <LI>a pointer to the next factor of the text
    047     * <LI>its length (number of characters, which is equal to its ancestor's length plus one)
    048     * </UL>
    049     *
    050     * @author Sergio A. de Carvalho Jr.
    051     * @see FactorSequence
    052     */
    053    public class Factor
    054    {
    055            /**
    056             * A pointer to this factor's ancestor, which represents a prefix of this factor's
    057             * text.
    058             */
    059            protected Factor ancestor;
    060
    061            /**
    062             * A pointer to the next factor.
    063             */
    064            protected Factor next;
    065
    066            /**
    067             * This factor's serial number, which indicates the order of this factor inside the
    068             * linked list of factors of a text.
    069             */
    070            protected int serial_number;
    071
    072            /**
    073             * The number of characters of the text represented by this factor.
    074             */
    075            protected int length;
    076
    077            /**
    078             * The new character of this factor.
    079             */
    080            protected char new_char;
    081
    082            /**
    083             * Creates a new empty <CODE>Factor</CODE>. It has no ancestor and no character (both
    084             * are set to <CODE>null</CODE>). Its serial number is set to zero as well as its
    085             * length.
    086             *
    087             * <P>This constructor is used to initiate the a linked list of factors of a text. Its
    088             * <CODE>next</CODE> pointer is initially <CODE>null</CODE>, but it is typically set
    089             * to point to the first factor afterwards (with the <CODE>setNext</CODE> method).
    090             *
    091             * @see #setNext
    092             */
    093            public Factor ()
    094            {
    095                    this.ancestor = null;
    096                    this.next = null;
    097                    this.serial_number = 0;
    098                    this.length = 0;
    099                    this.new_char = 0;
    100            }
    101
    102            /**
    103             * Creates a new <CODE>Factor</CODE> instance with the specified serial number and
    104             * new character, and pointing to the given ancestor. Its length is set to its
    105             * ancestor's length plus 1.
    106             *
    107             * <P>Its <CODE>next</CODE> pointer is initially <CODE>null</CODE>, but it is
    108             * typically set to point to the next factor afterwards (with the <CODE>setNext</CODE>
    109             * method).
    110             *
    111             * @param ancestor this factor's ancestor
    112             * @param serial_number this factor's serial number
    113             * @param new_char this factor's new character
    114             * @see #setNext
    115             */
    116            public Factor (Factor ancestor, int serial_number, char new_char)
    117            {
    118                    this.ancestor = ancestor;
    119                    this.serial_number = serial_number;
    120                    this.new_char = new_char;
    121                    if (ancestor != null)
    122                            this.length = ancestor.length() + 1;
    123                    else
    124                            throw new IllegalArgumentException ("Ancestor factor cannot be null.");
    125            }
    126
    127            /**
    128             * Sets this factor's <CODE>next</CODE> pointer to point to the specified factor.
    129             * Although the next factor has typically a serial number equal to this factor's
    130             * serial number plus 1, no attempt is made to guarantee this rule. This allows
    131             * special constructs or a different order in the factorisation.
    132             *
    133             * @param next the factor that will be pointed to
    134             * @see #getNext
    135             */
    136            public void setNext (Factor next)
    137            {
    138                    this.next = next;
    139            }
    140
    141            /**
    142             * Returns this factor's ancestor factor.
    143             *
    144             * @return this factor's ancestor factor
    145             */
    146            public Factor getAncestor ()
    147            {
    148                    return ancestor;
    149            }
    150
    151            /**
    152             * This method is a shorthand to return the serial number of this factor's ancestor.
    153             * Note that it does not check if this factor has an ancestor or not, therefore, if
    154             * it is called on the root factor, a NullPointerException is raised.
    155             *
    156             * @return the serial number of this factor's ancestor
    157             */
    158            public int getAncestorSerialNumber ()
    159            {
    160                    return ancestor.getSerialNumber();
    161            }
    162
    163            /**
    164             * Returns this factor's next factor.
    165             *
    166             * @return this factor's next factor
    167             * @see #setNext
    168             */
    169            public Factor getNext ()
    170            {
    171                    return next;
    172            }
    173
    174            /**
    175             * Returns this factor's serial number.
    176             *
    177             * @return this factor's serial number
    178             */
    179            public int getSerialNumber ()
    180            {
    181                    return serial_number;
    182            }
    183
    184            /**
    185             * Returns this factor's length.
    186             *
    187             * @return this factor's length
    188             */
    189            public int length ()
    190            {
    191                    return length;
    192            }
    193
    194            /**
    195             * Returns this factor's new character.
    196             *
    197             * @return this factor's new character
    198             */
    199            public char getNewChar ()
    200            {
    201                    return new_char;
    202            }
    203
    204            /**
    205             * Returns a string representation of the text represented by this factor. It inspects
    206             * its chain of ancestors up until as far as the root factor, spelling their new
    207             * characters out.
    208             *
    209             * @return a string representation of the text denoted by this factor
    210             */
    211            public String toString ()
    212            {
    213                    StringBuffer buf = new StringBuffer();
    214                    Factor ancestor = this;
    215
    216                    while (ancestor.getAncestor() != null)
    217                    {
    218                            buf.insert(0, ancestor.getNewChar());
    219                            ancestor = ancestor.getAncestor();
    220                    }
    221
    222                    return buf.toString();
    223            }
    224    }