import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 求N个字符串中的最大公子串 思路:先找出字符串中最短的那个字符串,然后依次取出最短字符串中的每个字符与其余字符串进行比较。
 */
public class ShortString {
	// 定义字符串的比较器(根据长度比较)
	private class LengthComparator implements Comparator<String> {
		@Override
		public int compare(String str1, String str2) {
			if (str1.length() < str2.length())
				return -1;
			else if (str1.length() == str2.length())
				return 0;
			else if (str1.length() > str2.length())
				return 1;
			return 0;
		}
	}

	// 字符串列表中的最短字符串
	public String minStr(Collection<String> strings) {
		return Collections.min(strings, new LengthComparator());
	}

	// 判断字符串列表中的每个字符串是否包含指定字符串,如果有一个不包含就返回false
	public boolean contains(ArrayList<String> strings, String str) {
		for (String s : strings) {
			if (!s.contains(str))
				return false;
		}
		return true;
	}

	// 最短公共字符串
	public String maxSubString(ArrayList<String> strings) {
		String maxStr = "";// 最长公子串
		String tempStr = "";// 临时变量
		String minStr = minStr(strings);// 所有字符串中的最短字符串
		/**
		 * 思路:
		 * 1.先获得所有字符串中的最短的字符串
		 * 2.然后截取最短字符串(从长到短),例如abcd,截取顺序abcd,abc,ab,a,bcd,bc,b,cd,c,d
		 * 3.将截取后的最短字符串与列表中的所有字符串比较
		 */
		for (int i = 0; i < minStr.length(); i++) {
			//如果最所剩字符数小于最长公子串长度,就直接进入跳出循环。
			//	例如:minStr ="abcd",maxStr="ab";那么就没有必要再遍历cd及cd的子串了
			if (maxStr.length() < minStr.length() - i) {
				for (int j = minStr.length(); j >= i; j--) {
					tempStr = minStr.substring(i, j);
					//如果截取的临时字符串长度 <= 最长公子串的长度,就没有必要再执行循环了,因为接下来的循环只能使临时字符串越来越短
					if (tempStr.length() <= maxStr.length())
						break;//结束内循环,跳到外循环
					if (contains(strings, tempStr)) {
						if (tempStr.length() > maxStr.length()) {
							maxStr = tempStr;
						}
					}
				}
			}else 
				break;
		}
		return maxStr;
	}

	public static void main(String[] args) {
		ArrayList<String> strings = new ArrayList<String>(Arrays.asList(
				"abdfdfabf", "abcabdeftdsfgsdg","abdcdefsdf"));
		ShortString ss = new ShortString();
		System.out.println("字符串列表:" + strings);
		System.out.println("最短字符串:" + ss.minStr(strings));
		System.out.println("最长公子串:" + ss.maxSubString(strings));
	}
}