From e890805c1d6a0885f9c515a324c5ace8ad3e3a52 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 21 Jan 2014 17:57:23 +0100 Subject: add multiinterpolation search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .../searching/MultiinterpolationSearch.java | 141 +++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/algorithms/searching/MultiinterpolationSearch.java (limited to 'src') diff --git a/src/algorithms/searching/MultiinterpolationSearch.java b/src/algorithms/searching/MultiinterpolationSearch.java new file mode 100644 index 0000000..0a69721 --- /dev/null +++ b/src/algorithms/searching/MultiinterpolationSearch.java @@ -0,0 +1,141 @@ +/** + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * 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 algorithms.searching; + +import java.util.*; +import java.math.*; + + +/** + * Multiinterpolation search class.This algorithm is exactly to + * interpolation search as multibinary search is to binary search. + * + * This algorithm was devised by Mattias Andrée in January of 2014. + */ +public class MultiinterpolationSearch +{ +£>for T in char byte short int long float double BigInteger BigDecimal; do . src/comparable + /** + * Find the indices of multiple items in a list + * + * @param items Sorted list of unique items for which to search + * @param array Sorted list in which to search + * @return Two arrays of integer arrays, the 0:th being the indices + * of items, the 1:th being their positions. That is, + * two separate arrays, not and array of pairs. The expected + * position is returned inverted if it was not found, the + * position it whould have upon be inserted, otherwise the + * position is returned as an index. + */ + public static £(fun "long[][]" indexOf "${T}[] items, ${Tarray} array") + { + return indexOf(items, array, 0, array.length - 1£{Targ_name}); + } + + /** + * Find the indices of multiple items in a list + * + * @param items Sorted list of unique items for which to search + * @param array Sorted list in which to search + * @param start The index of the first position to search in the array + * @return Two arrays of integer arrays, the 0:th being the indices + * of items, the 1:th being their positions. That is, + * two separate arrays, not and array of pairs. The expected + * position is returned inverted if it was not found, the + * position it whould have upon be inserted, otherwise the + * position is returned as an index. + */ + public static £(fun "long[][]" indexOf "${T}[] items, ${Tarray} array, int start") + { + return indexOf(items, array, start, array.length - 1£{Targ_name}); + } + + /** + * Find the indices of multiple items in a list + * + * @param items Sorted list of unique items for which to search + * @param array Sorted list in which to search + * @param start The index of the first position to search in the array + * @param end The index after the last position to search in the array + * @return Two arrays of integer arrays, the 0:th being the indices + * of items, the 1:th being their positions. That is, + * two separate arrays, not and array of pairs. The expected + * position is returned inverted if it was not found, the + * position it whould have upon be inserted, otherwise the + * position is returned as an index. + */ + public static £(fun "long[][]" indexOf "${T}[] items, ${Tarray} array, int start, int end") + { + int m = items.length, lb_m = 1; + long[][] rc = new long[2][m]; + + if (m == 0) + return rc; + + if ((m & 0xFFFF0000) != 0) { lb_m |= 16; m >>= 16; } + if ((m & 0x0000FF00) != 0) { lb_m |= 8; m >>= 8; } + if ((m & 0x000000F0) != 0) { lb_m |= 4; m >>= 4; } + if ((m & 0x0000000C) != 0) { lb_m |= 2; m >>= 2; } + if ((m & 0x00000002) != 0) { lb_m += 1; } + + int[][] minomax = new int[4][lb_m]; + m = items.length - 1; + + int rc_i = 0; + int mm_i = 0; + int imin, imax, amin = 0, amax = 0, lastimax, lastamax; + + minomax[0][mm_i] = 0; + minomax[1][mm_i] = m; + minomax[2][mm_i] = start; + minomax[3][mm_i++] = end - 1; + +£>interpol_search="InterpolationSearch.indexOf(items[imax], array, amin, amax${Targ_name})" + + while (mm_i-- > 0) + { + imin = minomax[0][mm_i]; + imax = minomax[1][mm_i]; + amin = minomax[2][mm_i]; + amax = minomax[3][mm_i]; + + while (imax != imin) + { + lastimax = imax; + lastamax = amax; + rc[0][rc_i] = imax = imin + ((imax - imin) >>> 1); + rc[1][rc_i++] = amax = (int)(£{interpol_search}); + if (amax < 0) + amax = ~amax; + + minomax[0][mm_i] = imax + 1; + minomax[1][mm_i] = lastimax; + minomax[2][mm_i] = amax + 1; + minomax[3][mm_i++] = lastamax; + } + } + + imax = m; + amax = (int)(£{interpol_search}); + rc[0][rc_i] = imax; + rc[1][rc_i++] = amax; + + return rc; + } +£>done +} + -- cgit v1.2.3-70-g09d2