我有琴弦
a.b.c.d
我想计算“。”的出现。以惯用方式,最好是单线。
(以前,我曾将此约束表示为“无循环”,以防您想知道为什么每个人都试图不使用循环而回答)。
我有琴弦
a.b.c.d
我想计算“。”的出现。以惯用方式,最好是单线。
(以前,我曾将此约束表示为“无循环”,以防您想知道为什么每个人都试图不使用循环而回答)。
Answers:
我对此的“惯用一语”是:
int count = StringUtils.countMatches("a.b.c.d", ".");
当它已经成为公共语言时,为什么还要自己编写呢?
Spring Framework的oneliner为此:
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
这个怎么样。它在下面不使用正则表达式,因此应该比其他一些解决方案更快,并且不会使用循环。
int count = line.length() - line.replace(".", "").length();
总结其他答案以及我所知道的使用单线执行此操作的所有方法:
String testString = "a.b.c.d";
1)使用Apache Commons
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
2)使用Spring Framework的
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
3)使用替换
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
4)使用replaceAll(案例1)
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
5)使用replaceAll(案例2)
int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
6)使用分割
int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);
7)使用Java8(案例1)
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
8)使用Java8(案例2),对于unicode可能比案例1更好
long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);
9)使用StringTokenizer
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);
来自评论:请谨慎使用StringTokenizer,对于abcd它将起作用,但对于a ... bc ... d或... abcd或a..b ...... c ..... d ...等等,它将不起作用。它只会算。字符之间只有一次
github中的更多信息
性能测试(使用JMH,模式= AverageTime,得分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
"1🚲2🚲3 has 2".codePoints().filter((c) -> c == "🚲".codePointAt(0)).count()
迟早,有些东西必须循环。对于您来说,编写(非常简单的)循环要比使用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;
}
然后,您不需要在主代码中包含循环-但循环必须在某个地方。
length()
调用移动到循环外会使性能变差,正如@ShuggyCoUk提到的一些评论。
我有一个类似于姆拉登的主意,但是相反。
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
replaceAll()
and中执行了数十个循环length()
。好吧,如果它不可见,那么它就不存在; o)
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
ReplaceAll(“。”)将替换所有字符。
PhiLho的解决方案使用ReplaceAll(“ [^。]”,“”),由于[。]代表字符“点”,而不是“任何字符”,因此不需要转义。
这是没有循环的解决方案:
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));
好了,有一个循环,但是它是不可见的 :-)
-约纳坦
我不喜欢为此目的分配新字符串的想法。并且由于该字符串在其存储值的后面已经有一个char数组,因此String.charAt()实际上是免费的。
for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))
仅需J2SE,就可以在1行以内或更少的时间内完成需要的操作,而无需进行需要收集的其他分配。
charAt
遍历16位代码点而不是字符!char
Java中的A 不是字符。因此,此答案表示必须没有Unicode代码等于的代码点的Unicode符号delim
。我不确定该点是否正确,但总的来说可能不正确。
好的,受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);
}
递归是否算作循环取决于您使用的确切定义,但可能与您将得到的定义很接近。
我不知道这些天大多数JVM是否都进行尾递归...如果没有,当然,对于适当的长字符串,您会得到同义的堆栈溢出。
受到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);
}
}
(免责声明:未经测试,未经编译,不明智。)
也许是最好的(单线程,没有代理对支持)编写方式:
public static int countOccurrences(String haystack, char needle) {
int count = 0;
for (char c : haystack.toCharArray()) {
if (c == needle) {
++count;
}
}
return count;
}
用 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
.codePoints()
代替.chars()
将支持任何Unicode值(包括那些需要代理对的值)
完整样本:
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;
}
}
呼叫:
int occurrences = CharacterCounter.countOccurrences("l", "Hello World.");
System.out.println(occurrences); // 3
您split()
仅需一行代码即可使用该功能
int noOccurence=string.split("#",-1).length-1;
limit
在此重载的拆分方法调用中将参数设置为零。例如:"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:""]
)的数组。
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
尽管方法可以将其隐藏,但没有循环(或递归)就无法计数。但是出于性能原因,您想使用char []。
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(即RE)听起来并不是最好的方法。
好吧,在完成一个非常类似的任务时,我偶然发现了这个线程。我没有看到任何编程语言限制,并且因为groovy在Java vm上运行:这就是我使用Groovy解决问题的方法。
"a.b.c.".count(".")
完成。
代码中的某些地方必须循环。解决此问题的唯一方法是完全展开循环:
int numDots = 0;
if (s.charAt(0) == '.') {
numDots++;
}
if (s.charAt(1) == '.') {
numDots++;
}
if (s.charAt(2) == '.') {
numDots++;
}
... etc,但是您是在源代码编辑器中手动执行循环的人-而不是将运行该循环的计算机。参见伪代码:
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
这是一个稍微不同的样式递归解决方案:
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);
}
为什么不直接拆分字符,然后获取结果数组的长度。数组长度始终是实例数+1。对吗?
以下源代码将给您用户输入的单词中出现给定字符串的次数:-
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);
}
}
}