Skip to content

Instantly share code, notes, and snippets.

@aloiscochard
Created June 30, 2010 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aloiscochard/458949 to your computer and use it in GitHub Desktop.
Save aloiscochard/458949 to your computer and use it in GitHub Desktop.
IndexTranslator
package org.opensource.aloiscochard;
import java.util.Map;
import java.util.TreeMap;
/**
* This class handle simple translation of index (coordonate).<br>
* <i>N.B. can be used when translating index during string manipulation.</i>
* @author alois.cochard@gmail.com
*
*/
public class IndexTranslator {
/**
* Store index position with translation value.
*/
private Map<Integer, Integer> indexTranslationMap = new TreeMap<Integer, Integer>();
/**
* Add new translation at index.
* @param index the index where translation occur
* @param translation translation value
*/
public void setTranslation(int index, int translation) {
if (translation == 0) {
return;
}
indexTranslationMap.put(index, translation);
}
/**
* Convert translated indexes to original indexes.<br>
* <b>N.B. Translated indexes must be sorted in ascending order</b>
* @param translatedIndexes translated indexes
* @return original indexes
*/
public Integer[] getIndex(Integer... translatedIndexes) {
return translate(false, translatedIndexes);
}
/**
* Convert indexes to translated indexes.<br>
* <b>N.B. Indexes must be sorted in ascending order</b>
* @param indexes original indexes
* @return translated indexes
*/
public Integer[] getTranslatedIndex(Integer... indexes) {
return translate(true, indexes);
}
private Integer[] translate(boolean translated, Integer... input) {
Integer[] output = input.clone();
int translation = 0;
// Browser translation map and calculate relative indexes
int i = 0;
for (Map.Entry<Integer, Integer> indexTranslation : indexTranslationMap.entrySet()) {
// Is memorized index higher than input one
while (indexTranslation.getKey() > output[i]) {
// Memorize translation
translation += convert(output[i] - input[i], translated);
// Next position
i++;
if (i >= output.length) {
break;
}
// Add translation
output[i] += convert(translation, translated);
translation = 0;
}
if (i >= output.length) {
break;
}
// Add memorized index translation
output[i] += convert(indexTranslation.getValue(), translated);
}
if (i < (output.length - 1)) {
// Processing remaining input indexes
translation = convert(output[i] - input[i], translated);
i++;
while (i < output.length) {
output[i] += convert(translation, translated);
i++;
}
}
return filter(output);
}
private Integer[] filter(Integer[] input) {
// Filtering negative values
for (int i = 0; i < input.length; i++) {
if (input[i] < 0) {
input[i] = 0;
} else {
break;
}
}
return input;
}
private int convert(int value, boolean translated) {
if (!translated) {
return -value;
}
return value;
}
}
package org.opensource.aloiscochard;
import org.junit.Assert;
import org.junit.Test;
/**
* Test case for IndexTranslator class.
* @author alois.cochard@gmail.com
*
*/
public class IndexTranslatorTest {
@Test
public void test() {
int[][] translations = { { 6, -3 }, { 20, -4 }, { 33, -3 }, { 56, -6 } };
Integer[] indexes = { 1, 9, 24, 43, 70, 80 };
Integer[] translated = { 1, 6, 17, 33, 54, 64 };
IndexTranslator translator = new IndexTranslator();
for (int[] translation : translations) {
translator.setTranslation(translation[0], translation[1]);
}
Assert.assertArrayEquals(translated, translator.getTranslatedIndex(indexes));
Assert.assertArrayEquals(indexes, translator.getIndex(translated));
}
@Test
public void testNegative() {
int[][] translations = { { 0, -3 } };
Integer[] indexes = { 1, 2, 3 };
Integer[] translated = { 0, 0, 0 };
IndexTranslator translator = new IndexTranslator();
for (int[] translation : translations) {
translator.setTranslation(translation[0], translation[1]);
}
Assert.assertArrayEquals(translated, translator.getTranslatedIndex(indexes));
Assert.assertArrayEquals(new Integer[] { 3, 3, 3 }, translator.getIndex(translated));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment