Как подсчитать количество появлений символа в строке? - PullRequest
494 голосов
/ 09 ноября 2008

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

a.b.c.d

Я хочу посчитать вхождения '.' идиоматическим образом, предпочтительно однострочник.

(Ранее я выражал это ограничение как "без цикла", на случай, если вам интересно, почему все пытаются ответить без использования цикла).

Ответы [ 41 ]

14 голосов
/ 16 апреля 2013

Мне не нравится идея выделения новой строки для этой цели. И так как строка уже имеет массив char сзади, где она хранит свое значение, String.charAt () практически свободна.

for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))

делает трюк, без дополнительных выделений, которые требуют сбора, в 1 строку или меньше, только с J2SE.

13 голосов
/ 09 ноября 2008

Хорошо, вдохновленный решением Йонатана, вот один, который является чисто рекурсивным - используются только библиотечные методы length() и charAt(), ни один из которых не выполняет циклов:

public static int countOccurrences(String haystack, char needle)
{
    return countOccurrences(haystack, needle, 0);
}

private static int countOccurrences(String haystack, char needle, int index)
{
    if (index >= haystack.length())
    {
        return 0;
    }

    int contribution = haystack.charAt(index) == needle ? 1 : 0;
    return contribution + countOccurrences(haystack, needle, index+1);
}

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

Я не знаю, выполняет ли большинство JVM хвостовую рекурсию в наши дни ... если нет, то, конечно, вы получите одноименное переполнение стека для подходящих длинных строк.

11 голосов
/ 11 ноября 2008

Вдохновленный Джоном Скитом, нецикличной версией, которая не взорвет ваш стек. Также полезная отправная точка, если вы хотите использовать инфраструктуру fork-join.

public static int countOccurrences(CharSequeunce haystack, char needle) {
    return countOccurrences(haystack, needle, 0, haystack.length);
}

// Alternatively String.substring/subsequence use to be relatively efficient
//   on most Java library implementations, but isn't any more [2013].
private static int countOccurrences(
    CharSequence haystack, char needle, int start, int end
) {
    if (start == end) {
        return 0;
    } else if (start+1 == end) {
        return haystack.charAt(start) == needle ? 1 : 0;
    } else {
        int mid = (end+start)>>>1; // Watch for integer overflow...
        return
            countOccurrences(haystack, needle, start, mid) +
            countOccurrences(haystack, needle, mid, end);
    }
}

(Отказ от ответственности: не проверено, не скомпилировано, не имеет смысла.)

Пожалуй, лучший (однопоточный, без поддержки суррогатных пар) способ написать:

public static int countOccurrences(String haystack, char needle) {
    int count = 0;
    for (char c : haystack.toCharArray()) {
        if (c == needle) {
           ++count;
        }
    }
    return count;
}
9 голосов
/ 26 мая 2014

С вы также можете использовать потоки для достижения этой цели. Очевидно, что есть итерация за кулисами, но вам не нужно писать это явно!

public static long countOccurences(String s, char c){
    return s.chars().filter(ch -> ch == c).count();
}

countOccurences("a.b.c.d", '.'); //3
countOccurences("hello world", 'l'); //3
9 голосов
/ 11 января 2013

Не уверен насчет эффективности этого, но это самый короткий код, который я мог написать без привлечения сторонних библиотек:

public static int numberOf(String target, String content)
{
    return (content.split(target).length - 1);
}
8 голосов
/ 24 мая 2017

Также возможно использовать Reduce в Java 8 для решения этой проблемы:

int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);

Выход:

3
7 голосов
/ 03 марта 2012

Полный образец:

public class CharacterCounter
{

  public static int countOccurrences(String find, String string)
  {
    int count = 0;
    int indexOf = 0;

    while (indexOf > -1)
    {
      indexOf = string.indexOf(find, indexOf + 1);
      if (indexOf > -1)
        count++;
    }

    return count;
  }
}

Вызов:

int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3
5 голосов
/ 17 мая 2017

Самый простой способ получить ответ заключается в следующем:

public static void main(String[] args) {
    String string = "a.b.c.d";
    String []splitArray = string.split("\\.");
    System.out.println("No of . chars is : " + splitArray.length-1);
}
5 голосов
/ 24 февраля 2011

Если вы используете Spring Framework, вы также можете использовать класс "StringUtils". Метод будет "countOccurferencesOf".

4 голосов
/ 19 мая 2016

Вы можете использовать функцию split() в одной строке кода

int noOccurence=string.split("#").length-1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...