Простой способ подсчета символов в строке
Есть ли простой способ (вместо того, чтобы вручную перемещать всю строку или цикл для indexOf), чтобы узнать, сколько раз символ появляется в строке?
Скажем, у нас есть «abdsd3 $ asda $ asasdd $ sadas», и мы хотим, чтобы $ появился 3 раза.
- Должен ли я использовать string.isEmpty () или "" .equals (string)?
- Android: что-то лучше, чем андроид: ellipsize = "end", чтобы добавить "..." в укороченные длинные строки?
- Как разбить строку на строки и включить разделители с помощью .NET?
- C #: как получить первый символ строки?
- Каков наилучший способ рекурсивного преобразования строки в Java?
- Как предотвратить java.lang.String.split () от создания ведущей пустой строки?
- Java String.indexOf и пустые строки
- Пользовательский манипулятор для C ++ iostream
- Как работает строковая подстрока в Swift
- Преобразование строки в целое число на Android
- Как использовать LINQ Contains (string ) вместо Contains (string)
- Преобразование строки в DateTime в c #
- Где живут строковые литералы Java и .NET?
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; } }