View Javadoc

1   /**
2    * Copyright 2005 Steve Molloy
3    * 
4    * This file is part of OV4J.
5    * 
6    * OV4J is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
7    * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
8    * 
9    * OV4J is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
10   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11   * 
12   * You should have received a copy of the GNU General Public License along with OV4J; if not, write to the Free Software
13   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14   * 
15   */
16  package org.ov4j.comp;
17  
18  import java.util.logging.Level;
19  import java.util.logging.Logger;
20  
21  /**
22   * This class is used to compare 2 strings as character sequences.
23   * 
24   * @author smolloy
25   */
26  public class StringComparisonResult extends ComparisonResult<String> {
27  	/**
28  	 * Logger for this class
29  	 */
30  	private static final Logger	logger	= Logger.getLogger(StringComparisonResult.class.getName());
31  
32  	/** How close the 2 strings are to each other. */
33  	private double				similitude;
34  
35  	/**
36  	 * @see org.ov4j.comp.ComparisonResult#compute()
37  	 */
38  	@Override
39  	public void compute() {
40  		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
41  			StringComparisonResult.logger.entering("StringComparisonResult", "compute()", "start");
42  		}
43  
44  		computeSimilitude();
45  		if (getOriginal() != null && getChanged() != null) {
46  			if (getChanged().length() > 0) {
47  				setPrecision(Math.min(1.0, Math.max(0.0, similitude / getChanged().length())));
48  			} else {
49  				setPrecision(1.0);
50  			}
51  			if (getOriginal().length() > 0) {
52  				setRecall(Math.min(1.0, Math.max(0.0, similitude / getOriginal().length())));
53  			} else {
54  				setRecall(1.0);
55  			}
56  		} else if (getOriginal() != null) {
57  			setPrecision(1.0);
58  			setRecall(0.0);
59  		} else if (getChanged() != null) {
60  			setPrecision(0.0);
61  			setRecall(1.0);
62  		} else {
63  			setPrecision(1.0);
64  			setRecall(1.0);
65  		}
66  
67  		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
68  			StringComparisonResult.logger.exiting("StringComparisonResult", "compute()", "end");
69  		}
70  	}
71  
72  	/**
73  	 * Compute the similitude.
74  	 */
75  	public void computeSimilitude() {
76  		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
77  			StringComparisonResult.logger.entering("StringComparisonResult", "computeSimilitude()", "start");
78  		}
79  
80  		if (getOriginal() != null && getChanged() != null) {
81  			final char[] oChars = getOriginal().toCharArray();
82  			final char[] cChars = getChanged().toCharArray();
83  			double dist = 0;
84  			int i = 0, j = 0;
85  			while (i < oChars.length && j < cChars.length) {
86  				if (oChars[i] == cChars[j]) {
87  					i++;
88  					j++;
89  				} else {
90  					int oIdx = getOriginal().indexOf(cChars[j], i);
91  					int cIdx = getChanged().indexOf(oChars[i], j);
92  					if (oIdx < 0) {
93  						oIdx = Integer.MAX_VALUE;
94  					}
95  					if (cIdx < 0) {
96  						cIdx = Integer.MAX_VALUE;
97  					}
98  					if (oIdx == cIdx) {
99  						final NumericComparisonResult<Integer> numRes = new NumericComparisonResult<Integer>();
100 						numRes.setOriginal(Integer.valueOf(oChars[i]));
101 						numRes.setChanged(Integer.valueOf(cChars[j]));
102 						numRes.compute();
103 						dist += 1.0 - numRes.getPrecision();
104 						i++;
105 						j++;
106 					} else if (oIdx < cIdx) {
107 						dist++;
108 						i++;
109 					} else {
110 						dist++;
111 						j++;
112 					}
113 				}
114 			}
115 			dist += oChars.length - i;
116 			dist += cChars.length - j;
117 			similitude = Math.abs(Math.max((double) oChars.length, (double) cChars.length) - dist);
118 		} else if (getOriginal() != null || getChanged() != null) {
119 			similitude = 0.0;
120 		} else {
121 			similitude = 1.0;
122 		}
123 
124 		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
125 			StringComparisonResult.logger.exiting("StringComparisonResult", "computeSimilitude()", "end");
126 		}
127 	}
128 
129 	/**
130 	 * @see org.ov4j.comp.ComparisonResult#fastCompute()
131 	 */
132 	@Override
133 	public void fastCompute() {
134 		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
135 			StringComparisonResult.logger.entering("StringComparisonResult", "fastCompute()", "start");
136 		}
137 
138 		if (getOriginal() != null && getChanged() != null && getOriginal().equals(getChanged())) {
139 			setPrecision(1.0);
140 		}
141 
142 		if (StringComparisonResult.logger.isLoggable(Level.FINER)) {
143 			StringComparisonResult.logger.exiting("StringComparisonResult", "fastCompute()", "end");
144 		}
145 	}
146 
147 	/**
148 	 * @return Returns the similitude.
149 	 */
150 	public double getSimilitude() {
151 		return similitude;
152 	}
153 
154 	/**
155 	 * @param similitude
156 	 *            The similitude to set.
157 	 */
158 	public void setSimilitude(final double similitude) {
159 		this.similitude = similitude;
160 	}
161 }