/** * @author Jonathan */ package com.abewy.android.extended.util; import java.util.List; public class SearchUtil { public static final int NOT_FOUND = -1; /** * <p>Search an object in an array of object using a binary search.</p> * <p>Binary search is O(log N) complexity</p> * <p>The array must be sorted from lower to higher</p> * * @param a the array to search in * @param x the object to search for * @return the index of the object, -1 if not found */ public static <T extends Comparable<? super T>> int binarySearch(T[] a, T x) { int low = 0, high = a.length - 1; while (low <= high) { int mid = (low + high) / 2; int result = a[mid].compareTo(x); if (result < 0) low = mid + 1; else if (result > 0) high = mid - 1; else return mid; // Found } return NOT_FOUND; } /** * <p>Search an object in an list of object using a binary search.</p> * <p>Binary search is O(log N) complexity</p> * <p>The list must be sorted from lower to higher</p> * * @param l the list to search in * @param x the object to search for * @return the index of the object, -1 if not found */ public static <T extends Comparable<? super T>> int binarySearch(List<T> l, T x) { int low = 0, high = l.size() - 1; while (low <= high) { int mid = (low + high) / 2; int result = l.get(mid).compareTo(x); if (result < 0) low = mid + 1; else if (result > 0) high = mid - 1; else return mid; // Found } return NOT_FOUND; } /** * <p>Return the maximum sum of a consecutive sub sequence of the array</p> * <p>For exemple, consider the following array : -2 11, -4, 13, -5, -2. * <br />Then the maximum sub sequence sum is 20 (11, -4, 13).</p> * * * @param a an array of integers (positive and negatives) * @return the maximum sub sequence sum */ public static int maxSubSum(int[] a) { // Here are others algorithms that are working // But that have a higher complexity // This is the simple but worst algorithm, complexity O(N�) /*int maxSum = 0; for (int i = 0; i < a.length; i++) { for (int j = i; j < a.length; j++) { int thisSum = 0; for (int k = i; k <= j; k++) thisSum += a[k]; if (thisSum > maxSum) maxSum = thisSum; } } return maxSum;*/ // Second one, complexity O(N�) /*int maxSum = 0; for (int i = 0; i < a.length; i++) { int thisSum = 0; for (int j = i; j < a.length; j++) { thisSum += a[j]; if (thisSum > maxSum) maxSum = thisSum; } } return maxSum;*/ // Third one, better than the previous one but very complex // Complexity O(N log N) // This algorithm uses the "divide and conquer" strategy // We calculate first the max sum of the left half of the array, // then on the right half, then we return the max value of the left, // right and the sum of the two at the center /*public static int maxSumRec(int[] a, int left, int right) { if (left == right) { if (a[left] > 0) return a[left]; else return 0; } int center = (left + right) / 2; int maxLeftSum = maxSumRec(a, left, center); int maxRightSum = maxSumRec(a, center + 1, right); int maxLeftBorderSum = 0, leftBorderSum = 0; for (int i = center; i >= left; i--) { leftBorderSum += a[i]; if (leftBorderSum > maxLeftBorderSum) maxLeftBorderSum = leftBorderSum; } int maxRightBorderSum = 0, rightBorderSum = 0; for (int i = center + 1; i <= right; i++) { rightBorderSum += a[i]; if (rightBorderSum > maxRightBorderSum) maxRightBorderSum = rightBorderSum; } // max3() return the maximum of the 3 values return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); }*/ // This is the best algorithm, complexity O(N) int maxSum = 0, thisSum = 0; for (int j = 0, n = a.length; j < n; j++) { thisSum += a[j]; if (thisSum > maxSum) maxSum = thisSum; else thisSum = 0; } return maxSum; } }