Advertisement
Guest User

Untitled

a guest
May 27th, 2017
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 KB | None | 0 0
  1. open System
  2. open System.IO
  3. open System.Net
  4. open System.Text
  5. open System.Collections.Specialized
  6.  
  7. //========================================================================
  8.  
  9. // Task 1
  10. // Получает список символов по строке
  11. let explode (s:string) = [for c in s -> c]
  12.  
  13. // Проверяем, сбалансированы ли скобки
  14. let isBalanced str =
  15. // acc здесь - список только скобочных символов (изначально пустой)
  16. let rec isBalanced' acc str =
  17. // str - список символов строки
  18. match str with
  19. // Если открывающийся - добавим
  20. | '('::xs -> isBalanced' ('('::acc) xs
  21. | '['::xs -> isBalanced' ('['::acc) xs
  22. | '{'::xs -> isBalanced' ('{'::acc) xs
  23. // Иначе надо проверить, что открывающаяся скобка такого же типа лежит на вершине листа
  24. | ')'::xs ->
  25. if (List.head acc = '(') then
  26. // МЫ БЕРЕМ List.tail, то есть все, без первого элемента!!!
  27. isBalanced' (List.tail acc) xs
  28. else
  29. false
  30. | ']'::xs ->
  31. if (List.head acc = '[') then
  32. isBalanced' (List.tail acc) xs
  33. else
  34. false
  35. | '}'::xs ->
  36. if (List.head acc = '{') then
  37. isBalanced' (List.tail acc) xs
  38. else
  39. false
  40. // Если символ - не скобка, то пофиг
  41. | _::xs -> isBalanced' acc xs
  42. | [] -> List.isEmpty acc
  43.  
  44. // Возвращаем такую штуку (аналог return)
  45. isBalanced' [] (explode str)
  46.  
  47. let str1 = "((8)){{[]}}{900}" //Все сбалансировано
  48. let str2 = "((88)){]" //Все плохо
  49. let TASK1_1 = isBalanced str1 // Возвращает true
  50. let TASK1_2 = isBalanced str2 // Возвращает false
  51.  
  52. //=============================================================================
  53.  
  54. // Task 2 - Считаем выражение, заданное строкой
  55. // Используем обратную польскую запись:
  56.  
  57. // Параметр list - список символов строки
  58. let calc list =
  59.  
  60. // Сначала не смотри на эту функцию, смотри на следующую!!!!!
  61. let rec evaluate ops values =
  62. if List.isEmpty ops then
  63. List.head values
  64. else
  65. let a::b::xs = values
  66. let op::left_ops = ops
  67. match op with
  68. | '+' -> evaluate left_ops ((a + b) :: xs)
  69. | '-' -> evaluate left_ops ((a - b) :: xs)
  70. | '*' -> evaluate left_ops ((a * b) :: xs)
  71. | '/' -> evaluate left_ops ((a / b) :: xs)
  72.  
  73. // Что делает это говно.
  74. // Параметры:
  75. // balance - текущий скобочный баланс
  76. // op_acc - список операций (задается символами +,-,..)
  77. // value_acc - список цифр (=чисел, так как работаем только с цифрами, но семеру это не обязательно знать)
  78. // list - изначальный список символов строки, который будем парсить
  79. // Функция называется calc', в ней есть ключевое слово rec, потому что она рекурсивная
  80. let rec calc' balance op_acc value_acc list =
  81. match list with
  82. | ')'::_ when balance < 0 -> (op_acc, value_acc)
  83. | ')'::xs -> calc' (balance - 1) op_acc value_acc xs
  84. | _::xs when balance <> 0 -> calc' balance op_acc value_acc xs
  85. | '+'::xs -> calc' balance ('+'::op_acc) value_acc xs
  86. | '-'::xs -> calc' balance ('-'::op_acc) value_acc xs
  87. | '*'::xs -> calc' balance ('*'::op_acc) value_acc xs
  88. | '/'::xs -> calc' balance ('/'::op_acc) value_acc xs
  89. | '('::xs ->
  90. let a, b = (calc' 0 [] [] xs)
  91. let result = evaluate a b
  92. calc' (balance + 1) op_acc (result::value_acc) xs
  93. | ' ':: xs -> calc' balance op_acc value_acc xs
  94. | x::xs -> calc' balance op_acc (((int x) - (int '0')) :: value_acc) xs
  95. | [] -> (op_acc, value_acc)
  96. let ops, values = calc' 0 [] [] list
  97. evaluate ops values
  98.  
  99. let b = "3 * (1 + 2 / 2)" // Работаем только с цифрами!!! С числами не умеем!
  100. printfn "%A" (calc (explode b)) // Выводит 6!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement