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
pub fn solve_string(mut input: String) -> f32 {
        //declares stuff.
        let mut answer: f32 = 404.0;
        let mut operator_places = vec![];
        let exponent = "^";
        let multiplication = "*";
        let division = "/";
        let addition = "+";
        let subtraction = "~";
        let mut current_letter;
        let mut before_letter= "l";
        let mut num_of_parth = 0;
        let mut most_inner_parth;
        let mut places_after_most_inner;
        let mut runner;
        //creates a clone of input in order to retain the original input.
        let mut before_input = input.clone();
        //adds parenthesis on either side of the equation.
        input = "".to_string();
        input.push_str("(");
        input.push_str(&before_input);
        input.push_str(")");
        //finds the number of opening parenthesis
        for i in 0..input.len() {
            current_letter = &input[i..i + 1];
            if current_letter == "(" {
                num_of_parth = num_of_parth + 1
            }
        }
        for i in 1..input.len() {
            current_letter = &input[i..i + 1];
            before_input = input.clone();
            before_letter = &before_input[i - 1..i];
            if (current_letter == "-") & (is_string_numeric(std::string::String::from(before_letter)) == true) {
                input = "".to_string();
                input.push_str(&((&before_input[0..i] as &str).to_owned() + "~" + &(before_input[i + 1..])));
            }
        }
        //runs the solving part of solve string once for each opening parenthesis
        while num_of_parth > 0 {
            //resets variables
            most_inner_parth = 0;
            places_after_most_inner = 0;
            runner = 0;
            //determines the location of the innermost opening and closing parenthesis
            for i in 0..input.len() {
                current_letter = &input[i..i + 1];
                if current_letter == "(" {
                    most_inner_parth = most_inner_parth + runner;
                    runner = 0;
                } else if current_letter == ")" {
                    break;
                }
                runner = runner + 1;
            }
            for i in most_inner_parth..input.len() {
                current_letter = &input[i..i + 1];
                if current_letter == ")" {
                    break;
                } else {
                    places_after_most_inner = places_after_most_inner + 1;
                }
            }
            // creates an input to be fed to the operator detector and solver.
            let mut new_input = (&input[(most_inner_parth + 1) as usize..(most_inner_parth + places_after_most_inner) as usize]).to_string();
            //adds operations in the order of pemdas
            for i in 0..new_input.len() {
                current_letter = &new_input[i..i + 1];
                if current_letter == exponent {
                    operator_places.push(exponent);
                }
            }
            for i in 0..new_input.len() {
                current_letter = &new_input[i..i + 1];
                if current_letter == multiplication {
                    operator_places.push(multiplication);
                } else if current_letter == division {
                    operator_places.push(division);
                }
            }
            for i in 0..new_input.len() {
                current_letter = &new_input[i..i + 1];
                if current_letter == addition {
                    operator_places.push(addition);
                } else if current_letter == subtraction {
                    operator_places.push(subtraction);
                }
            }
            //finds the place of the current operator.
            for i in 0..operator_places.len() {
                let mut beforeplaces = 1;
                let mut afterplaces = 1;
                let current_operator = operator_places[i];
                let mut int_cop: i32 = 0;
                for s in 0..new_input.len() {
                    current_letter = &new_input[s..s + 1];
                    if current_operator == current_letter {
                        int_cop = s as i32;
                    }
                }
                let mut ch_p: usize;
                //determines the number of places before the operator that are numbers
                loop {
                    ch_p = (int_cop - beforeplaces) as usize;
                    if ch_p == 0 {
                        break;
                    }
                    let ch = (&new_input[ch_p - 1..ch_p]).to_string();
                    if true == is_string_numeric(ch.clone()) || (ch == ".") || (ch == "-") {
                        beforeplaces = beforeplaces + 1;
                    } else {
                        break;
                    }
                }
                //determines the number of places after the operator that are numbers.
                loop {
                    ch_p = (int_cop + afterplaces + 1) as usize;
                    if ch_p == new_input.len() {
                        break;
                    }
                    let ch = (&new_input[ch_p..ch_p + 1]).to_string();
                    if true == is_string_numeric(ch.clone()) || (ch == ".") || (ch == "-") {
                        afterplaces = afterplaces + 1;
                    } else {
                        break;
                    }
                }
                //takes new input and before places and comes up with first number to be operatored on.
                let firstnumf32 = (&new_input[(int_cop - beforeplaces) as usize..(int_cop) as usize]).parse::<f32>().unwrap();
                //does the same as first num except after places.
                let secnumf32 = (&new_input[(int_cop + 1) as usize..(int_cop + afterplaces + 1) as usize]).parse::<f32>().unwrap();
                //does the corresponding math as requested by current operator.
                if current_operator == exponent {
                    answer = firstnumf32.powf(secnumf32);
                }
                if current_operator == multiplication {
                    answer = firstnumf32 * secnumf32;
                }
                if current_operator == division {
                    answer = firstnumf32 / secnumf32;
                }
                if current_operator == addition {
                    answer = firstnumf32 + secnumf32;
                }
                if current_operator == subtraction {
                    answer = firstnumf32 - secnumf32;
                }

                //edits new input to equal new input minus the operator and numbers acted upon.
                let inputcash1 = &new_input.clone()[0 as usize..int_cop as usize - beforeplaces as usize];
                let inputcash2 = &answer.to_string() as &str;
                let inputcash3 = &new_input.clone()[(int_cop + afterplaces + 1) as usize..new_input.len() as usize];
                new_input = ("").parse().unwrap();
                new_input.push_str(inputcash1);
                new_input.push_str(inputcash2);
                new_input.push_str(inputcash3);
            }
            //lets input be modified from the answer of the parenthesis
            let inputclone = input.clone();
            let inputcash1 = &inputclone[0 as usize..most_inner_parth as usize];
            let inputcash2 = &answer.to_string() as &str;
            let inputcash3 = &inputclone[(most_inner_parth + places_after_most_inner + 1) as usize..(input.len()) as usize];
            input = ("").parse().unwrap();
            input.push_str(inputcash1);
            input.push_str(inputcash2);
            input.push_str(inputcash3);
            num_of_parth = num_of_parth - 1;
            operator_places.clear();
        }
        //returns the answer as f32
        println!("{}", answer);
        return answer;

}

    //determines if the characters in a string are numeric. written by me
    fn is_string_numeric(str: String) -> bool {
        for c in str.chars() {
            if !c.is_numeric() {
                return false;
            }
        }
        return true;
    }