Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
0 / 0 / 1
Регистрация: 20.05.2013
Сообщений: 49
1

Абсолютно не понимаю логику своей программы

05.09.2014, 23:02. Показов 1045. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем добрый день! Пишу калькулятор, код представляет из себя просто наработки, но уже сейчас программа работает совсем не так, как я ожидал.

Сразу говорю, это никак не связано с чьей-то странной просьбой сделать калькулятор целиком за аффтора...

Имеем следующий код. Интересует нижняя его часть.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.tsystems.javaschool.tasks;
 
 
public class CalculatorImpl {
    public static void main(String[] args)  
    {
        String cr = "2*4*6*10";
        processingStatement(cr);
    }
    
    public static void processingStatement(String statement)
    {
        String bracket = "";
        Integer currentnum = 0;
//Check whole statement
        for (int i = 0; i < statement.length(); i++) {
            if (statement.charAt(i) == '(') {
//Found the bracket, need to find another.
                for (int k = i; k < statement.length(); k++) {
                    if (statement.charAt(k) == ')') {
                        bracket = statement.substring(i, k);
System.out.println ("bracket = " + bracket);
                        for (int b = 0; b < bracket.length(); b++){
                            if (bracket.charAt(b) == '('){
                                break;
                            } else {
                                for (int s = 0; s < bracket.length(); s++){
                                    bracket += bracket.charAt(s);
                                }
System.out.println("bracket = " + bracket);
                                processingStatement(bracket);
                            }
                        }
                    }
                }
            }           
        }
        String nums[] = statement.split("[*-]");
        for (String q : nums) {
System.out.println("num = " + q);
        }
        String operands[] = statement.split("[0-9]");
        for (String q : operands) {
System.out.println("operand = " + q);
            }
        int i = 0;
        while (i < operands.length) {
System.out.println("Ищем операнды...");
 
            if (operands[i].equals("*")) {
                
System.out.println("Нашли, это №" + i);
System.out.println(nums[i]);
System.out.println(nums[i+1]);
                String n = nums[i-1] + operands[i] + nums[i];
System.out.println("String n = " + n);
                currentnum = Integer.parseInt(nums[i-1]) * Integer.parseInt(nums[i]);
System.out.println("Currentnum сейчас равен " + currentnum);
                statement = statement.replace(n, currentnum.toString());
System.out.println("Мы пытаемся заменить " + n + " на " + currentnum.toString() + " и получаем строку " + statement);
 processingStatement(statement);
break;
}
            i++;
        } 
    }
        
}
И код это по выполнении выдает в консоль вот что:
num = 2
num = 4
num = 6
num = 10
operand =
operand = *
operand = *
operand = *
Ищем операнды...
Ищем операнды...
Нашли, это №1
4
6
String n = 2*4
Currentnum сейчас равен 8
Мы пытаемся заменить 2*4 на 8 и получаем строку 8*6*10
num = 8
num = 6
num = 10
operand =
operand = *
operand = *
Ищем операнды...
Ищем операнды...
Нашли, это №1
6
10
String n = 8*6
Currentnum сейчас равен 48
Мы пытаемся заменить 8*6 на 48 и получаем строку 48*10
num = 48
num = 10
operand =
operand =
operand = *
Ищем операнды...
Ищем операнды...
Ищем операнды...
Нашли, это №2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at com.tsystems.javaschool.tasks.CalculatorImpl.processingStatement(CalculatorImpl. java:53)
at com.tsystems.javaschool.tasks.CalculatorImpl.processingStatement(CalculatorImpl. java:61)
at com.tsystems.javaschool.tasks.CalculatorImpl.processingStatement(CalculatorImpl. java:61)
at com.tsystems.javaschool.tasks.CalculatorImpl.main(CalculatorImpl.java:8)
Собсно, перепробовал уже много чего, однако не понимаю, почему результат именно такой. При получении выражения , скажем x * y, мы находим знак умножения и перемножаем множители с соседними индексами в другом массиве. Это все видно из кода. Но при обработке выражений находятся лишние, "пустые" операнды (знаки сложения, умножения и пр.). И пускай каждый раз лишний знак программа находит, видимо, перед первым множителем, пускай. Но мозг выносит появление ДВУХ пустых знаком при обработке выражения 48*10. Моя логика сломана. Помогите мне.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.09.2014, 23:02
Ответы с готовыми решениями:

Не понимаю логику работы программы
Здравствуйте уважаемые форумчане. У меня при просмотре кода ниже написанной программы возникли...

Ключ для своей программы - как продумать логику
Всем привет, Лазил по Готовым решениям и просвещался. Заинтересовала эта заметка, решил...

Определение количества слов и букв, введенных пользователем (не понимаю логику программы)
Помогите понять некоторые действия программы. Необходимо написать программу, подсчитывающую...

Заплатка для своей программы посредством другой своей программы
Доброго времени... друзья! Есть программа: program Project1; uses Windows; var

2
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
06.09.2014, 12:35 2
Разбивай на функции свой парсер иначе ничего невозможно разобрать. В идеале так вобще отделить калькулятор от парсера.
У меня есть мой завалявшийся парсер на c#, можешь посмотреть для примера:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
namespace SuperModule.parser
{
 
    /// <summary>
    /// Предоставляет возможность распарсить и вычислить сразу целое выражение
    /// </summary>
    class Parser
    {
        private ICalculator calculator;
 
        public Parser(ICalculator calculator)
        {
            this.calculator = calculator;
            calculator.SystemSch = SystemOp.Dec;
        }
 
        /// <summary>
        /// Распарсивает выражение в переданой строке и вычисляет его с помощью calculator
        /// </summary>
        public double Parse(string action)
        {
            action = replacePI(action);
            Result res = PlusMinus(action);
            if (!res.IsEmpty())
                throw new ParseException("Немогу распарсить: " + res.rest);
            return res.acc;
        }
 
        /// <summary>
        /// Выполняет автоподстановку значения числа пи
        /// </summary>
        public String replacePI(string input)
        {
            String piValue = "3.14";
            input.Replace("PI", piValue);
            input.Replace("pi", piValue);
            input.Replace("Pi", piValue);
            input.Replace("pI", piValue);
            return input;
        }
 
        /// <summary>
        /// Вычисляет сложение и вычитание
        /// </summary>
        private Result PlusMinus(string s)
        {
            Result current = MulDiv(s);
            while (!current.IsEmpty() && charIn(current.NextChar(), "+-"))
            {
                char operation = current.NextChar();
                double acc = current.acc;
                current = MulDiv(current.rest.Substring(1));
                calculator.Operands = new object[] { acc, current.acc };
                calculator.Operation = operation == '+' ? Operations.Plus : Operations.Minus;
                current.acc = (double)calculator.Result;
            }
            return current;
        }
 
        /// <summary>
        /// Вычисляет умножение и деление
        /// </summary>
        private Result MulDiv(string s)
        {
            Result current = Bracket(s);
            while(!current.IsEmpty() && charIn(current.NextChar(), "*/"))
            {
                char operation = current.NextChar();
                double acc = current.acc;
                current = Bracket(current.rest.Substring(1));
                calculator.Operands = new object[] { acc, current.acc };
                calculator.Operation = operation == '*' ? Operations.Multiple : Operations.Divide;
                current.acc = (double)calculator.Result;
            }
            return current;
        }
 
        /// <summary>
        /// Выполняет операции в скобках
        /// </summary>
        private Result Bracket(string s)
        {
            if (s[0] == '(')
            {
                Result res = PlusMinus(s.Substring(1));
                if (!res.IsEmpty() && res.NextChar() == ')')
                    res.rest = res.rest.Substring(1);
                else throw new ParseException("Отсутствует закрывающая скобка");
                return res;
            }
            return Function(s);
        }
 
        /// <summary>
        /// Обрабатывает вызовы функций
        /// </summary>
        private Result Function(string s)
        {
            int i = 0;
            while (i < s.Length && Char.IsLetter(s[i]))
                i++;
            if (i > 0)
            {
                String fun = s.Substring(0, i);
                if (i < s.Length && s[i] == '(')
                {
                    int rightP = s.IndexOf(')', i);
                    if(rightP == -1)
                        throw new ParseException("Отсутствует закрывающая скобка");
                    object[] arguments = getFunArguments(s.Substring(i + 1, rightP - i - 1));
                    Result res = new Result(s.Substring(rightP+1));
                    return ProcessFunction(fun, res, arguments);
                }
                else throw new ParseException("Ошибка пои вызове функции");
            }
            return NextOperand(s);
        }
 
        /// <summary>
        /// Находит аргументы для функции
        /// </summary>
        private object[] getFunArguments(string s)
        {
            string[] sValues = s.Split(',');
            object[] oValues = new object[sValues.Length];
            for (int i = 0; i < sValues.Length; i++)
                oValues[i] = Double.Parse(sValues[i], CultureInfo.InvariantCulture);
            return oValues;
        }
 
        /// <summary>
        /// Возвращает следующий операнд
        /// </summary>
        public Result NextOperand(String s)
        {
            bool negative = false;
            if (s.Length > 0 && charIn(s[0], "+-"))
            {
                negative = (s[0] == '-');
                s = s.Substring(1);
            }
 
            int dotCnt = 0;
            int endPos = 0;
            char ch = s.Length > 0 ? s[0] : '0';
            while (endPos < s.Length && (Char.IsDigit(ch) || ch == '.'))
            {
                if(ch == '.' && ++dotCnt > 1)
                    throw new ParseException("Некорректное число " + s.Substring(0, endPos+1));
                endPos++;
                ch = s.Length > endPos ? s[endPos] : '0';
            }
            //если числа мы не нашли
            if(endPos == 0)
                throw new ParseException("Не могу получить корректное число в строке " + s);
            double value = Double.Parse(s.Substring(0, endPos), CultureInfo.InvariantCulture);
            return new Result(negative ? -value : +value, s.Substring(endPos));
        }
 
        /// <summary>
        /// Находит значение функции
        /// </summary>
        private Result ProcessFunction(String fun, Result res, object[] arguments)
        {
            String f = fun.ToLower();
            calculator.Operands = arguments;
            if (f.Equals("sin"))
                calculator.Operation = Operations.Sin;
            else if (f.Equals("cos"))
                calculator.Operation = Operations.Cos;
            else if (f.Equals("tan"))
                calculator.Operation = Operations.Tan;
            else if (f.Equals("ctan"))
                calculator.Operation = Operations.Ctan;
            else if (f.Equals("n"))
                calculator.Operation = Operations.N;
            else if (f.Equals("sqrt"))
                calculator.Operation = Operations.SqrtX;
            else if (f.Equals("sqr"))
                calculator.Operation = Operations.SqrX;
            else if (f.Equals("sarifm"))
                calculator.Operation = Operations.SArifm;
            return new Result(Convert.ToDouble(calculator.Result), res.rest);
            throw new ParseException("Функция " + fun + " неопределена");
        }
 
        /// <summary>
        /// Проверяет вхождение символа в строку
        /// </summary>
        public static bool charIn(char ch, string s)
        {
            return s.IndexOf(ch) != -1;
        }
    }
}
1
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
06.09.2014, 13:55 3
Вы неявно используете рекурсию, это первое, А во-вторых, почему вы не используете замечательную библиотеку Java API? В ней есть, например, такие классы, как StringTokenizer, инстансы которых помогают разделять строку на отдельные символы, к тому же существует мощная поддержка механизмой сдвига, кастомного разделения и так далее. Советую посмотреть документацию по работе со строками. В-третьих, вы действуете не объектно-ориентированно. Программа на ООП - это совокупность объектов, взаимодействующих между собой, создавая логику и следуя ей.
0
06.09.2014, 13:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.09.2014, 13:55
Помогаю со студенческими работами здесь

Не понимаю логику советских вождей
Почему они говорили, что &quot;У нас не заменимых нет&quot;? Это как? Все вредители что ли? Больше то ни кого...

Логику программирования понимаю, а написать не могу.
Не могу написать под номером д) логику программирования понимаю а написать не могу. Правило...

Не понимаю логику обработки кода, разбитого на файлы
Ситуация примерно такая. Есть файл file1.h, в котором объявлена функция: template&lt;class T&gt; T...

хранить выборочные данные Checkbox, Не понимаю логику
Добрый день всем вот возник у меня такая проблема index.php &lt;form id=&quot;form1&quot; name=&quot;form1&quot;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru