package jal.GENERIC; import jal.GENERIC.VoidFunction; import jal.GENERIC.Predicate; import jal.GENERIC.BinaryPredicate; /** * A class that encapsulates non-mutating sequence algorithms on one * and two arrays. All methods are static and all variables are * static and final, so this class has no constructors. * *

* Most methods operate on a range of elements. A range is described * by the index of its first element and an index that is * one past its last element. So, for example, * [n, n+1) is a range that contains one element, * [n, n) is a range that contains zero elements, * and [n, n-1) is not a valid range. * *

* Unless otherwise specified, the test for equality uses * the == operator by default. Any different notion of * equality may be represented as a BinaryPredicate. You can use the * predefined class Equals, which implements BinaryPredicate, if you want * to use the Object.equals() method. * *

Copyright © 1996 * Silicon Graphics, Inc. * *
Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or * implied warranty. * * * @see Modification * @see Sorting * @see Numeric * @see BinaryPredicate * @see Equals * @author Matthew Austern (austern@mti.sgi.com) * @author Alexander Stepanov (stepanov@mti.sgi.com) */ final public class Inspection { /** * Applies a function to every element of a range. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @param f Function to be applied. */ public static void for_each(generic[] array, int first, int last, VoidFunction f) { while(first < last) f.apply(array[first++]); } /** * Finds the first adjacent pair of equal elements in a range. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @return The first iterator i in the range * [first, last-1) such that * array[i] == array[i+1]. Returns * last if no such iterator exists. */ public static int adjacent_find(generic[] array, int first, int last) { int next = first; while (++next < last) { if (array[first] == array[next]) return first; else first = next; } return last; } /** * Finds the first adjacent pair of elements in a range that satisfy * some condition. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @param p Condition that must be satisfied. * @return The first iterator i in the range * [first, last-1) such that * p.apply(array[i], array[i+1]) is * true. Returns * last if no such iterator exists. */ public static int adjacent_find(generic[] array, int first, int last, BinaryPredicate p) { int next = first; while (++next < last) { if (p.apply(array[first], array[next])) return first; else first = next; } return last; } /** * Finds the first element in a range that is equal to a specified value. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @param x Value to be searched for. * @return Index of first element E such that * E == x, or last if no such * element exists. */ public static int find(generic[] array, int first, int last, generic x) { while (first < last && !(x == array[first])) ++first; return first; } /** * Finds the first element in a range that is not equal to a specified value. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @param x Value to be searched for. * @return Index of first element E such that * E != x, or last if no such * element exists. */ public static int find_not(generic[] array, int first, int last, generic x) { while (first < last && x == array[first]) ++first; return first; } /** * Finds the first element in a range that satisfies a condition. * @param array Array containing the range. * @param first Beginning of the range. * @param last One past the end of the range. * @param p Condition to search for. * @return Index of first element E such that * E == x, or last if no such * element exists. */ public static int find_if(generic[] array, int first, int last, Predicate p) { while (first < last && !p.apply(array[first])) ++first; return first; } /** * Finds the first element in a range that does not satisfy some condition. * @param array Array containing the range * @param first Beginning of the range * @param last One past the end of the range * @param p Condition being tested * @return Index of first element E such that * p.apply(E) is false, or * last if no such element exists. */ public static int find_if_not(generic[] array, int first, int last, Predicate p) { while (first < last && p.apply(array[first])) ++first; return first; } /** * Counts the number of elements in a range that satisfy a condition. * @param array Array containing the range * @param first Beginning of the range * @param last One past the end of the range * @param p Condition being tested * @return Number of elements E such that * p.apply(E) is true. */ public static int count_if(generic[] array, int first, int last, Predicate p) { int counter = 0; while (first < last) if (p.apply(array[first++])) ++counter; return counter; } /** * Counts the number of elements in a range that do not satisfy a condition. * @param array Array containing the range * @param first Beginning of the range * @param last One past the end of the range * @param p Condition being tested * @return Number of elements E such that * p.apply(E) is false. */ public static int count_if_not(generic[] array, int first, int last, Predicate p) { int counter = 0; while (first < last) if (!p.apply(array[first++])) ++counter; return counter; } /** * Finds the first location at which two ranges differ. * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range * @param last1 One past the end of the first range * @param first2 Beginning of the second range * @return The first index i such that * array1[i] != array2[first2 + (i-first1)], * or last1 if no such index in the range * [first1,last1) exists. */ public static int mismatch(generic[] array1, generic[] array2, int first1, int last1, int first2) { while(first1 < last1 && array1[first1] == array2[first2]) { ++first1; ++first2; } return first1; } /** * Finds the first location at which two ranges fail to satisfy a condition. * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range * @param last1 One past the end of the first range * @param first2 Beginning of the second range * @param p Condition to be tested * @return The first index i such that * p.apply(array1[i], array2[first2 + (i-first1)]) * is false, or last1 if no such * index in the range [first1,last1) exists. */ public static int mismatch(generic[] array1, generic[] array2, int first1, int last1, int first2, BinaryPredicate p) { while(first1 < last1 && p.apply(array1[first1], array2[first2])) { ++first1; ++first2; } return first1; } /** * Tests whether two ranges are pairwise equal. * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range * @param last1 One past the end of the first range * @param first2 Beginning of the second range * @return true if, for every index i * in the range [first1,last1), * array1[i] == array2[first2 + (i-first1)], * otherwise returns false. */ public static boolean equal(generic[] array1, generic[] array2, int first1, int last1, int first2) { while (first1 < last1 && array1[first1] == array2[first2]) { ++first1; ++first2; } return first1 >= last1; } /** * Tests whether two ranges satisfiy a condition pairwise. * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range. * @param last1 One past the end of the first range. * @param first2 Beginning of the second range. * @param p Condition to be tested * @return true if, for every index i * in the range [first1,last1), * p.apply(array1[i], array2[first2 + (i-first1)]) * is true, otherwise returns false. */ public static boolean equal(generic[] array1, generic[] array2, int first1, int last1, int first2, BinaryPredicate p) { while (first1 < last1 && p.apply(array1[first1], array2[first2])) { ++first1; ++first2; } return first1 >= last1; } /** * Searches, within one range, for a sequence of elements equal * to the elements in a second range. * * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * Note: the worst-case performance of this algorithm is quadratic. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range. * @param last1 One past the end of the first range. * @param first2 Beginning of the second range. * @param last2 One past the end of the second range. * @return The first index in the range * [first1, last1-len) such that * for every non-negative i<len * (where len = last2-first2), the * condition * array1[first1+n] == array2[first1+n] * is satisfied, or last1 if no such * index exists. */ public static int search(generic[] array1, generic[] array2, int first1, int last1, int first2, int last2) { int len1 = last1 - first1; int len2 = last2 - first2; int cur1 = first1; int cur2 = first2; if (len1 < len2) return last1; while (cur2 < last2) { if (array1[cur1++] != array2[cur2++]) { if (len1 == len2) return last1; else { cur1 = ++first1; cur2 = first2; --len1; } } } return (cur2 == last2) ? first1 : last1; } /** * Searches, within one range, for a sequence of elements that match * the elements in a second range. Matching is defined as satisfying * a BinaryPredicate passed as an argument. * * Note: the two * ranges are permitted to be in the same array and are permitted to * overlap. * Note: the worst-case performance of this algorithm is quadratic. * @param array1 Array containing the first range. * @param array2 Array containing the first range. * @param first1 Beginning of the first range. * @param last1 One past the end of the first range. * @param first2 Beginning of the second range. * @param last2 One past the end of the second range. * @param p Condition to be tested pairwise. * @return The first index in the range * [first1, last1-len) such that * for every non-negative i<len * (where len = last2-first2), the * condition * p.apply(array1[first1+n],array2[first1+n]) * is satisfied, or last1 if no such * index exists. */ public static int search(generic[] array1, generic[] array2, int first1, int last1, int first2, int last2, BinaryPredicate p) { int len1 = last1 - first1; int len2 = last2 - first2; int cur1 = first1; int cur2 = first2; if (len1 < len2) return last1; while (cur2 < last2) { if (!p.apply(array1[cur1++], array2[cur2++])) { if (len1 == len2) return last1; else { cur1 = ++first1; cur2 = first2; --len1; } } } return (cur2 == last2) ? first1 : last1; } /* We don't need a constructor. */ private Inspection() {} }