Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 주어진 문자열이 유효한 숫자인지 확인하는 방법

문제 개념

주어진 문자열이 유효한 숫자(numeric)인지 판별하는 프로그램을 작성해야 합니다. 단순히 숫자 형태처럼 보이는지만 확인하는 것이 아니라, 소수점과 지수 표기까지 포함해 엄격하게 검증해야 합니다.

입력 − str = "12.5"

출력 − true

입력 − str = "def"

출력 − false

입력 − str = "2e5"

출력 − true

입력 − str = "10e4.4"

출력 − false

접근 방법

문자열이 유효한 숫자인지 확인하려면 코드에서 다음과 같은 경우들을 반드시 처리해야 합니다.

  • 문자열 앞뒤에 있는 선행·후행 공백은 무시합니다.
  • 문자열 시작 부분의 '+', '-', '.' 기호는 허용합니다.
  • 문자열을 구성하는 모든 문자는 {+, -, ., e, [0-9]} 집합에 속해야 합니다.
  • 'e' 뒤에는 '.'이 나올 수 없습니다.
  • '.' 문자 다음에는 반드시 숫자가 이어져야 합니다.
  • 'e' 문자 뒤에는 '+', '-', 또는 숫자 중 하나가 와야 합니다.

동작 원리

먼저 두 포인터를 이용해 문자열 양 끝의 공백을 제거하고, 남은 구간이 비어 있거나 첫 문자가 유효하지 않으면 즉시 실패를 반환합니다. 이후 문자열을 한 글자씩 순회하면서 각 문자가 허용된 집합에 속하는지 검사하고, 소수점('.')과 지수('e')가 등장하는 위치와 그 뒤에 오는 문자의 조합이 올바른지 확인합니다. 모든 검사를 통과하면 해당 문자열은 유효한 숫자입니다. 전체 탐색은 문자열 길이 n에 대해 선형으로 진행되므로 시간 복잡도는 O(n)입니다.

예제 코드

// C++ program to check if input number
// is a valid number
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
int valid_number1(string str1){
    int i = 0, j = str1.length() - 1;
    while (i < str1.length() && str1[i] == ' ')
        i++;
    while (j >= 0 && str1[j] == ' ')
        j--;
    if (i > j)
        return 0;
    if (i == j && !(str1[i] >= '0' && str1[i] <= '9'))
        return 0;
    if (str1[i] != '.' && str1[i] != '+' && str1[i] != '-' && !(str1[i] >= '0' && str1[i] <= '9'))
        return 0;
    bool flagDotOrE = false;
    for (i; i <= j; i++) {
        // If any of the char does not belong to
        // {digit, +, -, ., e}
        if (str1[i] != 'e' && str1[i] != '.'
        && str1[i] != '+' && str1[i] != '-'
        && !(str1[i] >= '0' && str1[i] <= '9'))
        return 0;
        if (str1[i] == '.') {
            if (flagDotOrE == true)
                return 0;
            if (i + 1 > str1.length())
                return 0;
            if (!(str1[i + 1] >= '0' && str1[i + 1] <= '9'))
                return 0;
        }
        else if (str1[i] == 'e') {
            flagDotOrE = true;
            if (!(str1[i - 1] >= '0' && str1[i - 1] <= '9'))
                return 0;
            if (i + 1 > str1.length())
                return 0;
            if (str1[i + 1] != '+' && str1[i + 1] != '-'
                && (str1[i + 1] >= '0' && str1[i] <= '9'))
            return 0;
        }
    }
    return 1;
}
// Driver code
int main(){
    char str1[] = "0.1e10";
    if (valid_number1(str1))
        cout << "true";
    else
        cout << "false";
    return 0;
}

출력 결과

true

마무리

위 예제에서 입력 문자열 "0.1e10"은 소수점과 지수 표기를 모두 포함하지만 각 규칙을 만족하므로 true가 출력됩니다. 반면 "10e4.4"처럼 지수(e) 뒤에 소수점이 등장하는 문자열은 규칙 위반으로 false를 반환하게 됩니다. 이러한 단계별 검증 방식은 정규표현식 없이도 문자열 숫자 판별 문제를 안정적으로 해결할 수 있는 실용적인 접근 방법입니다.