본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[C/C++/JAVA 문자열 단어수 문제] 문자열에서 단어가 몇 개인지 세기 (문자열에 공백 포함)

반응형

안녕하세요 ㅎㅎ 오늘 오랜만에 아주 기초적인 문자열 문제를 들고 왔습니다.

다양한 문자열 사용법을 연습하고 싶은 꿈나무 개발자들에게 추천!

문제

대소문자와 띄어쓰기만으로 이루어진 영문자열에서 몇 개의 단어가 존재하는지 알려주는 프로그램을 작성하시오

입력

100글자 이내의 영문자 문자열

출력

총 단어의 개수 

예시

입력: "Nice to    meet   you  " 

출력: 4

 

입력: "   Hello World  !" 

출력: 3 

ANSWER 풀이 

단어를 세는 기준을  정해야겠죠?

1. 공백 다음에 문자가 오는 경우 (문자로 시작하는 경우 예외처리 필요)

2. 문자 다음에 공백이 오는 경우 (문자로 끝났을 경우 예외처리 필요)

3. 앞뒤가 문자 또는 공백으로 다를 경우 다 세고 나누기 2! (문자로 시작하거나 끝났을 경우 예외처리 필요)

요렇게 생각해볼 수 있어요.

사실 이거 생각하셨으면 금방 풀 수 있는 초간단한 문제긴 합니다. ㅎㅎ

 

C언어로 먼저 풀어볼까요?

[C언어 - scanf와 isspace 사용]

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main()
{
    char str[100];
    int count = 0; int i =0;

    printf("문장을 입력하세요 :");
    //요렇게 scanf를 통해서 공백을 입력받을 수 있다
    scanf("%[^\n]s", str);  //엔터 제외하고 다 입력처리해라~~
    if (!isspace(str[0])) count++;
    for (i; i < strlen(str)-1; i++)
    {
        if (isspace(str[i]) && !isspace(str[i+1]))
            count++;
    }
    printf("%d\n", count);
    return 0;
}

1번에 해당하는 방식으로 풀어봤어요.

공백 문자(정확히는 whitespace문자) 다음에 공백이 아닌 문자가 오면 단어로 세는거죠!

즉 단어의 시작점을 단어세는 기준으로 잡는 것~~ 그런데 처음은 공백으로 시작한다는 보장이 없으니 예외처리 해준 것 뿐이죠 ㅎㅎ

 

scanf가 원래는 space를 기준으로 입력을 받지만, 서식을 지정하여 공백을 받을 수 있게 할 수 있습니다.

scanf와 whitespace를 판별해주는 ctype.h 라이브러리의 isspace 함수를 이용해서 작성해봤어요.

 

[C 언어 XOR 연산자 ]

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
    char str[100];
    int count = 0;
    int i ;

    printf("문장을 입력하세요 :");
    gets_s(str, sizeof(str));

    if (!isspace(str[0])) count++;
    if (!isspace(str[strlen(str)])) count++;
    for (i = 0; i < strlen(str)-1; i++)
    {
        if (isspace(str[i]) ^ isspace(str[i+1])) //XOR이용해서 한번에 끝내기 
            count++;
    }
    printf("%d\n", count /2);
    return 0;
}

 XOR연산자를 이용해서 3번째 방식대로 풀이해줬어요. 단어 처음과 끝 모두를 센거니 마지막에 나누기 2를 해줘야겠죠?

 

[C++ getline함수와 향상된 for문]

#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
    string str;
    int count = 0;
    char temp = 0x20;
    printf("문장을 입력하세요 :");
    getline(cin, str);
    for (char ch : str)
    {
        if (isspace(temp) ^ isspace(ch)) //XOR이용해서 한번에 끝내기 
            count++;
        temp = ch;
    }
    printf("%d\n", (count % 2) ? (count/2)+1: count/2);
    return 0;
}

이번에는 C++언어로 변경해서 풀어봤습니다. 한 줄 읽는 getline함수를 사용해봤어요.

temp는 이전 문자라면 ch는 현재 문자가 되겠죠?

 

[자료구조 스택 구현해서 풀기]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct _Stack
{
	int top = 0;
	char pvalue[10][100]{}; //최대단어 10개 하나의 단어는 100글자 가정 
}Stack;
void push(Stack* stack, char* str, int size)
{
	strncpy(stack->pvalue[stack->top], str, size);
	stack->pvalue[stack->top][size] = '\0';
	stack->top++;
}
char* pop(Stack* stack)
{
	stack->top--;
	return stack->pvalue[stack->top];

}
int main()
{
  	Stack st;
	char arr[100] = { 0, };
	int index = 0;
	scanf("%[^\n]s", arr);
	for (int i = 0; i < strlen(arr); ++i) {
		if (isalpha(arr[i]) && !index){ //단어는 영문자로만 이뤄진다고 가정하자.
				index = i;
		}
		else if (isspace(arr[i])){
			if(index>0)
				push(&st, arr+index, i-index);
			index = 0;
		} 
		if (i == strlen(arr) - 1 && !isspace(arr[i])) {
			push(&st, arr + index, i - index+1);
		}
	}
	printf("단어개수 %d\n", st.top);
	printf("마지막에 들어있는 단어: %s", pop(&st));
	return 0;
}

스택에 단어를 하나씩 넣고 저장된 단어의 수를 리턴하는 코드로 작성해봤어요 ㅎㅎ

 

[ 자바 JAVA - trim과 replaceAll ]

import java.util.Scanner;
public class Main {

	public static void main(String[] args) {
		String str; 
        int cnt = 0; int  i;
		System.out.println("문장을 입력하세요:");
		Scanner sc = new Scanner(System.in);
		str = sc.nextLine();
		
		//연속된 공백을 하나의 공백으로 치환   
		str = str.replaceAll(" +", " ");
		//trim으로 앞뒤 공백 제거 
		str = str.trim();
		
		for ( i =0 ;i<str.length(); i++) {
			if (' ' == str.charAt(i))
				cnt++;
		}
		if (i != 0 ) cnt++;
		System.out.println(cnt);
	}
}

이번에는 자바 풀이입니다. 자바는 String클래스 자체에 trim을 제공하고 있어서, trim을 이용해봤어요.

또 C++과는 다르게 replace가 정규식을 지원하죠. ㅎㅎ 

 

사이사이 연속된 공백들을 하나로 제거하고 앞뒤 공백을 제거한 뒤, 

단어의 개수는 공백의 개수보다 한 개가 더 많다는 점을 활용해봤습니다. (물론 단어가 하나도 안들어왔을 때는 예외처리!) 

 

오늘은 간단한 문제를 풀이해봤어요 ㅎㅎ

도움이 되셨다면 공감어떤가요? 다음 포스팅에서 봐요 

반응형