Подсчет слов из массива в строке

1

У меня есть массив строк.

A=["hello", "you"]

У меня есть строка, скажем

s="hello, hello you are so wonderful"

Мне нужно подсчитать количество вхождений строк из A в s. В этом случае число вхождений равно 3 (2 "hello", 1 "you").

Как это сделать эффективно? (A может содержать много слов, и s может быть длительным на практике)

  • 1
    Можете ли вы показать нам, что вы пытались?
  • 3
    перебирать массив, для каждого слова подсчитывать вхождения
Теги:
algorithm

7 ответов

1
Лучший ответ
public void countMatches() {
    String[] A = {"hello", "you"};
    String s = "hello, hello you are so wonderful";
    String patternString = "(" + StringUtils.join(A, "|")   + ")";
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(s);
    int count = 0;
    while (matcher.find()) {
        count++;
    }
    System.out.println(count);
}

Обратите внимание, что StringUtils - от apache commons. Если вы не хотите включать и добавить банку, вы можете просто построить эту строку, используя цикл for.

  • 1
    В Java 8 вы можете сказать String.join ("|",A) . Больше нет необходимости в Apache Commons.
  • 1
    PS Я бы добавил "\\b" к обеим сторонам patternString , в зависимости от точных требований.
Показать ещё 2 комментария
2

Пытаться:

Map<String, Integer> wordCount = new HashMap<>();
for(String a : dictionnary) {
    wordCount.put(a, 0);
}
for(String s : text.split("\\s+")) {
    Integer count = wordCount.get(s);
    if(count != null) {
        wordCount.put(s, count + 1);
    }
}
1
HashSet<String> searchWords = new HashSet<String>();

for(String a : dictionary) {
    searchWords.add(a);
}

int count = 0;

for(String s : input.split("[ ,]")) {
    if(searchWords.contains(s)) {
       count++;
    }
}
  • 0
    Вероятно, должно быть "[ ,]+" , то есть разделить на запятую последовательность длиной один или несколько . Но ваш путь просто помещает лишние пустые строки в массив результатов, что безвредно.
  • 0
    Мне нравится это решение, так как (1) t может разбить строку на некоторые разделители по нашему выбору, и (2) сложность почти равна O (n)
Показать ещё 1 комментарий
1
int count =0;
for(int i=0;i<A.length;i++)
{
  count = count + s.split(A[i],-1).length - 1;
}

Рабочий идеон: http://ideone.com/Z9K3JX

0

Вот что я придумал:

Он не создает никаких новых объектов. Он использует String.indexOf(String, int), отслеживает текущий индекс и увеличивает счетчик occount-count.

public class SearchWordCount  {
   public static final void main(String[] ignored)  {
      String[] searchWords = {"hello", "you"};
      String input = "hello, hello you are so wonderful";

      for(int i = 0; i < searchWords.length; i++)  {
         String searchWord = searchWords[i];

         System.out.print(searchWord + ": ");

         int foundCount = 0;
         int currIdx = 0;
         while(currIdx != -1)  {
            currIdx = input.indexOf(searchWord, currIdx);

            if(currIdx != -1)  {
               foundCount++;
               currIdx += searchWord.length();
            }  else  {
               currIdx = -1;
            }
         }

         System.out.println(foundCount);

      }
   }
}

Вывод:

hello: 2
you: 1
0

Это полностью рабочий метод с выходом :)

public static void main(String[] args) {
    String[] A={"hello", "you"};
    String s= "hello, hello you are so wonderful";
    int[] count = new int[A.length];
    for (int i = 0; i < A.length; i++) {
        count[i] = (s.length() - s.replaceAll(A[i], "").length())/A[i].length();
    }

    for (int i = 0; i < count.length; i++) {
        System.out.println(A[i] + ": " + count[i]);
    }
}

Что делает эта линия?

count[i] = (s.length() - s.replaceAll(A[i], "").length())/A[i].length();

Эта часть s.replaceAll(A[i], "") изменяет все "привет" на пустую строку "" в тексте.

Поэтому я беру длину всего s.length() Я вычитаю из нее длину одной и той же строки без этого слова s.replaceAll(A[i], "").length() и я делю его на длину этого слова /A[i].length()


Пример вывода для этого примера:

hello: 2
you: 1
0

Вы можете использовать строковый токенизатор

Сделайте что-то вроде этого:

A = ["hello", "you"];
s = "hello, hello you are so wonderful";
StringTokenizer st = new StringTokenizer(s);
    while (st.hasMoreElements()) {
        for (String i: A) {
            if(st.nextToken() == i){
                //You can keep going from here
            }
        }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню