From b307e35d9fe462ed40ddb6d28fe95566e9d06aa1 Mon Sep 17 00:00:00 2001 From: grechkagk Date: Wed, 29 May 2024 13:12:31 +0000 Subject: [PATCH] 0.1.1 src MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit поддержка скобок --- src/main.rs | 146 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1c2f09a..b6d8605 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ use std::io::{self, Write}; // Импортируем библиотеки дл mod debug; // Импортируем модуль debug.rs use crate::debug::debugging; +static mut DEBUG_MODE: bool = false; + fn main() { println!( "{}, ver: {}, by: {} ; print 'H' to see help ; to exit print 'Q'", @@ -29,13 +31,14 @@ fn begin() { if input.chars().nth(0).unwrap() == 'H' || input.chars().nth(0).unwrap() == 'h' { // Выводим помощь println!( - "{}\n{}\n{}\n{}\n{}\n{}", + "{}\n{}\n{}\n{}\n{}\n{}\n{}", "calc help".bold().red(), "'!' = debug mode".italic(), "'+' = addition".italic(), "'-' = subtraction".italic(), "'*' = multiplication".italic(), - "'/' = division".italic() + "'/' = division".italic(), + "'(' or ')' = bracket".italic() ); begin() } @@ -44,6 +47,9 @@ fn begin() { debugging(&input.trim()); // Вызываем функцию дебаг calculate(formatting(&input.trim())); // Вызываем функцию вычисления + unsafe { + DEBUG_MODE = false; + } let_start_again() } @@ -55,6 +61,7 @@ fn formatting(formule: &str) -> Vec { let mut stack: Vec = vec![String::from("")]; // Массив для хранения чисел в виде строк let mut dot_count = 0; // Счетчик точек в текущем числе + let mut last_char = ' '; // Переменная для отслеживания последнего символа for c in formule.chars() { if c.is_digit(10) { @@ -75,18 +82,33 @@ fn formatting(formule: &str) -> Vec { stack.last_mut().unwrap().push(c); dot_count += 1; // Увеличиваем счетчик точек } - } else if c == '+' || c == '-' || c == '*' || c == '/' { - // Если символ является оператором + } else if c == '+' || c == '*' || c == '/' || c == '(' || c == ')' { + // Если символ является оператором (кроме '-') stack.push(String::from(c)); // Добавляем оператор в стек stack.push(String::from("")); // Добавляем пустую строку в стек dot_count = 0; // Сбрасываем счетчик точек при переходе к новому числу - } else if c == ' ' || c == '!' { + } else if c == '-' { + // Если символ является минусом + if last_char == ' ' || last_char == '(' || "+-*/(".contains(last_char) { + // Минус как часть числа (отрицательное число) + stack.last_mut().unwrap().push(c); + } else { + // Минус как оператор + stack.push(String::from(c)); // Добавляем оператор в стек + stack.push(String::from("")); // Добавляем пустую строку в стек + } + dot_count = 0; // Сбрасываем счетчик точек при переходе к новому числу + } else if c == ' ' { // Если символ является пробелом continue; + } else if c == '!' { + unsafe { DEBUG_MODE = true } } else { println!("{}", "Error: Invalid characters entered!".bold().red()); begin(); } + + last_char = c; // Обновляем последний символ } if formule.chars().nth(0).unwrap() == '!' { @@ -97,72 +119,86 @@ fn formatting(formule: &str) -> Vec { stack // спасибо чату жпт что подсказал что надо поставить эту хуйню :D } + fn calculate(formula: Vec) -> f32 { - let mut values: Vec = Vec::new(); - let mut operators: Vec = Vec::new(); + let mut values: Vec = Vec::new(); // стек чисел + let mut operators: Vec = Vec::new(); // стек операторов - let mut i = 0; + let mut i = 0; //счетчик while i < formula.len() { - let token = &formula[i]; + let token = &formula[i]; // число или оператор if let Ok(num) = token.parse::() { + //если число то прибавляет values.push(num); - } else if token == "*" || token == "/" { - // Проверяем, есть ли следующий токен и является ли он числом - if i + 1 >= formula.len() || formula[i + 1].parse::().is_err() { - println!( - "{}", - "Error: Invalid syntax, operator followed by another operator or end of input." - .bold() - .red() - ); - begin(); + } else if token == "(" { + // если "(" то добавляет в операторы + operators.push(token.clone()); + } else if token == ")" { + while let Some(op) = operators.pop() { + if op == "(" { + break; + } + apply_operator(&mut values, &op); } - - let op = token; - i += 1; - let next_value = formula[i].parse::().unwrap(); - let last_value = values.pop().unwrap(); - let result = if op == "*" { - last_value * next_value - } else { - last_value / next_value - }; - values.push(result); - } else if token == "+" || token == "-" { - // Проверяем, есть ли следующий токен и является ли он числом - if i + 1 >= formula.len() || formula[i + 1].parse::().is_err() { - println!( - "{}", - "Error: Invalid syntax, operator followed by another operator or end of input." - .bold() - .red() - ); - begin(); + } else if token == "+" || token == "-" || token == "*" || token == "/" { + while let Some(last_op) = operators.last() { + if precedence(token) <= precedence(last_op) { + let op = operators.pop().unwrap(); + apply_operator(&mut values, &op); + } else { + break; + } } - operators.push(token.clone()); } i += 1; - } - - let mut result = values[0]; - let mut value_index = 1; - - for operator in operators { - let next_value = values[value_index]; - if operator == "+" { - result += next_value; - } else { - result -= next_value; + unsafe { + if DEBUG_MODE == true { + println!("-- {}", i); + println!("!operators: {:?}", operators); + println!("!values: {:?}", values); + } } - value_index += 1; } - println!("Result: {}", result); + while let Some(op) = operators.pop() { + apply_operator(&mut values, &op); + unsafe { + if DEBUG_MODE == true { + println!("-- op"); + println!("!operators: {:?}", operators); + println!("!values: {:?}", values); + } + } + } + let result = values.pop().unwrap(); + println!("Result: {}", result); result } +fn apply_operator(values: &mut Vec, op: &str) { + let right = values.pop().unwrap(); + let left = values.pop().unwrap(); + let result = match op { + "+" => left + right, + "-" => left - right, + "*" => left * right, + "/" => left / right, + _ => panic!("Unknown operator"), + }; + values.push(result); +} + +fn precedence(op: &str) -> i32 { + match op { + "+" | "-" => 1, + "*" | "/" => 2, + "(" => 0, + _ => panic!("Unknown operator"), + } +} + fn let_start_again() { begin() -} +} \ No newline at end of file