Java String substring for initial common from String list

Description

Java String substring for initial common from String list

public class Main {
  public static void main(String[] argv) throws Exception {
    String[] strs = new String[] { "CSS", "CSS3" };
    System.out.println(getCommonPrefix(strs));
  }//from   w  w  w.j a va2 s .c  om
  public static final String EMPTY = "";

  /**
   * <p>
   * Compares all Strings in an array and returns the initial sequence of
   * characters that is common to all of them.
   * </p>
   *
   * <p>
   * For example,
   * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code>
   * </p>
   *
   * <pre>
   * getCommonPrefix(null) = ""
   * getCommonPrefix(new String[] {}) = ""
   * getCommonPrefix(new String[] {"abc"}) = "abc"
   * getCommonPrefix(new String[] {null, null}) = ""
   * getCommonPrefix(new String[] {"", ""}) = ""
   * getCommonPrefix(new String[] {"", null}) = ""
   * getCommonPrefix(new String[] {"abc", null, null}) = ""
   * getCommonPrefix(new String[] {null, null, "abc"}) = ""
   * getCommonPrefix(new String[] {"", "abc"}) = ""
   * getCommonPrefix(new String[] {"abc", ""}) = ""
   * getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
   * getCommonPrefix(new String[] {"abc", "a"}) = "a"
   * getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
   * getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
   * getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
   * getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
   * getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
   * </pre>
   *
   * @param strs
   *          array of String objects, entries may be null
   * @return the initial sequence of characters that are common to all Strings in
   *         the array; empty String if the array is null, the elements are all
   *         null or if there is no common prefix.
   * @since 2.4
   */
  public static String getCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) {
      return EMPTY;
    }
    int smallestIndexOfDiff = indexOfDifference(strs);
    if (smallestIndexOfDiff == -1) {
      // all strings were identical
      if (strs[0] == null) {
        return EMPTY;
      }
      return strs[0];
    } else if (smallestIndexOfDiff == 0) {
      // there were no common initial characters
      return EMPTY;
    } else {
      // we found a common initial character sequence
      return strs[0].substring(0, smallestIndexOfDiff);
    }
  }

  /**
   * <p>
   * Compares two Strings, and returns the index at which the Strings begin to
   * differ.
   * </p>
   *
   * <p>
   * For example,
   * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code>
   * </p>
   *
   * <pre>
   * indexOfDifference(null, null) = -1
   * indexOfDifference("", "") = -1
   * indexOfDifference("", "abc") = 0
   * indexOfDifference("abc", "") = 0
   * indexOfDifference("abc", "abc") = -1
   * indexOfDifference("ab", "abxyz") = 2
   * indexOfDifference("abcde", "abxyz") = 2
   * indexOfDifference("abcde", "xyz") = 0
   * </pre>
   *
   * @param str1
   *          the first String, may be null
   * @param str2
   *          the second String, may be null
   * @return the index where str2 and str1 begin to differ; -1 if they are equal
   * @since 2.0
   */
  public static int indexOfDifference(String str1, String str2) {
    if (str1 == str2) {
      return -1;
    }
    if (str1 == null || str2 == null) {
      return 0;
    }
    int i;
    for (i = 0; i < str1.length() && i < str2.length(); ++i) {
      if (str1.charAt(i) != str2.charAt(i)) {
        break;
      }
    }
    if (i < str2.length() || i < str1.length()) {
      return i;
    }
    return -1;
  }

  /**
   * <p>
   * Compares all Strings in an array and returns the index at which the Strings
   * begin to differ.
   * </p>
   *
   * <p>
   * For example,
   * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code>
   * </p>
   *
   * <pre>
   * indexOfDifference(null) = -1
   * indexOfDifference(new String[] {}) = -1
   * indexOfDifference(new String[] {"abc"}) = -1
   * indexOfDifference(new String[] {null, null}) = -1
   * indexOfDifference(new String[] {"", ""}) = -1
   * indexOfDifference(new String[] {"", null}) = 0
   * indexOfDifference(new String[] {"abc", null, null}) = 0
   * indexOfDifference(new String[] {null, null, "abc"}) = 0
   * indexOfDifference(new String[] {"", "abc"}) = 0
   * indexOfDifference(new String[] {"abc", ""}) = 0
   * indexOfDifference(new String[] {"abc", "abc"}) = -1
   * indexOfDifference(new String[] {"abc", "a"}) = 1
   * indexOfDifference(new String[] {"ab", "abxyz"}) = 2
   * indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
   * indexOfDifference(new String[] {"abcde", "xyz"}) = 0
   * indexOfDifference(new String[] {"xyz", "abcde"}) = 0
   * indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
   * </pre>
   *
   * @param strs
   *          array of strings, entries may be null
   * @return the index where the strings begin to differ; -1 if they are all equal
   * @since 2.4
   */
  public static int indexOfDifference(String[] strs) {
    if (strs == null || strs.length <= 1) {
      return -1;
    }
    boolean anyStringNull = false;
    boolean allStringsNull = true;
    int arrayLen = strs.length;
    int shortestStrLen = Integer.MAX_VALUE;
    int longestStrLen = 0;

    // find the min and max string lengths; this avoids checking to make
    // sure we are not exceeding the length of the string each time through
    // the bottom loop.
    for (int i = 0; i < arrayLen; i++) {
      if (strs[i] == null) {
        anyStringNull = true;
        shortestStrLen = 0;
      } else {
        allStringsNull = false;
        shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
        longestStrLen = Math.max(strs[i].length(), longestStrLen);
      }
    }

    // handle lists containing all nulls or all empty strings
    if (allStringsNull || (longestStrLen == 0 && !anyStringNull)) {
      return -1;
    }

    // handle lists containing some nulls or some empty strings
    if (shortestStrLen == 0) {
      return 0;
    }

    // find the position with the first difference across all strings
    int firstDiff = -1;
    for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
      char comparisonChar = strs[0].charAt(stringPos);
      for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
        if (strs[arrayPos].charAt(stringPos) != comparisonChar) {
          firstDiff = stringPos;
          break;
        }
      }
      if (firstDiff != -1) {
        break;
      }
    }

    if (firstDiff == -1 && shortestStrLen != longestStrLen) {
      // we compared all of the characters up to the length of the
      // shortest string and didn't find a match, but the string lengths
      // vary, so return the length of the shortest string.
      return shortestStrLen;
    }
    return firstDiff;
  }

}

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



PreviousNext

Related