문자열에서 문자 발생 횟수를 계산하는 방법
나는 끈을 가지고 있다.
a.b.c.d
''의 발생을 관용적인 방법으로 세어 보고 싶다.
(이전에는 왜 모든 사람들이 루프를 사용하지 않고 대답하려고 하는지 궁금할 경우를 대비해서 나는 이 제약조건을 "루프 없이"라고 표현했었다.)
이거 어때?아래에는 regexp를 사용하지 않으므로 다른 솔루션보다 속도가 빨라야 하며 루프를 사용하지 않는다.
int count = line.length() - line.replace(".", "").length();
이에 대한 나의 '직관적인 원라이너'는 다음과 같다.
int count = StringUtils.countMatches("a.b.c.d", ".");
이미 공용어로 되어 있는데 왜 직접 쓰세요?
이에 대한 Spring Framework의 oneliner는 다음과 같다.
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
원라이너를 사용하여 다른 답변과 이 작업을 수행할 수 있는 모든 방법을 요약하십시오.
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) 자바8 사용 (사례 1)
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
8) Java8(사례 2)을 사용하는 것이 사례 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는 주의하십시오. A.B.C.D.는 작동하지만 A.B.C.D 또는...A.B.C.D. 또는 A.B.C.D. 또는 A.B...c...d... 등에는 작동하지 마십시오.그것은 작동하지 않을 것이다.단지 한 번 캐릭터 사이에 있을 뿐이다.
성능 테스트(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
조만간 무언가가 반복될 것이다.이런 것을 쓰는 것보다 (아주 간단한) 루프를 쓰는 것이 훨씬 간단하다.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;
}
그러면 당신은 당신의 메인 코드에 루프가 필요하지 않다. 하지만 루프는 어딘가에 있어야 한다.
믈라덴과 비슷한 생각이 있었지만, 그 반대...
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
ReplaceAll(")"은 모든 문자를 대체한다.
PhiLho의 솔루션은 ReplaceAll("^ylt")을 사용하며, [yone character'가 아닌 'dot'자를 나타내기 때문에 탈출할 필요가 없다.
나의 '직관적인 원라이너' 해결책:
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
StringUtils를 사용하는 솔루션이 수락되는 이유를 전혀 모르십시오.
String s = "a.b.c.d";
long result = s.chars().filter(ch -> ch == '.').count();
더 짧은 예는 다음과 같다.
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));
음, 루프는 있지만 보이지 않는다 :-)
-- 요나탄
나는 이런 목적으로 새 끈을 할당한다는 생각이 마음에 들지 않는다.그리고 문자열은 이미 뒤에 값을 저장하는 문자열이 있기 때문에 String.charAt()는 사실상 무료다.
for(int i=0;i<s.length();num+=(s.charAt(i++)==delim?1:0))
수집이 필요한 추가 할당 없이 J2SE만 사용하여 트릭을 한 줄 또는 그 이하로 처리한다.
자, 요나탄의 해결책에 영감을 받아, 여기 순전히 재귀적인 방법이 하나 있는데, 사용된 유일한 도서관 방법은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이 꼬리에 꼬리를 물는지...만약 그렇지 않다면, 당연히 긴 끈을 위해 엄청난 스택 오버플로를 겪게 될 것이다.
이것의 효율성은 확실하지 않지만, 제3자 리브를 가져오지 않고도 쓸 수 있는 가장 짧은 코드다.
public static int numberOf(String target, String content)
{
return (content.split(target).length - 1);
}
스택을 날려버리지 않는 비루프 버전인 Jon Sket에서 영감을 받아.또한 포크 조인 프레임워크를 사용하려는 경우 유용한 시작 지점.
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
또한 이 문제를 해결하기 위해 Java 8에서 축소 사용 가능:
int res = "abdsd3$asda$asasdd$sadas".chars().reduce(0, (a, c) -> a + (c == '$' ? 1 : 0));
System.out.println(res);
출력:
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));
}
전체 샘플:
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
스프링 프레임워크를 사용하는 경우 "StringUtils" 클래스를 사용하십시오.그 방법은 "발생 횟수"가 될 것이다.
당신은 그것을 사용할 수 있다.split()
한 줄 코드로만 기능하다.
int noOccurence=string.split("#",-1).length-1;
훨씬 쉬운 해결책은 그 문자열을 그 문자열을 그 문자열에 맞추어 분할하는 것이다.
예를 들어.
int getOccurences(String characters, String string) { String[] words = string.split(characters); return words.length - 1; }
다음과 같은 경우 4가 반환된다.getOccurences("o", "something about a quick brown fox");
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;
}
방법은 그것을 숨길 수 있지만, 루프(또는 재귀) 없이는 셀 방법이 없다.성능상의 이유로 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)을 사용하는 것은 최선의 방법처럼 들리지 않는다.
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
글쎄, 꽤 비슷한 작업으로 나는 우연히 이 스레드를 발견했다.나는 프로그래밍 언어의 제약을 보지 못했고 그로비가 자바 VM에서 실행되기 때문에: 그로비를 사용하여 나의 문제를 해결할 수 있었던 방법은 다음과 같다.
"a.b.c.".count(".")
끝냈다
Eclipse 컬렉션 사용
int count = Strings.asChars("a.b.c.d").count(c -> c == '.');
둘를 쓸 수 CharBag
아래와 같이
CharBag bag = Strings.asChars("a.b.c.d").toBag();
int count = bag.occurrencesOf('.');
참고: 나는 Eclipse Collections의 커밋자입니다.
암호의 어딘가에서 뭔가가 반복되어야 해이 문제를 해결할 유일한 방법은 루프를 완전히 풀어버리는 것이다.
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);
}
문자를 분할한 다음 결과 배열의 길이를 얻는 것이 어때? 배열 길이는 항상 인스턴스 수 + 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);
}
}
}
'IT이야기' 카테고리의 다른 글
VueJS - 문자열 내에서 문자열 보간 (0) | 2022.05.08 |
---|---|
주니트와 함께 하는 인텔리제이 아이디어 4.7 "!!!JUnit 버전 3.8 이상 예상:" (0) | 2022.05.08 |
vuejs - 동적 입력 'synamic' (0) | 2022.05.08 |
Java: 인스턴스(Instanceof) 및 제네릭 (0) | 2022.05.08 |
C를 사용하여 키보드에서 문자열을 읽는 방법? (0) | 2022.05.08 |