계산식 문자열 필터링, 파싱

2024. 4. 23. 14:51개발자 과정/Kotlin

https://n-pureun.tistory.com/135

 

계산기 만들기

추상화 클래스를 통해 계산기를 만들라는 과제를 받았다. 계산기는 지독하리 만치 만든바... c언어 배울시절... ???: 변수와 연산자 배웠죠? 계산기 만들어봐요 ???: 조건문 배웠죠? 계산기 만들어

n-pureun.tistory.com

해당 글에서 이어진다. 

계산기를 만들고, 소수와 음수에 대한 예외처리를 한 후, 스페이스바임의 구분하던 계산식알고리즘적용하여,

연산자숫자추출하여 프로그램에 맞는 폼으로 포맷하는 기능을 추가하려 한다. 

 

사용자 대화 함수

 /**사용자와의 대화 함수*/
    private fun inputCalculate(): String
    {
        print("식을 적으세요(앞에 $ 붙이면 연쇄수식 호출 / x= 종료) : ")
        val inputString=readln()
        if(inputString.find { it=='x' }!=null)
            return "Exit"
        else if(inputString.isBlank()) return "-1"
        return convertString(inputString)
    }

= 사용자와 대화하는 구간에 분기를 추가하여 종료공백문자를 구분하고, 조건을 통과하면 문자열 변환함수진입한다. 

 

문자열 필터링

private fun stringFilter(inputString: String):String{
    val calc = StringBuilder()

    val operators = listOf('(', ')', '+', '-', '*', '/', '%')
    inputString.forEach {
        if(it.isDigit()||it in operators || it=='.')
            calc.append(it.toString())
    }

    println("문자열 필터링: $calc")
    return calc.toString()
}

= 우선 입력받은 문자열연산자숫자도출하는 로직을 통해 계산식을 도출한다. 

이를 통해 불필요한 문자와 공백을 일단 없애놓는다. 

 

결과 예시

이 이후 적절한 조건문으로 음수소수에 대한 처리와, 계산식프로그램에 맞게 포맷하는 과정에 돌입한다. 

 

문자열 변환

/**입력받은 문자열 변환함수*/
private fun convertString(inputString: String): String {
    val calc=stringFilter(inputString)//우선 문자열 필터링
    var str = ""

    val operators = listOf('(', ')', '+', '-', '*', '/', '%')
    calc.forEachIndexed { i, it ->
        if (it == '.' &&
            (i - 1 in calc.indices && calc[i - 1].isDigit()) &&
            (i + 1 in calc.indices && calc[i + 1].isDigit())
        ) {
            str += it
        } else if (it in operators) {
            str += " "
            if (i == 0 && it == '-') str += it
            else if (it == '-' && calc[i - 1] in operators)
                str += it
            else str += "$it "
        } else if (it.isDigit()) {
            str += it
        }
    }
    println("문자열 포맷: $str")

    //여기서 사용자 설정 다시 받음
    return if (str.isBlank()) "-1" else
        if (inputString.first() == '$') "$$str" else str
}

= 현재 문자가 '.' 이라면 앞뒤에 숫자가 붙어 있는지(소수의 형태는  최소 0.0이여야 함),

문자가 연산자라면 우선 공백을 넣고(숫자와의 구분),

'-'라면 이것이 식의 첫시작인지, 문자 앞에 연산자가 있는지 등을 체크하고 그에따라 문자를 다르게 붙인다.

(음수표현이라면 뒤에 공백이 없어야 하고 , -연산자라면 공백이 존재해야 한다.

그외의 경우는 인정하지 않아 연산자로 취급해 공백을 붙인다.)

그리고 숫자라면 공백없이 문자열을 누적한다. 

해당로직의 형태로 앞서 문자열 필터링에서 걸러지지 않은 문자한 번 더 걸러낸다. 

 

결과 예시

소수점을 위해 필터링되지 않는 '.'이 해당 함수를 통해 걸러짐

그 후 공백문자열이 반환되면 그에 따른 예외처리와, 추후에 설명할 연쇄수식을 위한 마킹도 한다. 

 

이것으로 프로그램에 맞는 문자열 변환 알고리즘을 구현하였다. 

 

결과

'개발자 과정 > Kotlin' 카테고리의 다른 글

계산기 프로젝트 최종  (0) 2024.04.24
연쇄수식 계산기  (0) 2024.04.23
계산기 만들기  (0) 2024.04.22
(코딩테스트) 기사단원  (0) 2024.04.17
(코딩테스트) 덧칠하기 (코틀린에서 index skip)  (0) 2024.04.17