Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
20 мая 2024, 10:22

Строковый Калькулятор

Автор Vasylii, 30 авг 2023, 13:33

0 Пользователей и 1 гость просматривают эту тему.

Vasylii

В общем проблема в следующем взял за основу калькулятор уже готовый, решил переделать в строковый но столкнулся с проблемой на соотвествии т.к. нужно сделать калькулятор который будет решать без приоритетов умножения или деления,(пример 5+7*8) в данном случае доходит до операции умножения перекидывает со счетом 3 на начала цикла но дальше не идет а завершает работу посчитав только 5+7, не могу понять в чем загвоздка

//ДОБАВИМ ВРЕМЕННЫЕ ПЕРЕМЕННЫЕ ДЛЯ РАСЧЕТА
ВременныйСписокОпераций = Новый Массив;
ВременныйСписокЦифр = Новый Массив;

//ДОБАВИМ СООТ. ОПЕРАЦИИ И ЕЕ ПРИОРИТЕТА
СоотПриоритетов = Новый Соответствие;
СоотПриоритетов.Вставить("+", 2);
СоотПриоритетов.Вставить("-", 2);
СоотПриоритетов.Вставить("*", 1);
СоотПриоритетов.Вставить("/", 1);                                   

Результат = 0;

Для Счет = 0 По МассивЦифр.Количество() - 1 Цикл


Если ВременныйСписокОпераций.Количество() Тогда

//ЕСЛИ ОПЕРАЦИЙ БОЛЬШЕ НЕТ И ЭТО БЫЛА ПОСЛЕДНЯЯ ПОЧИТАЕМ ЗНАЧЕНИЕ
Если МассивОпераций.Количество() = Счет Тогда

//ДОБАВИМ ПОСЛЕДНЕЕ ЧИСЛО В ПОСЛЕДОВАТЕЛЬНОСТЬ
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));

//ВСЕ НАШИ ПЕРЕДАННЫЕ СПИСКИ МЫ ПРОШЛИ, ОСТАЛОСЬ ПРОЙТИСЬ ПО ВРЕМЕННЫМ ТАБЛИЦАМ ОТ БОЛЬШЕГО К МЕНЬШЕМУ
Пока ВременныйСписокОпераций.Количество() Цикл

ПервоеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 3);
ВтороеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 2);
ТретьеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 1);

Операция = ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество()-1);

Если Операция = "+" Тогда
Результат = ПервоеЧисло + ВтороеЧисло;

ИначеЕсли Операция = "-" Тогда
Результат = ПервоеЧисло - ВтороеЧисло;

ИначеЕсли Операция = "*" Тогда
Результат =  Результат * ТретьеЧисло;

ИначеЕсли Операция = "/" Тогда
Результат = Результат / ТретьеЧисло;
КонецЕсли;

//УДАЛИМ ПОСЛЕДНЮЮ ЦИФРУ И ОПЕРАЦИЮ И ЗАПИШЕМ НОВУЮ                                   
ВременныйСписокЦифр.Удалить(ВременныйСписокЦифр.Количество() - 1);                 
ВременныйСписокОпераций.Удалить(ВременныйСписокОпераций.Количество() - 1);
ВременныйСписокЦифр.Добавить(Результат);                                           

КонецЦикла;

Иначе

Если СоотПриоритетов.Получить(МассивОпераций.Получить(Счет)) >
СоотПриоритетов.Получить(ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество() - 1)) Тогда

//ЕСЛИ ТЕКУЩАЯ ОПЕРАЦИЯ БОЛЬШЕ ПО ПРИОРИТЕТУ, ТО ПРОСТО ДОБАВЛЯЕМ В СПИСОК
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет));
Иначе

//ЕСЛИ ТЕКУЩАЯ ОПЕРАЦИЯ МЕНЬШЕ ИЛИ РАВНА ПО ПРИОРИТЕТУ, ТО СНАЧАЛА ВЫПОЛНЯЕМ СТАРУЮ
ПервоеЧисло = Число(МассивЦифр.Получить(Счет-1));
ВтороеЧисло = Число(МассивЦифр.Получить(Счет));
                    ТретьеЧисло = Число(МассивЦифр.Получить(Счет+1));

Операция = ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество()-1);

Если Операция = "+" Тогда
Результат = ПервоеЧисло + ВтороеЧисло;

ИначеЕсли Операция = "-" Тогда
Результат = ПервоеЧисло - ВтороеЧисло;

ИначеЕсли Операция = "*" Тогда
Результат =  Результат * ТретьеЧисло;

ИначеЕсли Операция = "/" Тогда
Результат = Результат / ТретьеЧисло;
КонецЕсли;



//УДАЛИМ ПОСЛЕДНЮЮ ЦИФРУ И ОПЕРАЦИЮ И ЗАПИШЕМ НОВУЮ
ВременныйСписокЦифр.Удалить(ВременныйСписокЦифр.Количество() - 1);                 
ВременныйСписокОпераций.Удалить(ВременныйСписокОпераций.Количество() - 1);
ВременныйСписокЦифр.Добавить(Результат);
КонецЕсли;
КонецЕсли;
Иначе
//ОПЕРАЦИЙ НЕТ, ДОБАВЛЯЕМ ЗНАЧЕНИЕ ЧИСЛА И ОПЕРАЦИИ В СТЕК
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));
Если Счет = 2 тогда
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет-1));
Иначе
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет));
КонецЕсли;

КонецЕсли;

КонецЦикла;

Возврат Результат;

Vasylii

кажется нашел корень проблемы изначально не добавляет знак умножения

Vasylii

Решил все через дикие костыли
//ДОБАВИМ ВРЕМЕННЫЕ ПЕРЕМЕННЫЕ ДЛЯ РАСЧЕТА
ВременныйСписокОпераций = Новый Массив;
ВременныйСписокЦифр = Новый Массив;

//ДОБАВИМ СООТ. ОПЕРАЦИИ И ЕЕ ПРИОРИТЕТА
СоотПриоритетов = Новый Соответствие;
СоотПриоритетов.Вставить("+", 1);
СоотПриоритетов.Вставить("-", 1);
СоотПриоритетов.Вставить("*", 1);
СоотПриоритетов.Вставить("/", 1);                                   

Результат = 0;

Для Счет = 0 По МассивЦифр.Количество() - 1 Цикл


Если ВременныйСписокОпераций.Количество() Тогда

//ЕСЛИ ОПЕРАЦИЙ БОЛЬШЕ НЕТ И ЭТО БЫЛА ПОСЛЕДНЯЯ ПОЧИТАЕМ ЗНАЧЕНИЕ
Если МассивОпераций.Количество() = Счет Тогда

//ДОБАВИМ ПОСЛЕДНЕЕ ЧИСЛО В ПОСЛЕДОВАТЕЛЬНОСТЬ
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));

//ВСЕ НАШИ ПЕРЕДАННЫЕ СПИСКИ МЫ ПРОШЛИ, ОСТАЛОСЬ ПРОЙТИСЬ ПО ВРЕМЕННЫМ ТАБЛИЦАМ ОТ БОЛЬШЕГО К МЕНЬШЕМУ
Пока ВременныйСписокОпераций.Количество() Цикл

Если Счет = 2 Тогда
ПервоеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 2);
                         ВтороеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 1);

Операция = ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество()-1);

Если Операция = "*" Тогда
Результат =  ПервоеЧисло * ВтороеЧисло;

ИначеЕсли Операция = "/" Тогда
Результат = ВтороеЧисло / ВтороеЧисло;
КонецЕсли;

Иначе
ПервоеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 3);
ВтороеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 2);
ТретьеЧисло = ВременныйСписокЦифр.Получить(ВременныйСписокЦифр.Количество() - 1);

Если Операция = "+" Тогда
Результат = ПервоеЧисло + ВтороеЧисло;

ИначеЕсли Операция = "-" Тогда
Результат = ПервоеЧисло - ВтороеЧисло;

ИначеЕсли Операция = "*" Тогда
Результат =  Результат * ТретьеЧисло;

ИначеЕсли Операция = "/" Тогда
Результат = Результат / ТретьеЧисло;
КонецЕсли;

КонецЕсли;




//УДАЛИМ ПОСЛЕДНЮЮ ЦИФРУ И ОПЕРАЦИЮ И ЗАПИШЕМ НОВУЮ                                   
ВременныйСписокЦифр.Удалить(ВременныйСписокЦифр.Количество() - 1);                 
ВременныйСписокОпераций.Удалить(ВременныйСписокОпераций.Количество() - 1);
ВременныйСписокЦифр.Добавить(Результат);                                           

КонецЦикла;

Иначе

Если СоотПриоритетов.Получить(МассивОпераций.Получить(Счет)) >
СоотПриоритетов.Получить(ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество() - 1)) Тогда

//ЕСЛИ ТЕКУЩАЯ ОПЕРАЦИЯ БОЛЬШЕ ПО ПРИОРИТЕТУ, ТО ПРОСТО ДОБАВЛЯЕМ В СПИСОК
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет));
Иначе

//ЕСЛИ ТЕКУЩАЯ ОПЕРАЦИЯ МЕНЬШЕ ИЛИ РАВНА ПО ПРИОРИТЕТУ, ТО СНАЧАЛА ВЫПОЛНЯЕМ СТАРУЮ
ПервоеЧисло = Число(МассивЦифр.Получить(Счет-1));
ВтороеЧисло = Число(МассивЦифр.Получить(Счет));
ТретьеЧисло = Число(МассивЦифр.Получить(Счет+1));

Операция = ВременныйСписокОпераций.Получить(ВременныйСписокОпераций.Количество() - 1);

Если Операция = "+" Тогда
Результат = ПервоеЧисло + ВтороеЧисло;

ИначеЕсли Операция = "-" Тогда
Результат = ПервоеЧисло - ВтороеЧисло;

ИначеЕсли Операция = "*" Тогда
Результат =  Результат * ТретьеЧисло;

ИначеЕсли Операция = "/" Тогда
Результат = Результат / ТретьеЧисло;
КонецЕсли;



//УДАЛИМ ПОСЛЕДНЮЮ ЦИФРУ И ОПЕРАЦИЮ И ЗАПИШЕМ НОВУЮ
ВременныйСписокЦифр.Удалить(ВременныйСписокЦифр.Количество() - 1);                 
ВременныйСписокОпераций.Удалить(ВременныйСписокОпераций.Количество() - 1);
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет));
ВременныйСписокЦифр.Добавить(Результат);                                           
КонецЕсли;
КонецЕсли;
Иначе
//ОПЕРАЦИЙ НЕТ, ДОБАВЛЯЕМ ЗНАЧЕНИЕ ЧИСЛА И ОПЕРАЦИИ В СТЕК
ВременныйСписокЦифр.Добавить(Число(МассивЦифр.Получить(Счет)));
ВременныйСписокОпераций.Добавить(МассивОпераций.Получить(Счет));

КонецЕсли;

КонецЦикла;

Возврат Результат;

LexaK

т.е. ваш калькулятор одновременно только с тремя числами может делать вычисления?
как-то ускользает смысл в таком калькуляторе,

(надеюсь вы не на говно..кодера учитесь? писать такую кучу бесполезного кода...)

в 1С есть отличная команда: Вычислить

СтрокаФормулы = "5 + 7 * 8";
Сообщить(СтрокаФормулы + " = " + Вычислить(СтрокаФормулы));
если помогло нажмите: Спасибо!

Vasylii

LexaK, я делал строго под тех задание, в нем был указан пример из 3 значений и использовал его за основу, вычислить я так же использую но для выражений со скобками что бы считало по правилам математики, кусок костыля который сделал для счета без приоритетов умножения и деления, знал бы я как сделать это все лучше и адаптивней сделал но увы пока знаниями такими не обладаю

Kvark5d

Vasylii, не совсем понятно:
Цитата: Vasylii от 30 авг 2023, 13:33нужно сделать калькулятор который будет решать без приоритетов умножения или деления,(пример 5+7*8)
5+7*8 = (5+7)*8=12*8=96  ???


Kvark5d

Vasylii,
Функция ВычислитьБезПриоритетовОпераций(ИсходнаяСтрока)
МассивОпераций = СтрРазделить(ИсходнаяСтрока,"0123456789");
МассивЧисел =   СтрРазделить(ИсходнаяСтрока,"+-/*");
Результат=МассивЧисел[0];
Для а=1 По МассивЧисел.Количество()-1 Цикл
Результат = Вычислить(Строка(Результат)+Строка(МассивОпераций[а-1])+Строка(МассивЧисел[а]));
КонецЦикла;
Возврат Результат;
КонецФункции

Vasylii


Vasylii

Kvark5d, Только у вас ошибка не большая
Для а=1 По МассивЧисел.Количество()-1 Цикл
        Результат = Вычислить(Строка(Результат)+Строка(МассивОпераций[а])+Строка(МассивЧисел[а]));         
    КонецЦикла;

где берем массив операций он захватывает почему то пустые значения в начале и конце по этому при данном расскладе просто берем значение а

Похожие темы (5)

Рейтинг@Mail.ru

Поиск