Простой способ подсчета символов в строке

Есть ли простой способ (вместо того, чтобы вручную перемещать всю строку или цикл для indexOf), чтобы узнать, сколько раз символ появляется в строке?

Скажем, у нас есть «abdsd3 $ asda $ asasdd $ sadas», и мы хотим, чтобы $ появился 3 раза.

String s = "..."; int counter = 0; for( int i=0; i 

Это, безусловно, самый быстрый способ. Регулярные выражения здесь намного медленнее, и их становится все труднее понять.

Функциональный стиль (Java 8, просто для удовольствия):

 str.chars().filter(num -> num == '$').count() 

Не оптимальный, но простой способ подсчета случаев:

 String s = "..."; int counter = s.split("\\$", -1).length - 1; 

Заметка:

  • Знак доллара – это специальный символ регулярного выражения, поэтому он должен быть экранирован с помощью обратного слэша.
  • Обратная косая черта – это специальный символ для escape-символов, таких как символы новой строки, поэтому он должен быть экранирован с помощью обратного слэша.
  • Второй аргумент split предотвращает удаление пустых строк.

Вы можете использовать StringUtils.countMatches(String string, String subStringToCount) Apache Commons StringUtils.countMatches(String string, String subStringToCount) .

Так как вы все-таки сканируете всю строку, вы можете построить полный счетчик символов и сделать любое количество запросов, все для одной и той же большой стоимости (n):

 public static Map getCharFreq(String s) { Map charFreq = new HashMap(); if (s != null) { for (Character c : s.toCharArray()) { Integer count = charFreq.get(c); int newCount = (count==null ? 1 : count+1); charFreq.put(c, newCount); } } return charFreq; } // ... String s = "abdsd3$asda$asasdd$sadas"; Map counts = getCharFreq(s); counts.get('$'); // => 3 counts.get('a'); // => 7 counts.get('s'); // => 6 

Частота частоты символов является общей задачей для некоторых приложений (например, образования), но не достаточно общей, чтобы гарантировать включение в основные Java-API. Таким образом, вам, вероятно, придется написать свою собственную функцию.

вы также можете использовать a для каждого цикла. Я думаю, что это проще читать.

 int occurrences = 0; for(char c : yourString.toCharArray()){ if(c == '$'){ occurrences++; } } 

Перемещение строки, вероятно, является наиболее эффективным, хотя использование Regex для этого может привести к созданию более чистого кода (хотя вы всегда можете скрыть свой обратный код в функции).

Для этого существует множество различных утилит, например Apache Commons Lang String Utils

но, в конце концов, он должен перебирать строку, чтобы считать события так или иначе.

Обратите внимание также, что метод countMatches выше имеет следующую подпись, поэтому будет работать и под подстроками.

public static int countMatches(String str, String sub)

Источником этого является ( отсюда ):

 public static int countMatches(String str, String sub) { if (isEmpty(str) || isEmpty(sub)) { return 0; } int count = 0; int idx = 0; while ((idx = str.indexOf(sub, idx)) != -1) { count++; idx += sub.length(); } return count; } 

Мне было любопытно, если они повторяют строку или используют Regex.

Я считаю, что «один лайнер», который вы ожидали получить, таков:

 "abdsd3$asda$asasdd$sadas".replaceAll( "[^$]*($)?", "$1" ).length(); 

Помните, что требования:

( вместо того, чтобы вручную перемещать всю строку или цикл для indexOf )

и позвольте мне добавить: что в основе этого вопроса звучит так: «любая петля» не нужна, и нет необходимости в скорости. Я считаю, что подтекстом этого вопроса является фактор прохлады .

Что-то более функциональное, без Regex:

 public static int count(String s, char c) { return s.length()==0 ? 0 : (s.charAt(0)==c ? 1 : 0) + count(s.substring(1),c); } 

Для ясности это не хвост рекурсивный.

Вы можете посмотреть сортировку строки – рассматривать ее как массив символов – и затем выполнить модифицированный двоичный поиск, который учитывает вхождения? Но я согласен с @tofutim, что пересечение его является наиболее эффективным – O (N) по сравнению с O (N * logN) + O (logN)

Это простой код, но, конечно, немного медленнее.

 String s = ...; int countDollar = s.length()-s.replaceAll("\\$","").length(); int counta = s.length()-s.replaceAll("a","").length(); 

Еще лучший ответ здесь по второму вопросу

Существует еще один способ подсчета количества символов в каждой строке. Предполагая, что у нас есть String as String str = "abfdvdvdfv"

Затем мы можем подсчитать количество раз, когда каждый символ появляется, пройдя только один раз,

 for (int i = 0; i < str.length(); i++) { if(null==map.get(str.charAt(i)+"")) { map.put(str.charAt(i)+"", new Integer(1)); } else { Integer count = map.get(str.charAt(i)+""); map.put(str.charAt(i)+"", count+1); } } 

Затем мы можем проверить выход, пройдя по карте как

 for (Map.Entry entry:map.entrySet()) { System.out.println(entry.getKey()+" count is : "+entry.getValue()) } 
  public static int countChars(String input,char find){ if(input.indexOf(find) != -1){ return countChars(input.substring(0, input.indexOf(find)), find)+ countChars(input.substring(input.indexOf(find)+1),find) + 1; } else { return 0; } } 
  • Почему String.split требует, чтобы разделитель строк был экранирован?
  • Обратное строковое слово Word в Word
  • Как проверить, содержит ли строка только цифры в Java
  • Найти первый повторный символ в строке
  • Как заменить специальные символы в строке?
  • История за названием «String»
  • Преобразовать байты в строку?
  • байты строки в java?
  • Когда следует использовать амперсанд с scanf ()
  • Извлечь подстроку в Bash
  • Bash: разделите строку на массив символов
  • Давайте будем гением компьютера.