给定一个字符串列表和一个字符数组,返回仅包含数组中字符的最长字符串。
我很确定我把它搞砸了。我的第一直觉是使用正则表达式,但我认为没有人在第一次得到正确的东西而且没有任何查找。
使用按位运算符或其他方法是否有一种棘手的方法?
答案 0 :(得分:3)
一个想法是将char[]
转换为Set<Character>
进行O(1)包含测试,然后简单地循环遍历字符串列表并检查每个特定字符串是否只包含在上述设置,跟踪您使用此属性找到的最长字符串。
如果您有更多信息,可以进行更多优化。例如,如果字符串本身很长但列表不是很长,那么首先按长度排序列表然后开始最长处理字符串可能是有益的。
使用按位运算符或其他方法是否有一种棘手的方法?
如果您对char[]
中可包含的字符范围有某种(小小)限制,那么您可以将整个内容编码为一个int
/ { {1}},它可以替代我上面提到的long
。例如,假设只包含Set<Character>
到'a'
中的字符,那么我们可以按如下方式执行编码:
'z'
现在,要检查原始long charset = 0;
for (char c : chars) {
charset |= (1 << (c - 'a'));
}
中是否包含某些字符c
,我们只需使用:
char[]
答案 1 :(得分:2)
如果char[]
中存在字符串的所有字符,则以下代码在已排序的char数组上使用二进制搜索来有效地检查。请注意,由于缓存局部性,对数组的二进制搜索非常快。
public String longest(char[] chars, List<String> strings) {
char[] sorted = Arrays.copyOf(chars, chars.length);
Arrays.sort(sorted);
String result = null;
for (String string : strings) {
if (containsAll(sorted, string)
&& (result == null || string.length() > result.length())) {
result = string;
}
}
return result;
}
public boolean containsAll(char[] sorted, String string) {
int length = string.length();
for (int i = 0; i < length; ++i) {
if (Arrays.binarySearch(sorted, string.charAt(i)) < 0) {
return false;
}
}
return true;
}
答案 2 :(得分:0)
如果您被允许使用Java 8:
public static Optional<String> longestValidWord(List<String> words, char[] validCharacters){
String allValidCharacters = new String(validCharacters);
return words.stream()
.filter(word -> word.chars().allMatch(c -> allValidCharacters.indexOf(c) > -1))
.max((s1, s2) -> Integer.compare(s1.length(), s2.length()));
}
答案 3 :(得分:0)
/**
* @param list List of Strings.
* @param array Array of characters.
* @return The longest String from list that contains only characters in the array.
* If there is no such String, "" will be returned.
*/
private static String getLongest(List<String> list, Character[] array) {
String longest = "";
if (list == null || list.isEmpty() || array == null
|| array.length == 0) {
return longest;
}
Set<Character> set = new HashSet<Character>(Arrays.asList(array));
for (String word : list) {
boolean valid = true;
for (Character c : word.toCharArray()) {
if (!set.contains(c)) {
valid = false;
break;
}
}
if (valid && longest.length() < word.length()) {
longest = word;
}
}
return longest;
}