Saya punya talinya
a.b.c.d
Saya ingin menghitung kemunculan '.' dengan cara yang idiomatis, lebih disukai satu kalimat.
(Sebelumnya saya telah menyatakan batasan ini sebagai "tanpa loop", jika Anda bertanya-tanya mengapa semua orang mencoba menjawab tanpa menggunakan loop).
Jawaban:
'One-liner idiomatik' saya untuk ini adalah:
Mengapa menulis sendiri ketika sudah di commons lang ?
Oneliner Spring Framework untuk ini adalah:
sumber
int count = CharMatcher.is('.').countIn("a.b.c.d");
... Seperti dijawab oleh dogbane dalam pertanyaan rangkap.Bagaimana dengan ini. Itu tidak menggunakan regexp di bawahnya jadi harus lebih cepat daripada beberapa solusi lain dan tidak akan menggunakan loop.
sumber
Ringkas jawaban lain dan apa yang saya tahu semua cara untuk melakukan ini menggunakan satu-baris:
1) Menggunakan Apache Commons
2) Menggunakan Spring Framework's
3) Menggunakan ganti
4) Menggunakan replaceAll (case 1)
5) Menggunakan replaceAll (case 2)
6) Menggunakan split
7) Menggunakan Java8 (kasus 1)
8) Menggunakan Java8 (case 2), mungkin lebih baik untuk unicode daripada case 1
9) Menggunakan StringTokenizer
Dari komentar : Hati-hati untuk StringTokenizer, karena abcd itu akan berfungsi tetapi untuk ... bc ... d atau ... abcd atau ... b ...... c ..... d ... atau dll. itu tidak akan berfungsi. Itu hanya akan dihitung. antar karakter sekali saja
Info lebih lanjut di github
Tes kinerja (menggunakan JMH , mode = AverageTime, skor
0.010
lebih baik dari itu0.351
):sumber
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
Cepat atau lambat, sesuatu harus berulang. Jauh lebih mudah bagi Anda untuk menulis loop (sangat sederhana) daripada menggunakan sesuatu seperti
split
yang jauh lebih kuat daripada yang Anda butuhkan.Dengan segala cara merangkum loop dalam metode yang terpisah, misalnya
Maka Anda tidak perlu memiliki loop di kode utama Anda - tetapi loop harus ada di suatu tempat.
sumber
length()
panggilan di luar loop dapat membuat kinerja lebih buruk , seperti yang disebutkan oleh @ShuggyCoUk beberapa komentar.Saya punya ide yang mirip dengan Mladen, tetapi sebaliknya ...
sumber
replaceAll()
danlength()
. Nah, jika itu tidak terlihat, itu tidak ada; o)ReplaceAll (".") Akan menggantikan semua karakter.
Solusi PhiLho menggunakan ReplaceAll ("[^.]", ""), Yang tidak perlu diloloskan, karena [.] Mewakili karakter 'titik', bukan 'karakter apa pun'.
sumber
Solusi 'satu baris idiomatik' saya:
Tidak tahu mengapa solusi yang menggunakan StringUtils diterima.
sumber
sumber
Contoh yang lebih pendek adalah
sumber
di sini adalah solusi tanpa loop:
baik, ada loop, tetapi tidak terlihat :-)
- Yonatan
sumber
Saya tidak suka gagasan mengalokasikan string baru untuk tujuan ini. Dan karena string sudah memiliki array char di belakang di mana ia menyimpan nilainya, String.charAt () praktis gratis.
melakukan trik, tanpa alokasi tambahan yang perlu pengumpulan, dalam 1 baris atau kurang, dengan hanya J2SE.
sumber
charAt
iterasi melalui 16 bit kode poin bukan karakter! Achar
di Java bukan karakter. Jadi jawaban ini menyiratkan bahwa tidak boleh ada simbol Unicode dengan pengganti yang tinggi sama dengan titik kodedelim
. Saya tidak yakin apakah itu benar untuk titik, tetapi secara umum mungkin tidak benar.Oke, terinspirasi oleh solusi Yonatan, inilah yang murni rekursif - satu-satunya metode perpustakaan yang digunakan adalah ,
length()
dancharAt()
tidak ada yang melakukan perulangan:Apakah rekursi dianggap sebagai pengulangan tergantung pada definisi pasti yang Anda gunakan, tetapi mungkin sedekat yang Anda dapatkan.
Saya tidak tahu apakah sebagian besar JVM melakukan rekursi ekor akhir-akhir ini ... jika tidak, Anda akan mendapatkan stack overflow eponymous untuk string yang panjang, tentu saja.
sumber
Terinspirasi oleh Jon Skeet, versi non-loop yang tidak akan meniup stack Anda. Juga titik awal yang berguna jika Anda ingin menggunakan kerangka kerja fork-join.
(Penafian: Tidak diuji, tidak dikompilasi, tidak masuk akal.)
Mungkin cara terbaik (single-threaded, no surrogate-pair support) cara untuk menulisnya:
sumber
Tidak yakin tentang efisiensi ini, tetapi ini adalah kode terpendek yang dapat saya tulis tanpa membawa lib pihak ke-3:
sumber
return (content.split(target, -1).length - 1);
. Secara default, kejadian di akhir string dihilangkan dalam Array yang dihasilkan dari split (). Lihat DokuDengan java-8Anda juga bisa menggunakan stream untuk mencapai ini. Jelas ada iterasi di balik layar, tetapi Anda tidak harus menulisnya secara eksplisit!
sumber
.codePoints()
alih-alih.chars()
akan mendukung nilai Unicode apa pun (termasuk yang membutuhkan pasangan pengganti)Juga dimungkinkan untuk menggunakan pengurangan di Java 8 untuk mengatasi masalah ini:
Keluaran:
sumber
Sampel lengkap:
Panggilan:
sumber
Cara paling sederhana untuk mendapatkan jawabannya adalah sebagai berikut:
sumber
Jika Anda menggunakan kerangka kerja Spring, Anda mungkin juga menggunakan kelas "StringUtils". Metode ini akan menjadi "countOccurrencesOf".
sumber
Anda dapat menggunakan
split()
fungsi ini hanya dalam satu kode barissumber
limit
disetel ke nol dalam pemanggilan metode pemisahan yang kelebihan beban ini. Contoh:"1##2#3#####".split("#")
hanya akan menghasilkan array ukuran 4 ([0:"1";1:""; 2:"2"; 3:"3"]
), bukan ukuran 9 ([0:"1"; 1:""; 2:"2"; 3:"3"; 4:""; 5:""; 6:""; 7:""; 8:""]
).sumber
sumber
Sementara metode dapat menyembunyikannya, tidak ada cara untuk menghitung tanpa loop (atau rekursi). Anda ingin menggunakan char [] untuk alasan kinerja.
Menggunakan replaceAll (yaitu RE) tidak terdengar seperti cara terbaik untuk pergi.
sumber
Nah, dengan tugas yang sangat mirip saya menemukan Thread ini. Saya tidak melihat batasan bahasa pemrograman dan karena groovy berjalan pada java vm: Berikut adalah bagaimana saya dapat menyelesaikan Masalah saya menggunakan Groovy.
selesai
sumber
Solusi yang jauh lebih mudah adalah dengan membagi string berdasarkan karakter yang cocok dengan Anda.
Contohnya,
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
Ini akan menghasilkan 4 jika:
getOccurences("o", "something about a quick brown fox");
sumber
Di suatu tempat dalam kode, sesuatu harus diulang. Satu-satunya cara untuk mengatasi ini adalah membuka gulungan sepenuhnya loop:
... dll, tapi kemudian kaulah yang melakukan loop, secara manual, di editor sumber - bukan komputer yang akan menjalankannya. Lihat kodesemu:
sumber
Berikut adalah solusi rekursi gaya yang sedikit berbeda:
sumber
Mengapa tidak hanya membagi karakter dan kemudian mendapatkan panjang array yang dihasilkan panjang array akan selalu menjadi jumlah instance + 1. Benar?
sumber
Kode sumber berikut akan memberi Anda no.of kemunculan string yang diberikan dalam kata yang dimasukkan oleh pengguna: -
sumber
sumber