java怎么检查句子里的一个词是不是包含在arraylist里

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java怎么检查句子里的一个词是不是包含在arraylist里相关的知识,希望对你有一定的参考价值。

我在做一个聊天机器人 目标是检测一个句子里是否包含了arraylist的一个词然后返回这个词

假设 你有一个String a, 有一个ArrayList list; 判断 list是否存在a

你可以 直接使用 boolean exist=list.contains(a); 根据这个来判断就可以了。

顺便说下,你的词是用ArrayList来保存的,这里面你 用 contains 来判断这个集合里是否包含这个字符串。 你可以用 Set来保存那些需要判断的关键字,Set的cantains的效率比ArrayList的效率要高些。追问

我想查的是string A这一段话里是否包含了arraylist里的成员 不是arraylist是否包含了A

追答

这个逻辑是一样的,你把String A 按照 空格切分 A.split(" ") 切分成 一个单词数组,然后数组里的把每个单词 用list.contains 方法调用下,就可以了。当然你也把单词数组转换成List对象,然后取两个List的交集就可以了。String A 是一个 单词组成的字符串,List是一个单词的集合,你需要的是 这两个里面是否有相同单词的交集。你可以把A中的每个单词去List查找是否有,也可以把List里面的每个单词去A中查找,看A是否包含,这两个的逻辑实际上是一样的。

追问

我用空格split为什么的出的结果只有第一个单词呀

参考技术A 二分查找?追问

我想查的是string A这一段话里是否包含了arraylist里的成员 能不能详细说明

检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符

【中文标题】检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符【英文标题】:Checking a String (sentence space separated) to see if it contains any of the chars in an array检查字符串(句子空格分隔)以查看它是否包含数组中的任何字符 【发布时间】:2022-01-17 16:14:52 【问题描述】:

我一直在尝试看看是否有办法通过双循环来解决这个问题。循环遍历数组中的每个单词并检查提供的所有字符是否都存在于该单词中。

键盘损坏问题:

输入 A =“你好,我亲爱的朋友!”

输入 B = ['h', 'e', 'l, 'o', 'm']

我们这里的键盘坏了,其中只有列表 B 中的字母键(小写和大写)、数字键和标点键起作用。

编写一个函数,它接受一个字符串 A 和一个字符 B 的列表,并返回我们可以输入多少个单词。

解释 输入:A “你好,我亲爱的朋友!”,B = ['h', 'e', 'l, 'o', 'm'] 输出:1

解释:对于第一个单词“Hello”(包括逗号),我们可以找到列表 B 中的每个字符。 由于所有标点键都可以正常工作,所以输出++。

对于第二个单词“my”,我们只能在列表 B 中找到 char 'm',因此无法输入整个单词。然后同样,“亲爱的”,找不到char 'd',所以继续; “朋友!”,找不到字符'f',所以继续;

这是我迄今为止尝试过的,但我不能使用 String 的 .contain() 方法,因为它只接受 char 序列而不是 char 数组。如何使用 JAVA 检查每个单词的字符数组?

提前致谢,感谢任何支持。

    public class BrokenKeyboard


   public static void main(String[] args)
   
      String stringText = "Hello my dear friend";
      char [] charLetterArray = 'h', 'e', 'l', 'o', 'm';

      howManyWordsCalc(stringText, charLetterArray);
   

   // Only words from stringText that can be typed in whole should be printed.
   // If the letters present in the word aren't present in charLetterArray they don't get printed
   public static int howManyWordsCalc(String text, char[] letters)
   
      int wordCount = 0;
      // sanitise input
      if (text.isEmpty())
      
         return 0;
      
      else
      
         text = text.toLowerCase();
         String[] stringSeparated = text.split(" ");

         for (int i = 0; i < stringSeparated.length; i++)
         
            System.out.println(stringSeparated[i]);

            for (int j = 0; j < letters.length; j++)
            
               // stringSeparated[i].contains(letters)
               if (stringSeparated[i].contains())
               
                  wordCount++;

               
            
         
         return wordCount;
      
   


【问题讨论】:

可以将char转成字符串String.contains(Character.toString(c)) 【参考方案1】:

这是一个示例解决方案:

public class Main

   public static void main(String[] args)
      String stringText = "Hello my dear friend";
      char [] charLetterArray = 'h', 'e', 'l', 'o', 'm';
      System.out.println(howManyWordsCalc(stringText, charLetterArray));
   

   // Only words from stringText that can be typed in whole should be printed.
   // If the letters present in the word aren't present in charLetterArray they don't get printed
   public static int howManyWordsCalc(String text, char[] letters)
      int wordCount = 0;
      // sanitise input
      if (text.isEmpty())
         return 0;
      
      else
         text = text.toLowerCase();
         String[] stringSeparated = text.split(" ");

         for (int i = 0; i < stringSeparated.length; i++)
            int validLetters = 0;
            for(int j = 0; j < stringSeparated[i].length(); j++)
              for(char c: letters)
                if(c == stringSeparated[i].charAt(j))
                  validLetters++;
                  break;
                
              
            
            if(validLetters == stringSeparated[i].length())
              wordCount++;
            
         
         return wordCount;
      
   


此代码的工作方式与您的完全相同,除了用于检查单词是否可以由可用字母组成的算法。

我首先遍历数组中每个单词的算法。然后,我创建了一个名为 validLetters 的整数,我们将在其中检查我们可以输入的单词中有多少个字母。如果validLetters的个数等于单词的长度,那么就可以输入单词了。

为了检查一个字母是否可以输入,我们将遍历单词中的每个字母,并查看它是否在数组 letters 内。如果是,我们增加validLetters并退出循环。

或者,如果您想在两个 for 循环中严格执行此操作,这是一个缩短版本:

import java.util.*;
public class Main

   public static void main(String[] args)
      String stringText = "Hello my dear friend";
      char [] charLetterArray = 'h', 'e', 'l', 'o', 'm';
      System.out.println(howManyWordsCalc(stringText, charLetterArray));
   

   // Only words from stringText that can be typed in whole should be printed.
   // If the letters present in the word aren't present in charLetterArray they don't get printed
   public static int howManyWordsCalc(String text, char[] letters)
      int wordCount = 0;
      // sanitise input
      if (text.isEmpty())
         return 0;
      
      else
         text = text.toLowerCase();
         String[] stringSeparated = text.split(" ");

         for (int i = 0; i < stringSeparated.length; i++)
            int validLetters = 0;
            for(int j = 0; j < stringSeparated[i].length(); j++)
              if (new String(letters).indexOf(stringSeparated[i].charAt(j)) != -1) 
                 validLetters++;
              
            
            if(validLetters == stringSeparated[i].length())
              wordCount++;
            
         
         return wordCount;
      
   


如果您有任何问题/澄清,请告诉我!

【讨论】:

太好了,非常感谢。两种解决方案都很棒,我更喜欢您的第二种解决方案。 if (new String(letters).indexOf(stringSeparated[i].charAt(j)) != -1) 在上面的行中,结果可能是-1 吗?? 如果字母不在单词中,那么语句将为-1。如果这是真的,那么 validLetters 的值将不会增加,因此永远不会达到单词的长度并且永远不会更新 wordCount。 是的,当然。再次感谢:) np 很乐意提供帮助【参考方案2】:

我稍微改了一下,看看:

public static void wordCalc(String input, char[] chars) 
    String[] inputWords = input.toLowerCase().split(" ");

    boolean[] allLetters = new boolean[26];
    for(int i=0; i<chars.length; i++) 
        allLetters[chars[i] - 'a'] = true;
    

    int wordCount = 0;
    for(String word : inputWords) 
        boolean isWordPossible = true;
        for(int i=0; i<word.length(); i++)
            if(!allLetters[word.charAt(i) - 'a'])
                isWordPossible = false;
                break;
            
        

        if(isWordPossible) 
            System.out.println("word " + word + " is possible");
            wordCount++;
        
    

    System.out.println(wordCount);

我曾经在互联网上发现了这个非常巧妙的技巧。将允许的字母存储在布尔数组中。这样,当您想检查是否允许使用 char 时,您只需检查与该字符对应的索引处的数组值!

然而,这确实让我注意到了一个重要的注意事项。字符存储为整数,这就是为什么你可以来回转换它们并做一些时髦的东西,比如word.charAt(i) - 'a'(这会给你在布尔数组中的位置,因为它会给你字母“a”和任何东西之间的距离字母在单词中的位置“i”)。

字符串最终是 char 数组。所以你可以这样做:

char[] stuff = someString.toCharArray();

同样重要的是要注意字符串是不可变的,字符串字面量指向同一个对象。

关于时间复杂度的最后说明,最好尽可能避免嵌套循环。如果你有大量的输入,它会变得非常慢!如果你有一个循环,它是 O(n) 时间,2 个循环它已经是 O(n^2),就时间复杂度而言,这是相当慢的。但是,对于这种情况,我想不出另一种方法。您使用的结构和访问方法会极大地影响性能。我想你会非常喜欢HashSets,尤其是对于这个允许的字符是唯一的问题。

【讨论】:

非常感谢,我从未见过布尔数组。我也很欣赏大 O 参考。是的,也许在这里创建一个哈希集是有益的。【参考方案3】:

您可以通过使用另一个循环(实际上与String::contains 具有相同的复杂性)来检查单词中的所有字符是否包含在letters 字符数组中。

另外,我建议通过使用[\pZ\pP]+ 正则表达式拆分重复的标点符号和/或空白字符来获取单词,其中\pZ 代表空格,\pP 代表标点符号。

public static int howManyWordsCalc(String text, char[] letters) 
    int wordCount = 0;
    
    String[] words = text.toLowerCase().split("[\\pP\\pZ]+");
    
    for (String word : words) 
        // System.out.print("'" + word + "'\t");
        boolean allFound = true;
        for (char c : word.toCharArray()) 
            boolean found = false;
            for (char letter : letters) 
                if (c == letter) 
                    found = true;
                    break;
                
            
            if (!found) 
                // System.out.println("not found letter: " + c + " in word " + word);
                allFound = false;
                break;
            
        
        if (allFound) 
            wordCount++;
            // System.out.println("all found");
        
    
    return wordCount;
    

测试:

System.out.println(howManyWordsCalc(
    "Hello, my dear friend!", new char[] 'h', 'e', 'l', 'o', 'm', 'y'
));

输出(启用调试打印):

'hello' all found
'my'    all found
'dear'  not found letter: d in word dear
'friend'    not found letter: f in word friend
2

【讨论】:

String[] words = text.toLowerCase().split("[\\pP\\pZ]+"); 太棒了,多么巧妙的把戏【参考方案4】:

我在 c# 中尝试过相同的方法,但您也可以使用 HashSet 集合并尝试相同的方法。 Java HashSet 也有 Contains()。

我希望这会有所帮助。

class Program

    static void Main(string[] args)
    
        string a = "Hello, my dear friend!";
        string A = a.ToUpper();
        string[] seperate = A.Split(new Char[]  ' ', ',', '.', '-', '\n', '\t', '!' );
        HashSet<Char> hash = new HashSet<char>();
        hash.Add('H');
        hash.Add('E');
        hash.Add('L');
        hash.Add('O');
        hash.Add('M');
        int count = 0;
        bool flag = true;
        foreach (var w in seperate)
        
            if (w.Length > 0)  
                Char[] ca = w.ToCharArray();
                foreach (var d in ca)
                
                    if(!hash.Contains(d))
                    
                        flag = false;
                        break;
                    
                
                if(flag)
                
                    flag = true;
                    count++;
                
            
        
        Console.WriteLine("Count : " + count);
        Console.Read();
    

【讨论】:

以上是关于java怎么检查句子里的一个词是不是包含在arraylist里的主要内容,如果未能解决你的问题,请参考以下文章

在python怎么样把输入的txt文件里的句子分成词

检查句子是不是包含某些单词

检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符

使用 Java Regex,如何检查字符串是不是包含集合中的任何单词?

检查一个词是不是是另一个词的子字谜(Java)

java 检查是否数字