我有字符串
a.b.c.d
Run Code Online (Sandbox Code Playgroud)
我想计算'.'的出现次数.以惯用的方式,最好是单线.
(以前我把这个约束表达为"没有循环",如果你想知道为什么每个人都试图回答而不使用循环).
And*_*and 985
这个怎么样.它不使用下面的regexp,所以应该比其他一些解决方案更快,并且不会使用循环.
int count = line.length() - line.replace(".", "").length();
Run Code Online (Sandbox Code Playgroud)
Cow*_*wan 693
我的'惯用单线'是这样的:
int count = StringUtils.countMatches("a.b.c.d", ".");
Run Code Online (Sandbox Code Playgroud)
当它已经在公共场所时,为什么要自己写呢?
Spring Framework的oneliner就是:
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
Run Code Online (Sandbox Code Playgroud)
Via*_*nin 267
总结其他答案以及我所知道的使用单线程的所有方法:
String testString = "a.b.c.d";
Run Code Online (Sandbox Code Playgroud)
1)使用Apache Commons
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
Run Code Online (Sandbox Code Playgroud)
2)使用Spring Framework
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
Run Code Online (Sandbox Code Playgroud)
3)使用替换
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
Run Code Online (Sandbox Code Playgroud)
4)使用replaceAll(案例1)
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
Run Code Online (Sandbox Code Playgroud)
5)使用replaceAll(案例2)
int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
Run Code Online (Sandbox Code Playgroud)
6)使用拆分
int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);
Run Code Online (Sandbox Code Playgroud)
7)使用Java8(案例1)
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
Run Code Online (Sandbox Code Playgroud)
8)使用Java8(案例2),对于unicode可能比案例1更好
long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);
Run Code Online (Sandbox Code Playgroud)
9)使用StringTokenizer
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);
Run Code Online (Sandbox Code Playgroud)
来自评论:要小心StringTokenizer,对于abcd,它可以工作但是... bc ... d或... abcd或a .... b ...... c ...... d ......或者它等等.它只是值得.人物之间只有一次
更多信息在github中
性能测试(使用JMH,模式=平均时间,得分0.010
更好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
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 171
迟早,某些东西必须循环.编写(非常简单)循环比使用split
比你需要的功能更强大的东西要简单得多.
通过所有方式将循环封装在单独的方法中,例如
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;
}
Run Code Online (Sandbox Code Playgroud)
然后你不需要在主代码中使用循环 - 但循环必须在某处.
Phi*_*Lho 62
我有一个类似于Mladen的想法,但相反......
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
Run Code Online (Sandbox Code Playgroud)
Mla*_*dic 36
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
Run Code Online (Sandbox Code Playgroud)
ReplaceAll(".")将替换所有字符.
PhiLho的解决方案使用ReplaceAll("[^.]",""),它不需要转义,因为[.]代表字符'dot',而不是'任何字符'.
mlc*_*622 28
我的'惯用单线'解决方案:
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
Run Code Online (Sandbox Code Playgroud)
不知道为什么接受使用StringUtils的解决方案.
fub*_*ubo 27
String s = "a.b.c.d";
long result = s.chars().filter(ch -> ch == '.').count();
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey 24
一个较短的例子是
String text = "a.b.c.d";
int count = text.split("\\.",-1).length-1;
Run Code Online (Sandbox Code Playgroud)
Yon*_*man 18
这是一个没有循环的解决方案:
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));
Run Code Online (Sandbox Code Playgroud)
好吧,有一个循环,但它是看不见的 :-)
- Yonatan
0xC*_*ABE 15
我不喜欢为此目的分配新字符串的想法.由于字符串后面已经有一个char数组,它存储了它的值,String.charAt()实际上是免费的.
for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))
Run Code Online (Sandbox Code Playgroud)
如果没有需要收集的额外分配,只需要一行或更少,只需要J2SE.
Jon*_*eet 14
好的,受到Yonatan解决方案的启发,这里有一个纯粹递归的方法 - 使用的唯一库方法是,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);
}
Run Code Online (Sandbox Code Playgroud)
递归计数是否为循环取决于您使用的确切定义,但它可能与您获得的接近.
我不知道这些天大多数JVM是否会进行尾递归...如果不是,你会得到适当长串的同名堆栈溢出,当然.
Tom*_*ine 12
灵感来自Jon Skeet,一个不会让你的筹码无法破坏的非循环版本.如果要使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
(免责声明:未经测试,未编译,不合理.)
也许最好的(单线程,没有代理对支持)方式来编写它:
public static int countOccurrences(String haystack, char needle) {
int count = 0;
for (char c : haystack.toCharArray()) {
if (c == needle) {
++count;
}
}
return count;
}
Run Code Online (Sandbox Code Playgroud)
Kan*_*arU 10
不确定这个效率,但它是我可以编写的最短代码而不引入第三方库:
public static int numberOf(String target, String content)
{
return (content.split(target).length - 1);
}
Run Code Online (Sandbox Code Playgroud)
Ale*_* C. 10
使用java-8,您还可以使用流来实现此目的.显然幕后有一个迭代,但你不必明确地写它!
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
Run Code Online (Sandbox Code Playgroud)
也可以在Java 8中使用reduce来解决这个问题:
int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);
Run Code Online (Sandbox Code Playgroud)
输出:
3
Run Code Online (Sandbox Code Playgroud)
完整样本:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
呼叫:
int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3
Run Code Online (Sandbox Code Playgroud)
获得答案的最简单方法如下:
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));
}
Run Code Online (Sandbox Code Playgroud)
您split()
仅需一行代码即可使用该功能
int noOccurence=string.split("#",-1).length-1;
Run Code Online (Sandbox Code Playgroud)
小智 5
一个更简单的解决方案是根据您与之匹配的字符拆分字符串。
例如,
int getOccurences(String characters, String string) {
String[] words = string.split(characters);
return words.length - 1;
}
在以下情况下,这将返回 4:
getOccurences("o", "something about a quick brown fox");
归档时间: |
|
查看次数: |
837445 次 |
最近记录: |