나는 문자열이
a.b.c.d
'.'의 발생 횟수를 계산하고 싶습니다. 관용적 방식으로, 바람직하게는 하나의 라이너.
(이전에는 모든 사람들이 루프를 사용하지 않고 응답하려고하는 이유가 궁금한 경우를 대비하여이 제약 조건을 "루프없이"로 표현했습니다.)
나는 문자열이
a.b.c.d
'.'의 발생 횟수를 계산하고 싶습니다. 관용적 방식으로, 바람직하게는 하나의 라이너.
(이전에는 모든 사람들이 루프를 사용하지 않고 응답하려고하는 이유가 궁금한 경우를 대비하여이 제약 조건을 "루프없이"로 표현했습니다.)
답변:
이것에 대한 나의 '아이디 오 메틱 원 라이너'는 다음과 같습니다.
int count = StringUtils.countMatches("a.b.c.d", ".");
이미 commons lang 에있을 때 직접 작성해야하는 이유는 무엇 입니까?
이를위한 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) 스프링 프레임 워크 사용
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 (case 2 )을 사용하면 case 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()
루프 외부로 호출을 이동하면 성능 이 어떻게 나빠질 수 있는지 궁금합니다 .
나는 Mladen과 비슷한 아이디어를 가지고 있었지만 그 반대는 ...
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
replaceAll()
하고 length()
. 글쎄, 보이지 않는 경우 존재하지 않습니다; o)
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
ReplaceAll ( ".")은 모든 문자를 대체합니다.
PhiLho의 솔루션 은 ReplaceAll ( "[^.]", "")을 사용합니다. [.]는 'any character'가 아닌 'dot'문자를 나타내므로 이스케이프 할 필요가 없습니다.
내 '아이디 오 매틱 원 라이너'솔루션 :
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
StringUtils를 사용하는 솔루션이 왜 허용되는지 모릅니다.
더 짧은 예는
String text = "a.b.c.d";
int count = text.split("\\.",-1).length-1;
루프가없는 솔루션은 다음과 같습니다.
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 는 문자가 아닙니다. 따라서이 답변은의 코드 포인트와 높은 대리 문자가있는 유니 코드 기호가 없어야 함을 나타 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에서 영감을 얻었습니다. 포크 조인 프레임 워크를 사용하려는 경우에도 유용한 시작점입니다.
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;
}
이것의 효율성에 대해서는 확실하지 않지만 타사 라이브러리를 가져 오지 않고 작성할 수있는 가장 짧은 코드입니다.
public static int numberOf(String target, String content)
{
return (content.split(target).length - 1);
}
return (content.split(target, -1).length - 1);
. 기본적으로 문자열 끝에서 발생하는 것은 split ()으로 인해 Array에서 생략됩니다.
와 자바 -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()
대리 쌍이 필요한 값을 포함하여 모든 유니 코드 값이 지원됩니다.
Java 8에서 reduce를 사용하여이 문제를 해결할 수도 있습니다.
int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);
산출:
3
완전한 샘플 :
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
답을 얻는 가장 간단한 방법은 다음과 같습니다.
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));
}
split()
한 줄의 코드로 함수를 사용할 수 있습니다
int noOccurence=string.split("#",-1).length-1;
limit
오버로드 된 split 메소드 호출에서 인수 가 0으로 설정 되므로이 솔루션에는 후행 공백 적중이 포함되지 않습니다 . 예 : 크기 9 ( ) 대신 크기 "1##2#3#####".split("#")
4 ( [0:"1";1:""; 2:"2"; 3:"3"]
) 의 배열 만 생성합니다 [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 getOccurences(String characters, String string) {
String[] words = string.split(characters);
return words.length - 1;
}
다음과 같은 경우 4를 반환합니다.
getOccurences("o", "something about a quick brown fox");
코드 어딘가에서 무언가가 반복되어야합니다. 이 문제를 해결할 수있는 유일한 방법은 루프를 완전히 푸는 것입니다.
int numDots = 0;
if (s.charAt(0) == '.') {
numDots++;
}
if (s.charAt(1) == '.') {
numDots++;
}
if (s.charAt(2) == '.') {
numDots++;
}
... 등, 그러나 당신은 그것을 실행하는 컴퓨터 대신 소스 편집기에서 수동으로 루프를 수행하는 사람입니다. 의사 코드를 참조하십시오.
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);
}
다음 소스 코드는 사용자가 입력 한 단어에서 주어진 문자열의 발생 횟수를 제공합니다.
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);
}
}
}