İpim var
a.b.c.d
'' Oluşumlarını saymak istiyorum. deyimsel bir şekilde, tercihen bir astar.
(Daha önce herkesin bir döngü kullanmadan neden cevap vermeye çalıştığını merak ediyorsanız, bu kısıtlamayı "döngü olmadan" olarak ifade etmiştim).
İpim var
a.b.c.d
'' Oluşumlarını saymak istiyorum. deyimsel bir şekilde, tercihen bir astar.
(Daha önce herkesin bir döngü kullanmadan neden cevap vermeye çalıştığını merak ediyorsanız, bu kısıtlamayı "döngü olmadan" olarak ifade etmiştim).
Yanıtlar:
Bunun için benim 'deyimsel bir astar':
int count = StringUtils.countMatches("a.b.c.d", ".");
Zaten müşterek dildeyken neden kendiniz yazıyorsunuz ?
Spring Framework'ün bu konudaki öncüsü:
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Yinelenen bir soruda dogbane tarafından yanıtlandığı gibi .
Buna ne dersin. Altında regexp kullanmaz, bu nedenle diğer bazı çözümlerden daha hızlı olmalı ve bir döngü kullanmayacaktır.
int count = line.length() - line.replace(".", "").length();
Diğer yanıtı ve tek katmanlı kullanarak bunu yapmanın tüm yollarını bildiklerimi özetleyin:
String testString = "a.b.c.d";
1) Apache Commons Kullanımı
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
2) Spring Framework'leri kullanma
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
3) değiştirin kullanma
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
4) replaceAll kullanma (durum 1)
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
5) replaceAll kullanma (durum 2)
int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
6) split kullanma
int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);
7) Java8 kullanma (durum 1)
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
8) Java8 (durum 2) kullanmak, unicode için durum 1'den daha iyi olabilir
long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);
9) StringTokenizer Kullanımı
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);
Yorumdan : StringTokenizer için dikkatli olun, abcd için işe yarayacak ama ... bc ... d veya ... abcd veya a ... b ...... c ..... d için ... ya da vs. çalışmaz. Sadece sayılır. karakterler arasında sadece bir kez
Daha fazla bilgi github
Performans testi ( JMH kullanarak , mode = AverageTime, 0.010
o zaman daha iyi puan 0.351
):
Benchmark Mode Cnt Score Error Units
1. countMatches avgt 5 0.010 ± 0.001 us/op
2. countOccurrencesOf avgt 5 0.010 ± 0.001 us/op
3. stringTokenizer avgt 5 0.028 ± 0.002 us/op
4. java8_1 avgt 5 0.077 ± 0.005 us/op
5. java8_2 avgt 5 0.078 ± 0.003 us/op
6. split avgt 5 0.137 ± 0.009 us/op
7. replaceAll_2 avgt 5 0.302 ± 0.047 us/op
8. replace avgt 5 0.303 ± 0.034 us/op
9. replaceAll_1 avgt 5 0.351 ± 0.045 us/op
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Er ya da geç, bir şey ilmek yapmalıdır. split
İhtiyacınız olandan çok daha güçlü bir şey kullanmaktan (çok basit) döngüyü yazmak sizin için çok daha basittir .
Her halükarda, döngüyü ayrı bir yöntemde, örneğin
public static int countOccurrences(String haystack, char needle)
{
int count = 0;
for (int i=0; i < haystack.length(); i++)
{
if (haystack.charAt(i) == needle)
{
count++;
}
}
return count;
}
O zaman döngü ana kodunuzda olması gerekmez - ama döngü orada bir yerde olmalı.
length()
çağrıyı döngü dışına taşımanın performansı nasıl daha da kötüleştirebileceğini merak ediyorum .
Mladen'e benzer bir fikrim vardı, ama tam tersi ...
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
replaceAll()
ve length()
.
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
ReplaceAll (".") Tüm karakterlerin yerine geçer.
PhiLho'nun çözümü , kaçması gerekmeyen ReplaceAll ("[^.]", "") 'İ kullanır, çünkü [.]' Herhangi bir karakteri 'değil' nokta 'karakterini temsil eder.
'İdiyomatik tek katlı' çözümüm:
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
StringUtils kullanan bir çözümün neden kabul edildiğine dair bir fikriniz yok.
Daha kısa bir örnek
String text = "a.b.c.d";
int count = text.split("\\.",-1).length-1;
İşte döngü olmayan bir çözüm:
public static int countOccurrences(String haystack, char needle, int i){
return ((i=haystack.indexOf(needle, i)) == -1)?0:1+countOccurrences(haystack, needle, i+1);}
System.out.println("num of dots is "+countOccurrences("a.b.c.d",'.',0));
iyi, bir döngü var, ama görünmez :-)
- Yonatan
Bu amaç için yeni bir dize tahsis etme fikrini sevmiyorum. Ve dize zaten değerini sakladığı bir char dizisine sahip olduğundan, String.charAt () pratik olarak ücretsizdir.
for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))
sadece J2SE ile 1 satır veya daha az toplama gerektiren ek tahsisler olmadan hile yapar.
charAt
karakterleri değil 16 bit kod noktaları üzerinden yineler! char
Java'daki A bir karakter değildir. Dolayısıyla bu cevap, yüksek bir vekilin kod noktasına eşit olduğu bir Unicode sembolü olmaması gerektiği anlamına gelir delim
. Nokta için doğru olup olmadığından emin değilim, ancak genel olarak doğru olmayabilir.
Tamam, Yonatan'ın çözümünden esinlenilen, işte tamamen özyinelemeli - kullanılan tek kütüphane yöntemleri length()
ve charAt()
ikisi de herhangi bir döngü yapmıyor:
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);
}
Özyinelemenin döngü olarak sayılıp sayılmayacağı, tam olarak hangi tanımı kullandığınıza bağlıdır, ancak muhtemelen alabileceğiniz kadar yakındır.
Çoğu JVM'lerin bugünlerde kuyruk özyineleme yapıp yapmadığını bilmiyorum ... Aksi takdirde, uygun şekilde uzun dizeler için adsız yığın taşması elde edersiniz.
Yığınınızı uçurmayacak döngü olmayan bir versiyon olan Jon Skeet'ten esinlenmiştir. Çatalla birleştirme çerçevesini kullanmak istiyorsanız da kullanışlı başlangıç noktası.
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);
}
}
(Feragatname: Test edilmedi, derlenmedi, mantıklı değil.)
Belki de yazmanın en iyi (tek iş parçacıklı, yedek çift desteği yok) yolu:
public static int countOccurrences(String haystack, char needle) {
int count = 0;
for (char c : haystack.toCharArray()) {
if (c == needle) {
++count;
}
}
return count;
}
Bunun etkinliği hakkında emin değilim, ancak 3. taraf kütüphanelerini getirmeden yazabileceğim en kısa kod:
public static int numberOf(String target, String content)
{
return (content.split(target).length - 1);
}
İle Java-8bunu başarmak için de akışları kullanabilirsiniz. Açıkçası perde arkasında bir yineleme var, ama bunu açıkça yazmak zorunda değilsiniz!
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
.codePoints()
Bunun yerine kullanmak .chars()
daha sonra herhangi bir Unicode değerini destekleyecektir (vekil çiftler gerektirenler dahil)
Ayrıca bu sorunu çözmek için Java 8'de azaltma kullanmak da mümkündür:
int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);
Çıktı:
3
Tam örnek:
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;
}
}
Aramak:
int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3
Cevabı almanın en basit yolu aşağıdaki gibidir:
public static void main(String[] args) {
String string = "a.b.c.d";
String []splitArray = string.split("\\.",-1);
System.out.println("No of . chars is : " + (splitArray.length-1));
}
Spring framework kullanıyorsanız "StringUtils" sınıfını da kullanabilirsiniz. Yöntem "countOccurrencesOf" olacaktır.
Sen kullanabilirsiniz split()
sadece bir satır kod işlevi
int noOccurence=string.split("#",-1).length-1;
limit
aşırı yüklenmiş bölünmüş yöntem çağrısında sıfıra ayarlandığından. Örnek: 9 ( ) yerine "1##2#3#####".split("#")
yalnızca 4 ( [0:"1";1:""; 2:"2"; 3:"3"]
) boyutunda bir dizi verir [0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
.
public static int countOccurrences(String container, String content){
int lastIndex, currIndex = 0, occurrences = 0;
while(true) {
lastIndex = container.indexOf(content, currIndex);
if(lastIndex == -1) {
break;
}
currIndex = lastIndex + content.length();
occurrences++;
}
return occurrences;
}
import java.util.Scanner;
class apples {
public static void main(String args[]) {
Scanner bucky = new Scanner(System.in);
String hello = bucky.nextLine();
int charCount = hello.length() - hello.replaceAll("e", "").length();
System.out.println(charCount);
}
}// COUNTS NUMBER OF "e" CHAR´s within any string input
Yöntemler gizleyebilse de, bir döngü (veya özyineleme) olmadan saymanın bir yolu yoktur. Performans nedenlerinden dolayı bir char [] kullanmak istiyorsunuz.
public static int count( final String s, final char c ) {
final char[] chars = s.toCharArray();
int count = 0;
for(int i=0; i<chars.length; i++) {
if (chars[i] == c) {
count++;
}
}
return count;
}
ReplaceAll (yani RE) kullanmak en iyi yol gibi görünmüyor.
Oldukça benzer bir görevle bu Konuya rastladım. Hiçbir programlama dili kısıtlaması görmedim ve groovy bir java vm üzerinde çalıştığı için: İşte Groovy kullanarak Sorunumu nasıl çözebildim.
"a.b.c.".count(".")
yapılır.
Çok daha kolay bir çözüm, dizeyi sadece eşleştirdiğiniz karaktere göre bölmek olacaktır.
Örneğin,
int getOccurences(String characters, String string) {
String[] words = string.split(characters);
return words.length - 1;
}
Aşağıdaki durumlarda 4 geri dönecektir:
getOccurences("o", "something about a quick brown fox");
Kodun bir yerinde, bir şeyin ilmek yapması gerekir. Bunun tek yolu, döngüyü tamamen açmaktır:
int numDots = 0;
if (s.charAt(0) == '.') {
numDots++;
}
if (s.charAt(1) == '.') {
numDots++;
}
if (s.charAt(2) == '.') {
numDots++;
}
... vb, ancak daha sonra, döngüyü çalıştıran bilgisayar yerine, kaynak düzenleyicide elle yapan kişisiniz. Sözde koduna bakın:
create a project
position = 0
while (not end of string) {
write check for character at position "position" (see above)
}
write code to output variable "numDots"
compile program
hand in homework
do not think of the loop that your "if"s may have been optimized and compiled to
İşte biraz farklı bir stil özyineleme çözümü:
public static int countOccurrences(String haystack, char needle)
{
return countOccurrences(haystack, needle, 0);
}
private static int countOccurrences(String haystack, char needle, int accumulator)
{
if (haystack.length() == 0) return accumulator;
return countOccurrences(haystack.substring(1), needle, haystack.charAt(0) == needle ? accumulator + 1 : accumulator);
}
Neden sadece karaktere bölünmez ve sonuçta elde edilen dizinin uzunluğunu elde edemezsiniz. dizi uzunluğu her zaman örnek sayısı + 1 olacaktır. Değil mi?
Aşağıdaki kaynak kodu, kullanıcı tarafından girilen bir sözcükte belirli bir dizenin hiçbir örneğini verecektir: -
import java.util.Scanner;
public class CountingOccurences {
public static void main(String[] args) {
Scanner inp= new Scanner(System.in);
String str;
char ch;
int count=0;
System.out.println("Enter the string:");
str=inp.nextLine();
while(str.length()>0)
{
ch=str.charAt(0);
int i=0;
while(str.charAt(i)==ch)
{
count =count+i;
i++;
}
str.substring(count);
System.out.println(ch);
System.out.println(count);
}
}
}