Есть ли простой способ (вместо того, чтобы вручную перемещать всю строку или цикл для indexOf), чтобы узнать, сколько раз символ появляется в строке?
Скажем, у нас есть "abdsd3 $asda $asasdd $sadas", и мы хотим, чтобы $появился 3 раза.
Есть ли простой способ (вместо того, чтобы вручную перемещать всю строку или цикл для indexOf), чтобы узнать, сколько раз символ появляется в строке?
Скажем, у нас есть "abdsd3 $asda $asasdd $sadas", и мы хотим, чтобы $появился 3 раза.
public int countChar(String str, char c)
{
int count = 0;
for(int i=0; i < str.length(); i++)
{ if(str.charAt(i) == c)
count++;
}
return count;
}
Это, безусловно, самый быстрый способ. Регулярные выражения здесь намного медленнее, и их становится все труднее понять.
Функциональный стиль (Java 8, просто для удовольствия):
str.chars().filter(num -> num == '$').count()
Не оптимальный, но простой способ подсчета вхождений:
String s = "...";
int counter = s.split("\\$", -1).length - 1;
Примечание:
Вы можете использовать Apache Commons 'StringUtils.countMatches(String string, String subStringToCount)
.
Поскольку вы сканируете всю строку в любом случае, вы можете построить полный счетчик символов и сделать любое количество запросов, все для одной и той же большой-ой стоимости (n):
public static Map<Character,Integer> getCharFreq(String s) {
Map<Character,Integer> charFreq = new HashMap<Character,Integer>();
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. Таким образом, вам, вероятно, потребуется написать свою собственную функцию.
Я считаю, что "один лайнер", который вы ожидали получить, таков:
"abdsd3$asda$asasdd$sadas".replaceAll( "[^$]*($)?", "$1" ).length();
Помните, что требования:
(вместо того, чтобы вручную перемещать всю строку или для indexOf)
и позвольте мне добавить: что в основе этого вопроса звучит так, что "любая петля" не нужна, и нет необходимости в скорости. Я считаю, что подтекстом этого вопроса является фактор прохлады.
вы также можете использовать 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.
Что-то более функциональное, без 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);
}
Это не хвост рекурсивный, для ясности.
Это простой код, но, конечно, немного медленнее.
String s = ...;
int countDollar = s.length()-s.replaceAll("\\$","").length();
int counta = s.length()-s.replaceAll("a","").length();
Еще лучший ответ здесь в повторяющемся вопросе
Вы можете посмотреть сортировку строки - рассматривать ее как массив char - и затем выполнить модифицированный двоичный поиск, который учитывает вхождения? Но я согласен с @tofutim, что пересечение его является наиболее эффективным - O (N) по сравнению с O (N * logN) + O (logN)
Существует еще один способ подсчета количества символов в каждой строке.
Предположим, что у нас есть 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<String, Integer> 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;
}
}