每次字符串与我的字符串数组中的元素匹配时,尝试向变量添加计数

Posted

技术标签:

【中文标题】每次字符串与我的字符串数组中的元素匹配时,尝试向变量添加计数【英文标题】:Trying to add a count to a variable everytime a string matches an element in my string array 【发布时间】:2021-08-30 00:33:48 【问题描述】:

所以,我有一个字符串数组。例如,[test, exam, quiz] 我们将其称为cat 以防止误解。我也有一个字符串。例如,String school = "We have a test and a quiz next week"。我正在检查字符串school 以查看它是否包含/匹配字符串数组[test, exam, quiz]。但是,我想跟踪计数变量中发生了多少匹配。我一直无法弄清楚如何为每场比赛添加一个计数。例如,根据构建的场景,字符串数组中应该有两个匹配的三个。

这是我的代码:

int i = 0;

for (String s : cat) 
    if (school.contains(s)) 
        match = true;
        i++;
        break;
    

此代码的输出仅给出 1,即使字符串 school 包含测试和测验。我希望它给两个。

非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

你所要做的就是:

    将给定的school 拆分为单独的单词; 使用filter()过滤出需要的词; 计算流中的元素。
String school = "We have a test and a quiz next week test";
String[] cat =  "test", "exam", "quiz" ;
Set<String> words = Arrays.stream(cat).collect(Collectors.toSet());
long count = Arrays.stream(school.split("\\s+"))
                   .filter(words::contains)
                   .count();

【讨论】:

这是一个不错的解决方案 这个答案有一个问题:由于它是基于集合的,因此它将删除所有重复项。因此,如果一个关键字在输入句子中出现多次,则计数永远不会大于一。 @TimBiegeleisen 是的,你是对的。我错过了这个案子。【参考方案2】:

break 将在第一次匹配后停止 for 循环。这就是你得到i = 1的原因;

int i = 0;
for (String s: cat) 
  if (school.contains(s)) 
      match=true;
      i++;
      break; // This break will stop the for loop iteration after the first match.
    

为了满足您的两个要求,您可以将代码修改为以下内容。

String school = "We have a test and a quiz next week";
String[] cat = "test", "exam", "quiz";
int i = 0;
boolean match = false;
for (String s : cat) 
  if (school.contains(s)) 
     match = true;
     i++;
  

System.out.println(match ? "found " + i + " matches." : "not found any match");

但此代码中存在一个问题,因为如果同一文本有多个匹配项,它仍将计为 1 个匹配项。示例假设school 字符串中有两个test,您仍将计数为1。

【讨论】:

是的。这似乎是我在上面创建的简单循环函数的问题。我想提高效率,这就是我寻找这种方式来解决我给定难题的原因。【参考方案3】:

一种方法使用交替的搜索词以及正式的正则表达式模式匹配器:

String[] cat = new String[] "test", "exam", "quiz";
StringBuilder regex = new StringBuilder("\\b(?:");
for (int i=0; i < cat.length; ++i) 
    if (i > 0) regex.append("|");
    regex.append(cat[i]);

regex.append(")\\b");

String school = "We have a test and a quiz next week";
Pattern r = Pattern.compile(regex.toString());
Matcher m = r.matcher(school);
int count = 0;

while (m.find()) 
    ++count;


System.out.println("found " + count + " matches.");  // found 2 matches.

在这里要清楚,我们对输入句子使用的正则表达式模式是:

\b(?:test|exam|quiz)\b

我们遍历输入的句子,每次点击一个关键字,计数器就加一。

【讨论】:

【参考方案4】:

结果是 1,因为您在 if 条件中添加了一个 break 语句,这使它在找到第一个匹配项时退出循环,而不是您应该这样写

int i=0;
   for (String s: cat)
      if(school.contains(s))
         match=true;
         i++;
        
      

【讨论】:

如果输入句子碰巧有一个关键字more不止一次,那么你的String#contains逻辑仍然只会计算一次匹配。【参考方案5】:

您可以在 java 中使用 Hastable:(如果输入句子碰巧有一个关键字不止一次,那么您的 String#contains 逻辑仍然只会计算一次匹配)

import java.util.Hashtable;
public class Main

    public static void main(String[] args) 
    
    String school = "We have a test and a quiz next week";
    String cat[] = new String[]"test", "exam", "quiz";
    Hashtable<String, Integer> my_dict = new Hashtable<String, Integer>();
    int count=0; // variable should be named such that it is understandable the purpose of it
    for (String s: cat)
      if(school.contains(s))
         if(!my_dict.containsKey(s))
             my_dict.put(s, 1);
             count++;
         
         //else //don't need else in your case
        
      
      System.out.println( "Occurance: " + count );
    

如果您需要在一个句子中多次计数相同的字符串单词,那么只需删除 Hashtable 以及 Hashtable 的条件如下:

 int count=0; // variable should be named such that it is understandable the purpose of it
    for (String s: cat)
      if(school.contains(s))
             count++;
        
      
System.out.println( "Occurance: " + count );

【讨论】:

这不会计算多次出现 是的。我已经提到过。 “如果输入句子碰巧有一个关键字不止一次,那么你的 String#contains 逻辑仍然只会计算一个匹配”。如果您需要多个计数,则只需删除字典/哈希表

以上是关于每次字符串与我的字符串数组中的元素匹配时,尝试向变量添加计数的主要内容,如果未能解决你的问题,请参考以下文章

jQuery - 如果值与数组中的元素匹配,则禁用复选框

MongoDB计数按数组元素分组的数组中的匹配字符串

努力将正则表达式与我的字符串匹配

JS中如何判断一个字符串是一个字符串数组中的一个元素!!?

如何计算与我的 CSS 选择器匹配的元素数量?

无法重新加载 UITableView