자바 계산기 만 들 기

이 블 로 그 는 자바 로 계산 기 를 작성 하여 산수 표현 식 을 계산 합 니 다.이 표현 식 은 덧셈 과 곱셈,임의의 차원 의 괄호 내장 을 지원 합 니 다(괄호 만 지원 합 니 다).
아이디어 디자인
우선 생각 을 토론 하 다.만약 에 하나의 산수 표현 식 이(2 + 1) + 200 * 3.2 / (5 * (2 + 6 ))이 라 고 가정 하면 우 리 는 우선 순위 에 따라 가장 안쪽 괄호 안의 표현 식 을 계산 한 다음 에 바깥쪽 괄호 를 계산 해 야 한다.괄호 가 없 는 일반 덧셈 과 곱셈 표현 식 으로 진화 할 때 까지 최종 적 으로 결 과 를 얻 을 수 있다.
코드 디자인:서브 프로 세 스:computeFlatExp(String flatExp)함 수 는 괄호 가 없 는 가감 승제 표현 식 을 계산 하 는 데 사 용 됩 니 다.이 는 먼저 교대 훈련 으로 곱 하기 와 제 거 를 계산 한 다음 에 교대 훈련 으로 추가 와 감 소 를 계산 하여 최종 결 과 를 얻 을 때 까지 계산 합 니 다.
주 프로 세 스:닫 힌 괄호 를 계속 발견 한 다음computeFlatExp()함수 로 글자 표현 식 의 결 과 를 계산 하여 산수 표현 식 을 간소화 합 니 다.산수 표현 식 으로 간략화 할 때 까지 괄호 위 치 를 포함 하지 않 고 마지막 으로 한 번computeFlatExp()함수 로 최종 결 과 를 얻 을 수 있 습 니 다.
코드 및 분석
구체 적 인 코드 의 실현 을 살 펴 보 겠 습 니 다.먼저 보 자computeFlatExp().
computeFlatExp()서브 프로 세 스
private double computeFlatExp(String flatExp) {
    //             
    Pattern pattern = Pattern.compile("(?[\\d\\.]+)\\s*(?[\\*/])\\s*?(?[\\d\\.]+)");
    Matcher matcher = pattern.matcher(flatExp);
    while (matcher.find()) {
        double num1 = Double.parseDouble(matcher.group("num1"));
        double num2 = Double.parseDouble(matcher.group("num2"));
        String operator = matcher.group("operator");
        double result = operator.contains("*") ? num1 * num2 : num1 / num2;
        flatExp = flatExp.replace(matcher.group(0), String.valueOf(result));
        matcher = pattern.matcher(flatExp);
    }

    //             
    pattern = Pattern.compile("(?[\\d\\.]+)\\s*(?[\\+\\-])\\s*?(?[\\d\\.]+)");
    matcher = pattern.matcher(flatExp);
    while (matcher.find()) {
        Double num1 = Double.parseDouble(matcher.group("num1"));
        Double num2 = Double.parseDouble(matcher.group("num2"));
        String operator = matcher.group("operator");
        double result = operator.contains("+") ? num1 + num2 : num1 - num2;
        flatExp = flatExp.replace(matcher.group(0), String.valueOf(result));
        matcher = pattern.matcher(flatExp);
    }

    return Double.parseDouble(flatExp.trim());
}

위의 코드 사고방식 은 비교적 간단 하 다.주요 한 수단 은 바로 정규 표현 식 에 의존 하 는 것 이다.나 는 지난 블 로그 에서 자바 에서 정규 표현 식 을 사용 하 는 방식 을 논 의 했 는데 이번 에는 잘 써 야 한다.이것 은 왼쪽 에서 오른쪽으로 모든 곱셈 과 나눗셈 의 이원 표현 식 을 순서대로 캡 처 하고 계산 한 다음 에 왼쪽 에서 오른쪽으로 모든 덧셈 표현 식 이나 뺄셈 이원 표현 식 을 캡 처 하여 마지막 숫자 가 남 을 때 까지 계산 한 다음 에 이 표현 식 을 숫자 로 바 꾸 고 Double 의 대상 으로 되 돌려 줍 니 다.
메 인 프로 세 스
메 인 프로 세 스 코드 를 다시 보 겠 습 니 다.
public double compute(String expression) {
    int start = -1;
    for (int i = 0; i < expression.length(); i++) {
        if (expression.charAt(i) == '(') {
            start = i;
        }
        if (expression.charAt(i) == ')') {
            //        
            String flatExp = expression.substring(start + 1, i);
            double result = computeFlatExp(flatExp);
            StringBuilder sb = new StringBuilder();
            if (start > 0) {
                sb.append(expression.substring(0, start));
            }
            sb.append(String.valueOf(result));
            if (i < expression.length() - 1) {
                sb.append(expression.substring(i + 1));
            }
            return compute(sb.toString());
        }
    }

    //       
    return computeFlatExp(expression);
}

위의 코드 는 먼저 가장 오른쪽 에 있 는 왼쪽 괄호 를 기록 하고 오른쪽 괄호 를 만나면 일치 하 는 괄호 를 찾 았 다 는 것 을 의미한다.이런 방식 으로 괄호 의 끼 워 넣 기 를 처리 하 는 것 이 비교적 유용 하 다.일치 하 는 괄호 를 찾 으 면1.2 * 3.4하위 프로 세 스 를 호출 하여 일치 하 는 표현 식 을 계산 하고 계산 결 과 를 원본 표현 식 으로 대체 하여 전체 원본 표현 식 을 간소화 합 니 다.이 과정 을 계속 반복 하면 서 모든 괄호 의 하위 표현 식 을 계산 하여 모든 괄호 를 제거 합 니 다.마지막 으로 하위 과정5.6 / 7.8을 한 번 더 호출 하여 최종 결 과 를 얻 었 다.
호출 방식
이 계산기 의 외부 호출 방식 을 다시 한 번 봅 시다.
public static void main(String[] args) {
    MyCalculator cal = new MyCalculator();
    double result = cal.compute("(2 + 1) + 200 * 3.2 / (5 * (2 + 6 ))");
}

위의 표현 식 의 계산 결 과 는 19.0 이다.
완전한 코드
다음은 완전한 코드 입 니 다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyCalculator {
    public double compute(String expression) {
        int start = -1;
        for (int i = 0; i < expression.length(); i++) {
            if (expression.charAt(i) == '(') {
                start = i;
            }
            if (expression.charAt(i) == ')') {
                //        
                String flatExp = expression.substring(start + 1, i);
                double result = computeFlatExp(flatExp);
                StringBuilder sb = new StringBuilder();
                if (start > 0) {
                    sb.append(expression.substring(0, start));
                }
                sb.append(String.valueOf(result));
                if (i < expression.length() - 1) {
                    sb.append(expression.substring(i + 1));
                }
                return compute(sb.toString());
            }
        }

        //       
        return computeFlatExp(expression);
    }


    /**
     *       ,    
     *
     * @param flatExp
     * @return
     */
    private double computeFlatExp(String flatExp) {
        //             
        Pattern pattern = Pattern.compile("(?[\\d\\.]+)\\s*(?[\\*/])\\s*?(?[\\d\\.]+)");
        Matcher matcher = pattern.matcher(flatExp);
        while (matcher.find()) {
            double num1 = Double.parseDouble(matcher.group("num1"));
            double num2 = Double.parseDouble(matcher.group("num2"));
            String operator = matcher.group("operator");
            double result = operator.contains("*") ? num1 * num2 : num1 / num2;
            flatExp = flatExp.replace(matcher.group(0), String.valueOf(result));
            matcher = pattern.matcher(flatExp);
        }

        //             
        pattern = Pattern.compile("(?[\\d\\.]+)\\s*(?[\\+\\-])\\s*?(?[\\d\\.]+)");
        matcher = pattern.matcher(flatExp);
        while (matcher.find()) {
            Double num1 = Double.parseDouble(matcher.group("num1"));
            Double num2 = Double.parseDouble(matcher.group("num2"));
            String operator = matcher.group("operator");
            double result = operator.contains("+") ? num1 + num2 : num1 - num2;
            flatExp = flatExp.replace(matcher.group(0), String.valueOf(result));
            matcher = pattern.matcher(flatExp);
        }

        return Double.parseDouble(flatExp.trim());
    }



    public static void main(String[] args) {
        MyCalculator cal = new MyCalculator();
        double result = cal.compute("(2 + 1) + 200 * 3.2 / (5 * (2 + 6 ))");
    }
}

만약 당신 이 의문 이 있 거나 더 좋 은 방안 이 있다 면,평론 구역 에서 나 와 토론 하 는 것 을 환영 합 니 다.

좋은 웹페이지 즐겨찾기