Implement illustration for the folding technique
This commit is contained in:
parent
2449c8117a
commit
97c1f79f32
@ -0,0 +1,77 @@
|
||||
package com.baeldung.folding;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Calculate a hash value for the strings using the folding technique.
|
||||
*
|
||||
* The implementation serves only to the illustration purposes and is far
|
||||
* from being the most efficient.
|
||||
*
|
||||
* @author veontomo
|
||||
*
|
||||
*/
|
||||
public class FoldingHash {
|
||||
|
||||
/**
|
||||
* Calculate the hash value of a given string
|
||||
* @param str
|
||||
* @param groupSize
|
||||
* @param maxValue
|
||||
* @return
|
||||
*/
|
||||
public int hash(String str, int groupSize, int maxValue) {
|
||||
final int[] codes = this.toAsciiCodes(str);
|
||||
return IntStream.range(0, str.length())
|
||||
.filter(i -> i % groupSize == 0)
|
||||
.mapToObj(i -> extract(codes, i, groupSize))
|
||||
.map(block -> concatenate(block))
|
||||
.reduce(0, (a, b) -> (a + b) % maxValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array of given length whose elements are take from
|
||||
* the original one starting from the offset.
|
||||
*
|
||||
* If the original array has not enough elements, the returning array will contain
|
||||
* element from the offset till the end of the original array.
|
||||
*
|
||||
* @param numbers
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public int[] extract(int[] numbers, int offset, int length) {
|
||||
final int defect = numbers.length - (offset + length);
|
||||
final int s = defect < 0 ? length + defect : length;
|
||||
int[] result = new int[s];
|
||||
for (int index = 0; index < s; index++) {
|
||||
result[index] = numbers[index + offset];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate the numbers into a single number.
|
||||
* Assume that the procedure does not suffer from the overflow.
|
||||
* @param numbers
|
||||
* @return
|
||||
*/
|
||||
public int concatenate(int[] numbers) {
|
||||
final String merged = IntStream.of(numbers)
|
||||
.mapToObj(number -> "" + number)
|
||||
.collect(Collectors.joining());
|
||||
return Integer.parseInt(merged, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the string into its characters' ascii codes.
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
private int[] toAsciiCodes(String str) {
|
||||
return str.chars()
|
||||
.toArray();
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.baeldung.folding;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class FoldingHashUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenStringJavaLanguage_whenSize2Capacity100000_then48933() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int value = hasher.hash("Java language", 2, 100_000);
|
||||
assertEquals(value, 48933);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenStringVaJaLanguage_whenSize2Capacity100000_thenSameAsJavaLanguage() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int java = hasher.hash("Java language", 2, 100_000);
|
||||
final int vaja = hasher.hash("vaJa language", 2, 100_000);
|
||||
assertTrue(java == vaja);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenSingleElementArray_whenOffset0Size2_thenSingleElement() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int[] value = hasher.extract(new int[] {5}, 0, 2);
|
||||
assertArrayEquals(new int[] {5}, value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFiveElementArray_whenOffset0Size3_thenFirstThreeElements() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 0, 3);
|
||||
assertArrayEquals(new int[] {1, 2, 3}, value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFiveElementArray_whenOffset1Size2_thenTwoElements() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 1, 2);
|
||||
assertArrayEquals(new int[] {2, 3}, value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFiveElementArray_whenOffset2SizeTooBig_thenElementsToTheEnd() throws Exception {
|
||||
final FoldingHash hasher = new FoldingHash();
|
||||
final int[] value = hasher.extract(new int[] {1, 2, 3, 4, 5}, 2, 2000);
|
||||
assertArrayEquals(new int[] {3, 4, 5}, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user