Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Строчный калькулятор, Помогите плиз 
:(
    Опции темы
Shuma
Дата 26.4.2008, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 15.5.2007
Где: Беларусь, Гомель

Репутация: нет
Всего: 2



Привет.
Народ посоветуйте плиз подход для решения:
Нужен калькулятор который получает на вход выражение в виде строки(вводит пользователь)
и собственно вычисляет. В выражении могут быть цифры с дробной частью,+-*/,и любая степень вложенности скобок.
Собственно прошу посоветовать какими средствами лучше пользоватся может с небольшими примерами.
Думал разделить строку на 2 массива: первый для числовой части, второй для операций...все бы хорошо но вроде с вложенными скобками будут проблемы...
Спасибо.
PM MAIL ICQ   Вверх
man_without_face
Дата 26.4.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 1.4.2008

Репутация: нет
Всего: 1



а не проще распарсить строку с выражением? при обнаружении например "+" - складываешь число перед ним. ну и т.д. Только про скобки не забывать.
PM MAIL   Вверх
Shuma
Дата 26.4.2008, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 15.5.2007
Где: Беларусь, Гомель

Репутация: нет
Всего: 2



Пример плиз если можно...я в джаве ньюбл.
PM MAIL ICQ   Вверх
SoulKeeper
Дата 27.4.2008, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.1.2007
Где: Ukraine, Lviv.

Репутация: 11
Всего: 15



Код

import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
import java.io.Console;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Calc {

    private final ScriptEngine javaScriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");

    public Calc() {
    }

    public void readLine() {

        System.out.println("Console calculator initialized. Enter expression or \"exit\" to exit.");

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String string = null;
        try {
            while (!"exit".equals((string = reader.readLine()))) {
                calcResult(string);
                System.out.println("Enter new expression:");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
//                e.printStackTrace();
            }
        }

        System.out.println("Bye-Bye");
    }

    private void calcResult(String input) {
        Object result = null;

        try {
            result = javaScriptEngine.eval(input);
        } catch (ScriptException e) {
            //e.printStackTrace();
            System.err.println("Exception while calculating result: " + e);
        }

        if (result instanceof Number) {
            Number number = (Number) result;
            System.out.println("Result: " + number);
        } else {
            System.out.println("Result of expression is NaN");
        }
    }

    public static void main(String[] args) {
        new Calc().readLine();
    }
}


PM MAIL   Вверх
Shuma
Дата 28.4.2008, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 15.5.2007
Где: Беларусь, Гомель

Репутация: нет
Всего: 2



Спасибо большое, правда думал свое написать а не скрипт готовый...хотя зачем изобретать велосипед.
Спасибо еще раз.
PM MAIL ICQ   Вверх
Zlatogorov
Дата 28.4.2008, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 18.12.2007
Где: BW,Stuttgart

Репутация: нет
Всего: 1



Shuma
Обратите внимание на ANTLR. Там можно написать парсер обрабатывающий выражения типа: x=3 y=5 z=2  x+y*z

PM MAIL ICQ   Вверх
garbuz
Дата 28.4.2008, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 3
Всего: 11



Задача не так тривиальна, как кажется на первый взгляд, сам когда-то сталкивался с этой задачей. Почитай "Полный справочник по C#" Шилдта, там в конце книги описано пример - синтаксический анализ методом рекурсивного спуска, как раз то, что надо.
PM MAIL   Вверх
brejnev
Дата 28.4.2008, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 18.9.2005

Репутация: нет
Всего: нет



У нас в универе такая лаба была. Решение - набрать в гугле "обратная польская нотация". И еще есть куча алгоритмов, ищется тож в гугле по фразе "синтаксический разбор выражений" или что-то типо того.
PM MAIL   Вверх
SoulKeeper
Дата 28.4.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.1.2007
Где: Ukraine, Lviv.

Репутация: 11
Всего: 15



Велосипедисты smile
PM MAIL   Вверх
Shuma
Дата 29.4.2008, 04:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 15.5.2007
Где: Беларусь, Гомель

Репутация: нет
Всего: 2



Спасиб народ.
PM MAIL ICQ   Вверх
Shuma
Дата 13.5.2008, 07:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 15.5.2007
Где: Беларусь, Гомель

Репутация: нет
Всего: 2



Собственно вот мое решение без использования скрипта(для велосипедистов или если дана установка " писать свое"),надеюсь кому-нить пригодится...если кто найдет баг сообщите плиз. Решение несколько топорное, можно и увеличить скорость и сжать размер(но надо ли это для такой задачи?), да и алгоритм не самый лучший наверно.
Код

package Homework;
//<Import>
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/**
 *@about This is program named "calculator", for calculating string entered by user.
 * 
 *@author Shumilin "Shuma" Alexandr
 */
public class Calculator //Main class
{
    private StringBuilder cstring = new StringBuilder();//for user string storage
    private boolean PlusSign = true;//saving result sign
    private int CloseBracket,OpenBracket;//saving start and finish substring positions
    private int FinishPos = 0, StartPos = 0;//saving start and finish expression part positions
    
    public void readLine() //user string reader
    {
        System.out.println("Enter expression or \"exit\" to exit ");

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String exprString = null;
        try 
        {
            while(!(exprString = reader.readLine()).equals("exit"))
            {
                calculate(exprString);
                if (PlusSign == true) 
                {
                    System.out.println("Result: "+cstring);
                } else 
                {
                    cstring.insert(0, '-');
                    System.out.println("Result: "+cstring);
                }
                PlusSign = true;
                System.out.println("Enter new expression:");  
            }
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
         catch(NumberFormatException a)
        {
            System.out.println("ERROR!");
             System.out.println("Enter expression or \"exit\" to exit ");
        try 
        {
            while(!(exprString = reader.readLine()).equals("exit"))
            {
                calculate(exprString);
                if (PlusSign == true) 
                {
                    System.out.println("Result: "+cstring);
                } else 
                {
                    cstring.insert(0, '-');
                    System.out.println("Result: "+cstring);
                }
                PlusSign = true;
                System.out.println("Enter new expression:");  
            }
        } 
         catch (IOException e)
        {
            e.printStackTrace();
         }   
        }
    }
   
    private int valueCalc(String input)//calculating how many slots are needed for secondary array 
    {
        int Slots = 0;
        for (int i = 0; i < input.length(); i++) 
        {

            if ((input.charAt(i) == '+') || (input.charAt(i) == '-') || 
                    (input.charAt(i) == '*') || (input.charAt(i) == '/')|| 
                    (input.charAt(i) == ')')|| (input.charAt(i) == '(')) 
            {
                Slots++;
            }
        }

        return Slots;

    }
    private void calculate(String input)//main method
    {
        int[] CharsPos = new int[valueCalc(input)+2];//"+2" because also needed 
                                            //start and finish string positions 
        float a = 0, b = 0;//for parse parts
        Float c = null;//result between parts
         cstring.delete(0, cstring.length());//cleaning
         cstring.append(input);
        /////////////////////////////////////////////////////////////////////////
//<first priority block>        
        for (int i = 0; i < cstring.length(); i++) 
        {
            if(cstring.charAt(i)=='(')
            {
                OpenBracket=i;
            }
            if(cstring.charAt(i)==')')//for locating max priority 
            {
                CloseBracket=i;
                String subString=new String();
                subString=cstring.substring(OpenBracket+1, CloseBracket);
                cstring.delete(OpenBracket, CloseBracket+1);
                StringBuilder mainString=new StringBuilder(cstring);
                calculate(subString);
                mainString.insert(OpenBracket,cstring.toString());
                cstring.delete(0, cstring.length());
                cstring.insert(0, mainString.toString());
                calculate(cstring.toString());
            }
        }
//</first priority block>        
        ////////////////////////////////////////////////////////////////////////
//<secondary priority block>
        for (int i = 0; i < cstring.length(); i++) 
       {
           if (cstring.charAt(i) == '*')
            {
                CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
                 for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                
                a = Float.parseFloat(cstring.substring(StartPos, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(StartPos, FinishPos);
                c = a * b;
                cstring.insert(StartPos, c.toString());
                calculate(cstring.toString());
                break;
            }
           if (cstring.charAt(i) == '/')
            {
                      CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
                 for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                
                a = Float.parseFloat(cstring.substring(StartPos, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(StartPos, FinishPos);
                c = a / b;
                cstring.insert(StartPos, c.toString());
                calculate(cstring.toString());
                break;
            }
            
        }
         for (int i = 0; i < cstring.length(); i++) 
        {
            if ((cstring.charAt(i) == '*') || (cstring.charAt(i) == '/')) 
            {
                calculate(cstring.toString());
            }
        }
//</secondary priority block>         
        ////////////////////////////////////////////////////////////////////////
 //<third priority block>
        for (int i = 0; i < cstring.length(); i++)
        {
            if ((cstring.charAt(i) == '+') && (PlusSign == true)) 
            {
                       CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
               for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                a = Float.parseFloat(cstring.substring(StartPos, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(StartPos, FinishPos);
                c = a + b;
                cstring.insert(StartPos, c.toString());
                break;
            }

            if ((cstring.charAt(i) == '+') && (PlusSign == false)) 
            {
                       CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
                 for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                a = Float.parseFloat(cstring.substring(0, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(0, FinishPos);
                if (b > a) 
                {
                    c = b - a;
                    PlusSign = true;
                } 
                else 
                {
                    c = a - b;
                }
                cstring.insert(0, c.toString());
                break;
            }

            if ((cstring.charAt(i) == '-') && (PlusSign == true)) 
            {
                       CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
                 for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                a = Float.parseFloat(cstring.substring(0, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(0, FinishPos);
                if (b > a) 
                {
                    c = b - a;
                    PlusSign = false;
                } 
                else 
                {
                    c = a - b;
                }
                cstring.insert(0, c.toString());
                break;
            }

            if ((cstring.charAt(i) == '-') && (PlusSign == false)) 
            {
                       CharsPos[0]=0;
        for (int j = 0,  k = 1; j < cstring.length()-1; j++) 
        {
            if ((cstring.charAt(j) == '+') || (cstring.charAt(j) == '-') || 
                    (cstring.charAt(j) == '*') || (cstring.charAt(j) == '/')||
                    (cstring.charAt(j) == '(')|| (cstring.charAt(j) == ')')) 
            {
                CharsPos[k] = j+1;
                k++;
            }
            CharsPos[CharsPos.length-1]=cstring.length()+1;
        }
                 for(int k=0;k<CharsPos.length;k++)
                {
                    
                    if(CharsPos[k]==i+1)
                    {
                        StartPos=CharsPos[k-1];
                        FinishPos=CharsPos[k+1]-1;  
                    }
                }
                a = Float.parseFloat(cstring.substring(0, i));
                b = Float.parseFloat(cstring.substring(i + 1, FinishPos));
                cstring.delete(0, FinishPos);
                c = a + b;
                cstring.insert(0, c.toString());
                break;
            }
        }
        for (int i = 0; i < cstring.length(); i++) 
        {
            if ((cstring.charAt(i) == '+') || (cstring.charAt(i) == '-')) 
            {
                calculate(cstring.toString());
            }
        }

    }
 //</third priority block>
    public static void main(String[] args)
    {
        Calculator calc = new Calculator();
        calc.readLine();
    }
}


Это сообщение отредактировал(а) Shuma - 13.5.2008, 07:08
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0955 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.