ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 스튜디오 계산기(3): CalculateHelper 클래스 추가, 빌드
    Java/Android Studio 2020. 9. 10. 17:46

    이제 CalculateHelper 클래스를 추가해보자

     

    4. CalculateHelper 클래스 추가

     

     

    [File]-[New]-[Java Class]를 통해 클래스를 추가한다.

     

    내용은 다음과 같이 작성한다.

     

     

    [CalculateHelper.java]

    package com.example.dumb;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Stack;

    public class CalculateHelper {
    public static double num1;
    public static double num2;
    public static double resultNumber;

    private ArrayList splitTokens(String equation){
    String[] constant = equation.split(" ");

    ArrayList constantList = new ArrayList();
    double number=0;

    boolean flag= false;
    for(String data:constant){
    if(data.equals(" ")){
    continue;
    }
    if(checkNumber(data)){
    number = number*10+Double.parseDouble(data);
    flag=true;
    }
    else{
    if(flag){
    constantList.add(number);
    number=0;
    }
    flag=false;
    constantList.add(data);
    }
    }

    if(flag){
    constantList.add(number);
    }

    return constantList;
    }

    private ArrayList infixToPostfix(ArrayList constant){
    ArrayList result= new ArrayList();
    HashMap level = new HashMap();
    Stack stack = new Stack();

    level.put("*",3);
    level.put("/",3);
    level.put("+",2);
    level.put("-",2);
    level.put("(",1);

    for(Object object : constant){
    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }
    return result;
    }

    private Double postFixEval(ArrayList expr){
    Stack numberStack = new Stack();
    for(Object o : expr){
    if(o instanceof Double){
    numberStack.push(o);
    }else if(o.equals("+")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2+num1);
    }else if(o.equals("-")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2-num1);
    }else if(o.equals("*")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2*num1);
    }else if(o.equals("/")){
    num1=(Double)numberStack.pop();
    num2=(Double)numberStack.pop();
    numberStack.push(num2/num1);
    }
    }
    resultNumber = (Double)numberStack.pop();

    return resultNumber;
    }

    public Double process(String equation){
    ArrayList postfix = infixToPostfix(splitTokens(equation));
    Double result = postFixEval(postfix);
    return result;
    }

    public boolean checkNumber(String str){
    char check;

    if(str.equals("")){
    return false;
    }

    for(int i=0;i<str.length();i++){
    check=str.charAt(i);
    if(check<48||check>58){
    if(check!='.')
    return false;
    }
    }

    return true;
    }

    }

     

    CalculatorHelper 클래스는 앞서 입력한 계산식을 후위 표기법으로 바꾼 후 연산을 실행한다. 

     

     

     

    CalculateHelper에는 splitTokens, infixToPostfix, postFixEval, process, checkNumber 함수가 있다.

     

     

    [CalculateHelper.splitTokens] : 연산식을 ArrayList에 담아 반환한다.

     

     

     

    jamanbbo.tistory.com/53

     

    [Stack]사칙연산 계산기 구현(1) - 후위 표기법

    사칙연산 계산기 구현 - 후위 표기법 사칙연산 프로그램을 만들 때 사용하는 수식의 표현법이다. 보통 우리가 사용하는 수식은 중위 표기법으로 표현된다. 중위 표기법은 연산자가 피연산자들��

    jamanbbo.tistory.com

    이 글을 보면 스택 계산기의 후위 표기법에 대해 아주 잘 나타나 있다. 

     

     

    [CalculateHelper.infixToPostfix] : 중위 표기법을 후위 표기법으로 바꾼다.

    private ArrayList infixToPostfix(ArrayList constant){
    ArrayList result= new ArrayList();
    HashMap level = new HashMap();
    Stack stack = new Stack();

    level.put("*",3);
    level.put("/",3);
    level.put("+",2);
    level.put("-",2);
    level.put("(",1);

    for(Object object : constant){
    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }
    return result;
    }

     

    해쉬맵을 통해 우선순위를 곱셈, 나눗셈은 3, 덧셈 뺄셈은 2, 여는 괄호는 1로 설정해놨다.

     

    if(object.equals(")")){
    stack.push(object);
    }else if(object.equals(")")){
    while(!stack.peek().equals("(")){
    Object val = stack.pop();
    if(!val.equals("(")){
    result.add(val);
    }
    }
    stack.pop();
    }

    여는 괄호가 나오면 무조건 스택에 넣고 닫는 괄호가 나오면 여는 괄호까지의 모든 내용을 pop 한다.

     

    else if(level.containsKey(object)){
    if(stack.isEmpty()){
    stack.push(object);
    }else{
    if(Double.parseDouble(level.get(stack.peek()).toString()) >= Double.parseDouble(level.get(object).toString())){
    result.add(stack.pop());
    stack.push(object);
    }else{
    stack.push(object);
    }
    }
    }else{
    result.add(object);
    }
    }
    while(!stack.isEmpty()){
    result.add(stack.pop());
    }

    우선순위가 높은게 나오면 pop해서 result에 추가하고 낮은걸 스택에 쌓는다.

     

     

     

    [CalculateHelper.postFixEval]: 후위표기법의 식을 계산한다.

     

     

    후위 표기법의 식을 탐색한다. 숫자가 나올경우 스택에 Push하고 연산자가 나올 경우 첫번째 pop한 수와 두번째로 pop

    한 수에 연산을 한다.

     

    [CalculateHelper.process]: 최종적으로 계산값을 리턴하는 함수

    public Double process(String equation){
    ArrayList postfix = infixToPostfix(splitTokens(equation));
    Double result = postFixEval(postfix);
    return result;
    }

     

     

    [CalculateHelper.checkNumber]: 아스키코드로 숫자인지 판별해 boolean값을 반환하는 함수 

    public boolean checkNumber(String str){
    char check;

    if(str.equals("")){
    return false;
    }

    for(int i=0;i<str.length();i++){
    check=str.charAt(i);
    if(check<48||check>58){
    if(check!='.')
    return false;
    }
    }

    return true;
    }

     

     

     

    5. 앱 아이콘 변경, 빌드

    다음으로 앱 아이콘을 바꾸고 빌드해보자.

     

    [File]-[New]-[Image Asset]을 클릭한다.

     

     

    Select Path로 이미지가 저장된 경로를 연다.

     

     

    이미지를 선택하고 적당한 크기로 조절한다.

     

    기존의 아이콘(좌)와 바뀐 아이콘(우)

    아이콘이 바뀌었음을 확인할 수 있다.

     

    https://developer.android.com/studio/run?hl=ko
    https://developer.android.com/studio/run?hl=ko

     

    이렇게 에뮬레이터 대신 실제 기기로 실행해보면 어플이 기기에 배포된다. Google Play에 공유, 업로드 할 앱을 빌드하려면 다음과 같이 하면 된다.

     

    [Build]-[Build Bundle(s) / APK(s)]-[Build APK(s)] 

     

     

Designed by Tistory.