Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
棘手的Java字符串采访问题。给定列表<;字符串>;和char[]返回仅包含char[]的最长字符串_Java_String_Algorithm_List_Char - Fatal编程技术网

棘手的Java字符串采访问题。给定列表<;字符串>;和char[]返回仅包含char[]的最长字符串

棘手的Java字符串采访问题。给定列表<;字符串>;和char[]返回仅包含char[]的最长字符串,java,string,algorithm,list,char,Java,String,Algorithm,List,Char,给定字符串列表和字符数组,返回数组中仅包含字符的最长字符串 我敢肯定是我用水管冲洗的。我的第一反应是使用正则表达式,但我不认为任何人在没有任何查找的情况下第一次就正确地使用了正则表达式 有没有一种巧妙的方法可以使用位运算符之类的东西来实现这一点 一个想法是将char[]转换为一个集合,用于O(1)包容测试,然后简单地循环字符串列表,检查每个特定字符串是否仅包含在上述集合中的字符,跟踪使用此属性找到的最长字符串 如果你有更多的信息,你可以做更多的优化。例如,如果字符串本身很长,但列表不长,那么最好

给定字符串列表和字符数组,返回数组中仅包含字符的最长字符串

我敢肯定是我用水管冲洗的。我的第一反应是使用正则表达式,但我不认为任何人在没有任何查找的情况下第一次就正确地使用了正则表达式


有没有一种巧妙的方法可以使用位运算符之类的东西来实现这一点

一个想法是将
char[]
转换为一个
集合
,用于O(1)包容测试,然后简单地循环字符串列表,检查每个特定字符串是否仅包含在上述集合中的字符,跟踪使用此属性找到的最长字符串

如果你有更多的信息,你可以做更多的优化。例如,如果字符串本身很长,但列表不长,那么最好先按长度对列表排序,然后开始处理最长的字符串


有没有一种巧妙的方法可以使用位运算符之类的东西来实现这一点

如果您对
char[]
中可以包含的字符范围有某种(小的)限制,那么您可以在单个
int
/
long
中对整个内容进行编码,这将替代我上面提到的
集合。例如,假设只包含从
'a'
'z'
的字符,那么我们可以按如下方式执行编码:

long charset = 0;

for (char c : chars) {
    charset |= (1 << (c - 'a'));
}

如果允许您使用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()));
}
public静态可选longestValidWord(列出单词,字符[]有效字符){
String allValidCharacters=新字符串(validCharacters);
返回words.stream()
.filter(word->word.chars().allMatch(c->allValidCharacters.indexOf(c)>-1))
.max((s1,s2)->Integer.compare(s1.length(),s2.length());
}

以下代码使用排序字符数组上的二进制搜索来有效地检查字符串的所有字符是否都存在于
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;
}
公共字符串最长(字符[]个字符,列表字符串){
char[]sorted=Arrays.copyOf(chars,chars.length);
数组。排序(已排序);
字符串结果=null;
for(字符串:字符串){
if(containsAll(已排序,字符串)
&&(result==null | | string.length()>result.length()){
结果=字符串;
}
}
返回结果;
}
公共布尔containsAll(字符[]排序,字符串){
int length=string.length();
对于(int i=0;i
实施:

/**
 * @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;
}
/**
*@param-list字符串列表。
*@param字符数组。
*@返回列表中仅包含数组中字符的最长字符串。
*如果没有这样的字符串,将返回“”。
*/
私有静态字符串getLongest(列表,字符[]数组){
字符串最长=”;
if(list==null | | list.isEmpty()| |数组==null
||array.length==0){
返回时间最长;
}
Set=newhashset(Arrays.asList(array));
for(字符串字:列表){
布尔有效=真;
for(字符c:word.toCharArray()){
如果(!set.contains(c)){
有效=错误;
打破
}
}
if(有效&&longest.length()
我能想到的最简单的解决方案是2个嵌套的循环show large是字符串列表吗?每个单词平均有多长?在你尝试变得聪明并意识到暴力强迫没有错之前,你可以问这些问题和许多其他问题。我确实使用了暴力,即双循环。这是一个来自常春藤联盟的Q。它位于西雅图地区,因此我认为它比这更复杂。结果字符串是否可以包含字符数组中的重复字符?我建议使用两种方法之一:1)将
char[]
转换为一组字符,从而得到O(n)解;2) 排序
char[]
并使用二进制搜索,从而得到O(n log m)解决方案。这显然更像我认为我们正在寻找的。这里有一个优化,如果char[]比字符串长,则跳过它。@user447607:如果
char[]
包含重复项,则这不起作用。True。不幸的是,我不想问,所以我不知道它是否有效。再想想,我认为它确实有效,只是不能保证选择了哪一个副本。。。但这无关紧要。如果它在那里,它就在那里。我还没有机会使用Java 8,所以我不可能想到这个。这意味着至少复制N个字符,其中N=字符数组的长度。它还意味着实例化N个Char对象包装器,以便将它们放置在一个集合中。。。这是在你考虑在排序过程中复制的时候。至于按位操作,与其他解决方案相比,这似乎有点棘手。考虑到我最近遇到的一些其他问题,这是一个好主意。@user447607好吧,你的问题没有限制N可以是什么,那么我如何才能在我的答案中考虑到这一点呢?假设N不是很大,在这种情况下,我描述的预处理阶段应该非常便宜,并且在节省时间方面非常有益。关于您评论的第二部分,我认为
long
编码在许多方面比
Set
解决方案简单(假设您的情况允许)。我不知道我怎么可能知道一个解决方案是否“棘手”(正如你所要求的),但不是“太棘手”。我同意这一点实际上是没有意义的,因为我
/**
 * @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;
}