У меня есть строка
a.b.c.d
Я хочу посчитать вхождения '.' идиоматическим образом, предпочтительно однострочник.
(Ранее я выражал это ограничение как «без цикла», на случай, если вам интересно, почему все пытаются ответить без использования цикла).
Ответы:
Моя «идиоматическая строчка» для этого:
Зачем писать самому, когда он уже в общем языке ?
Единственный подход Spring Framework для этого:
источник
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Как ответил догбейн в дублирующем вопросе.Как насчет этого. Он не использует regexp, поэтому должен быть быстрее, чем некоторые другие решения, и не будет использовать цикл.
источник
Резюмируйте другой ответ, и я знаю все способы сделать это с помощью одной строки:
1) Использование Apache Commons
2) Использование Spring Framework
3) Использование замены
4) Использование replaceAll (случай 1)
5) Использование replaceAll (случай 2)
6) Использование сплита
7) Использование Java8 (случай 1)
8) Использование Java8 (случай 2), может быть лучше для юникода, чем случай 1
9) Использование StringTokenizer
Из комментария : Будьте осторожны с StringTokenizer, для abcd он будет работать, но для a ... bc ... d или ... abcd или a .... b ...... c ..... d ... или т. д. это не будет работать. Это просто будет иметь значение. между персонажами только один раз
Больше информации в github
Тест производительности (с использованием JMH , mode = AverageTime, тогда оценка
0.010
выше0.351
):источник
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Рано или поздно что-то должно зацикливаться. Вам гораздо проще написать (очень простой) цикл, чем использовать что-то подобное,
split
что намного мощнее, чем вам нужно.Обязательно инкапсулируйте цикл в отдельный метод, например
Тогда вам не нужно иметь цикл в вашем основном коде - но цикл должен быть где-то там.
источник
length()
вызова за пределы цикла может ухудшить производительность , как упомянуто @ShuggyCoUk несколькими комментариями.У меня была идея, похожая на Младена, но наоборот ...
источник
replaceAll()
иlength()
. выполняются десятки циклов . Ну, если его не видно, его не существует; o)ReplaceAll (".") Заменит все символы.
Решение PhiLho использует ReplaceAll ("[^.]", ""), Который не нужно экранировать, поскольку [.] Представляет символ «точка», а не «любой символ».
источник
Мое «идиоматическое однострочное» решение:
Понятия не имею, почему принято решение, использующее StringUtils.
источник
источник
Более короткий пример
источник
Вот решение без цикла:
ну, есть петля, но она невидима :-)
- Йонатан
источник
Мне не нравится идея выделения новой строки для этой цели. И так как строка уже имеет массив char сзади, где она хранит свое значение, String.charAt () практически бесплатна.
делает трюк, без дополнительных выделений, которые требуют сбора, в 1 строку или меньше, только с J2SE.
источник
charAt
перебирает 16-битные кодовые точки, а не символы! Аchar
в Java это не символ. Таким образом, этот ответ подразумевает, что не должно быть символа Unicode с высоким суррогатом, равным точке кодаdelim
. Я не уверен, правильно ли это для точки, но в целом это может быть не правильно.Хорошо, вдохновленный решением Йонатана, вот тот, который является чисто рекурсивным - используются только библиотечные методы,
length()
иcharAt()
ни один из которых не выполняет циклов:То, считается ли рекурсия зацикливанием, зависит от того, какое именно определение вы используете, но это, вероятно, так близко, как вы получите.
Я не знаю, выполняет ли большинство JVM хвостовую рекурсию в наши дни ... если нет, то вы получите одноименное переполнение стека для подходящих длинных строк, конечно.
источник
Вдохновленный Джоном Скитом, не петлевой версией, которая не подорвет ваш стек. Также полезная отправная точка, если вы хотите использовать инфраструктуру fork-join.
(Отказ от ответственности: не проверено, не скомпилировано, не имеет смысла.)
Возможно, лучший (однопоточный, без поддержки суррогатных пар) способ написать это:
источник
Не уверен насчет эффективности этого, но это самый короткий код, который я мог бы написать без привлечения сторонних библиотек:
источник
return (content.split(target, -1).length - 1);
. По умолчанию вхождения в конце строки опускаются в массиве, являющемся результатом split (). Смотрите ДокуС Java-8Вы также можете использовать потоки для достижения этой цели. Очевидно, что есть итерация за кулисами, но вам не нужно писать это явно!
источник
.codePoints()
вместо.chars()
этого поддержало бы любое значение Юникода (включая те, которые требуют суррогатных пар)Также возможно использовать Reduce в Java 8 для решения этой проблемы:
Вывод:
источник
Полный образец:
Вызов:
источник
Самый простой способ получить ответ заключается в следующем:
источник
Если вы используете Spring Framework, вы также можете использовать класс "StringUtils". Метод будет "countOccurferencesOf".
источник
Вы можете использовать
split()
функцию только в одной строке кодаисточник
limit
в этом перегруженном вызове метода split аргумент устанавливается равным нулю. Пример:"1##2#3#####".split("#")
выдаст только массив размером 4 ([0:"1";1:""; 2:"2"; 3:"3"]
) вместо размера 9 ([0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
).источник
источник
Хотя методы могут это скрыть, нет способа считать без цикла (или рекурсии). Вы хотите использовать char [] из соображений производительности.
Использование replaceAll (то есть RE) не похоже на лучший путь.
источник
Ну, с довольно похожей задачей я наткнулся на эту тему. Я не видел никаких ограничений в языке программирования, и поскольку groovy работает на Java vm: Вот как я смог решить мою проблему с помощью Groovy.
сделанный.
источник
Гораздо более простым решением было бы просто разбить строку на основе символа, с которым вы ее сопоставляете.
Например,
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
Это вернет 4 в случае:
getOccurences("o", "something about a quick brown fox");
источник
Где-то в коде что-то должно зацикливаться. Единственным выходом из этого является полное развертывание цикла:
... и т. д., но тогда вы выполняете цикл вручную в редакторе исходного кода, а не на компьютере, который будет его запускать. Смотрите псевдокод:
источник
Вот немного другое решение рекурсии стиля:
источник
Почему бы просто не разделить символ и затем получить длину полученного массива. длина массива всегда будет равна числу экземпляров + 1. Верно?
источник
Следующий исходный код даст вам отсутствие вхождений данной строки в слове, введенном пользователем: -
источник
источник