Как подсчитать вхождение каждого символа в строку Java с использованием Pattern Class (Regex) - PullRequest
0 голосов
/ 24 июня 2018

Я пытаюсь найти количество вхождений каждого символа в заданную строку.

  • Ожидаемый выход: t=2 e=1 s=1 i=1 n=1 g=1
  • Текущий выход: T=0 e=0 s=0 t=0 i=0 n=0 g=0

Код:

String str = "Testing";
int count = 0;

Pattern p = Pattern.compile("[a-zA-Z]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(str);

while (m.find()) {
    if (m.group().equals(str)) {
        count++;
    }
    System.out.println(m.group() + "=" + count);
}

Есть многоспособы сделать это, но я ищу только Regex, так как мы можем достичь этого с помощью Regex.Любая помощь будет оценена.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Есть много способов достижения результата, но Regex не является инструментом для этого.Если вы хотите отфильтровать символы и убедиться, что будет подсчитано только [a-zA-Z], отфильтруйте нежелательные символы с помощью: string = string.replaceAll("[^a-zA-Z]", "");.Теперь вернемся к вашей проблеме.

Вам нужно разделить String на символы, а Map<Character, Integer>, чтобы сохранить эти символы и их количество вхождений.Я предлагаю вам использовать LinkedHashMap<Character, Integer>, который обеспечивает порядок вставки.

char[] charArray = string.toCharArray();
Map<Character, Integer> map = new LinkedHashMap<>();

Теперь переберите символы и сохраните их на карте.Если символ уже был сохранен, увеличьте значение на единицу.Этого можно достичь с помощью процедурного и традиционного for-loop или начиная с Java 8, вы можете использовать .

До Java 8:

for (char ch: charArray) {
    if(map.containsKey(ch)){
        map.put(ch, map.get(ch)+1);
    } else {
        map.put(ch, 1);
    }
}

После Java8 (string.split("") возвращает массив строк, вам необходимо сопоставить их с символами):

Map<Character, Long> map = Arrays
    .asList(string.split("")).stream().map(s -> s.charAt(0))
    .collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));

В обоих случаях выходные данные будут одинаковыми:

System.out.println(map); // prints {t=2, e=1, s=1, i=1, n=1, g=1}
0 голосов
/ 24 июня 2018

Нет необходимости в регулярном выражении для решения вашей проблемы, если вы используете Java8 +, вы можете просто использовать:

String input = "Testing";
Map<String, Long> result = Arrays.stream(input.split(""))
        .map(String::toLowerCase)
        .collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));

выходы

{t=2, e=1, s=1, i=1, n=1, g=1}

Редактировать

ммм, Pattern в этом случае бесполезен. Я не советую использовать его в этой задаче, в качестве альтернативного решения, используя Pattern с результатами из Java9 +, вы можете использовать:

String str = "Testing";
Pattern.compile(".").matcher(str)
        .results()
        .map(m -> m.group().toLowerCase())
        .collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()))
        .forEach((k, v) -> System.out.println(k + " = " + v)); 

Выходы

t = 2
e = 1
s = 1
i = 1
n = 1
g = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...