Advertisement
Guest User

Untitled

a guest
Oct 18th, 2017
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace POZcalc
  8. {
  9. class RPN
  10. {
  11. //Метод Calculate принимает выражение в виде строки и возвращает результат, в своей работе использует другие методы класса
  12. static public double Calculate(string input)
  13. {
  14. string output = GetExpression(input); //Преобразовываем выражение в постфиксную запись
  15. double result = Counting(output); //Решаем полученное выражение
  16. return result; //Возвращаем результат
  17. }
  18.  
  19. //Метод, преобразующий входную строку с выражением в постфиксную запись
  20. static private string GetExpression(string input)
  21. {
  22. string output = string.Empty; //Строка для хранения выражения
  23. Stack<char> operStack = new Stack<char>(); //Стек для хранения операторов
  24.  
  25. for (int i = 0; i < input.Length; i++) //Для каждого символа в входной строке
  26. {
  27. //Разделители пропускаем
  28. if (IsDelimeter(input[i]))
  29. continue; //Переходим к следующему символу
  30.  
  31. //Если символ - цифра, то считываем все число
  32. if (Char.IsDigit(input[i])) //Если цифра
  33. {
  34. //Читаем до разделителя или оператора, что бы получить число
  35. while (!IsDelimeter(input[i]) && !IsOperator(input[i]))
  36. {
  37. output += input[i]; //Добавляем каждую цифру числа к нашей строке
  38. i++; //Переходим к следующему символу
  39.  
  40. if (i == input.Length) break; //Если символ - последний, то выходим из цикла
  41. }
  42.  
  43. output += " "; //Дописываем после числа пробел в строку с выражением
  44. i--; //Возвращаемся на один символ назад, к символу перед разделителем
  45. }
  46.  
  47. //Если символ - оператор
  48. if (IsOperator(input[i])) //Если оператор
  49. {
  50. if (input[i] == '(') //Если символ - открывающая скобка
  51. operStack.Push(input[i]); //Записываем её в стек
  52. else if (input[i] == ')') //Если символ - закрывающая скобка
  53. {
  54. //Выписываем все операторы до открывающей скобки в строку
  55. char s = operStack.Pop();
  56.  
  57. while (s != '(')
  58. {
  59. output += s.ToString() + ' ';
  60. s = operStack.Pop();
  61. }
  62. }
  63. else //Если любой другой оператор
  64. {
  65. if (operStack.Count > 0) //Если в стеке есть элементы
  66. if (GetPriority(input[i]) <= GetPriority(operStack.Peek())) //И если приоритет нашего оператора меньше или равен приоритету оператора на вершине стека
  67. output += operStack.Pop().ToString() + " "; //То добавляем последний оператор из стека в строку с выражением
  68.  
  69. operStack.Push(char.Parse(input[i].ToString())); //Если стек пуст, или же приоритет оператора выше - добавляем операторов на вершину стека
  70. }
  71.  
  72. }
  73. }
  74.  
  75. //Когда прошли по всем символам, выкидываем из стека все оставшиеся там операторы в строку
  76. while (operStack.Count > 0)
  77. output += operStack.Pop() + " ";
  78. Console.WriteLine("Обратная польская запись {0}",output);
  79. return output; //Возвращаем выражение в постфиксной записи
  80. }
  81.  
  82. //Метод, вычисляющий значение выражения, уже преобразованного в постфиксную запись
  83. static private double Counting(string input)
  84. {
  85. double result = 0; //Результат
  86. Stack<double> temp = new Stack<double>(); //Временный стек для решения
  87.  
  88. for (int i = 0; i < input.Length; i++) //Для каждого символа в строке
  89. {
  90. //Если символ - цифра, то читаем все число и записываем на вершину стека
  91. if (Char.IsDigit(input[i]))
  92. {
  93. string a = string.Empty;
  94.  
  95. while (!IsDelimeter(input[i]) && !IsOperator(input[i])) //Пока не разделитель
  96. {
  97. a += input[i]; //Добавляем
  98. i++;
  99. if (i == input.Length) break;
  100. }
  101. temp.Push(double.Parse(a)); //Записываем в стек
  102. i--;
  103. }
  104. else if (IsOperator(input[i])) //Если символ - оператор
  105. {
  106. //Берем два последних значения из стека
  107. double a = temp.Pop();
  108. double b = temp.Pop();
  109.  
  110. switch (input[i]) //И производим над ними действие, согласно оператору
  111. {
  112. case '+':
  113. result = b + a;
  114. Console.Write("{0} + {1} = {2}\n", b, a, result);
  115. break;
  116. case '-':
  117. result = b - a;
  118. Console.Write("{0} - {1} = {2}\n", b, a, result);
  119. break;
  120. case '*':
  121. result = b * a;
  122. Console.Write("{0} * {1} = {2}\n", b, a, result);
  123. break;
  124. case '/':
  125. if (a == 0)
  126. Console.WriteLine("Деление на ноль");
  127. else
  128. {
  129. result = b / a;
  130. Console.Write("{0} / {1} = {2}\n", b, a, result);
  131. }
  132. break;
  133. case '^':
  134. result = double.Parse(Math.Pow(double.Parse(b.ToString()), double.Parse(a.ToString())).ToString());
  135. Console.Write("{0} ^ {1} = {2}\n", b, a, result);
  136. break;
  137. }
  138. temp.Push(result); //Результат вычисления записываем обратно в стек
  139. }
  140. }
  141. return temp.Peek(); //Забираем результат всех вычислений из стека и возвращаем его
  142. }
  143.  
  144. static private bool IsDelimeter(char c)
  145. {
  146. if ((" =".IndexOf(c) != -1))
  147. return true;
  148. return false;
  149. }
  150.  
  151. static private bool IsOperator(char с)
  152. {
  153. if (("+-/*^()".IndexOf(с) != -1))
  154. return true;
  155. return false;
  156. }
  157.  
  158. static private byte GetPriority(char s)
  159. {
  160. switch (s)
  161. {
  162. case '(': return 0;
  163. case ')': return 1;
  164. case '+': return 2;
  165. case '-': return 3;
  166. case '*': return 4;
  167. case '/': return 4;
  168. case '^': return 5;
  169. default: return 6;
  170. }
  171. }
  172. }
  173. class Program
  174. {
  175. static void Main(string[] args)
  176. {
  177. Console.WriteLine("Введите выражение: ");
  178. string s = Console.ReadLine();
  179. char[] s1 = s.ToCharArray();
  180. int[] chars = new int[s.Length];
  181. for (int i = 0; i < s.Length; i++)
  182. chars[i] = -1;
  183. for (int i = 0; i < s.Length; i++)
  184. {
  185. if (Char.IsLetter(s[i]) == true)
  186. {
  187. int k = 0;
  188. int temp = 0;
  189. for(int j=0; j<i;j++)
  190. {
  191. if (s[j] == s[i])
  192. {
  193. k++;
  194. temp = j;
  195. }
  196. }
  197. if (k == 0)
  198. {
  199. Console.Write("{0} = ", s[i]);
  200. chars[i] = Convert.ToInt32(Console.ReadLine());
  201. }
  202. else
  203. chars[i] = chars[temp];
  204. }
  205. }
  206. string finalstring = "";
  207. char[] Chars = s.ToCharArray();
  208. for (int i = 0; i < s.Length; i++)
  209. if (chars[i] != -1)
  210. finalstring += chars[i].ToString();
  211. else
  212. finalstring += Chars[i];
  213.  
  214. Console.WriteLine("Результат: {0}",RPN.Calculate(finalstring));
  215. Console.ReadKey();
  216. }
  217. }
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement