Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Перевод текста в математическое выражение Добавлено: 12.12.03 11:24  

Автор вопроса:  dNW

Предположим в поле text1 я ввел "2*45^2". как заставить компьютер посчитать выражение и выдать результат?

Ответить

  Ответы Всего ответов: 8  

Номер ответа: 1
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #1
Добавлено: 12.12.03 17:43

Это дело называется синтаксический анализ. Сперва определяешь некую структуру, которая будет служить тебе деревом. Вот пример:

23*34^2-(3*2+98) (примечание: скобки не нужны вообще-то, но используются для демонстрации их разветвления)

Разложение: от операций с высшим приоритетом до операций с низшим приоритетом: в каждом случае происходит ветвление дерева

23*34^2; (3*2+98) - конечно, надо сохранять отношение между ветвями,т.е. действие, которое ты будешь производить с ветвями одного уровня, поднимаясь от концов (Примечание: граф должен быть ориентированным, т.е. чтоб ты мог сказать, какая ветвь из ветвей одного уровня левее - например, для операции деления). К тому же ветвь может делиться единожды - т.е. на одну ветвь - например, при вычислении корня

Ветвь 23*34^2 ветвится на 23 и 34^2. Отношение - умножение

Ветвь 3*2+98 (скобки можно отбросить, т.к. они обеспечивали ветвление предыдущего уровня) ветвится на 3*2 и 98 (неразветвляющуюся). Отношение: сумма

Ветвь 23 неразветвляющаяся, 34^2 ветвится на две (ориентирование!) неразветвляющиеся 34 и 2. Отношение: возведение в степень

И, наконец, 3*2 ветвится на неразветвляющиеся ветви 3 и 2, отношение: умножение

Теперь поднимаемся снизу вверх. Самый низкий уровень - у 3 и 2 с отношением умножения и у 34 и 2 с отношением возведения в степень. Выполняем операции - 6, 1156, сворачиваем таким образом дерево. Затем выполняем операцию дальше: 23 и 1156 - отношение умножение, 6 и 98 - отношение сумма. Сворачивая, получаем, 26558 и 104.

Затем оставшиеся две ветви сворачиваем с отношением разность. Получаем 26454 - искомое число.

Не зню, насколько я понятно объяснил, но я старался :)

Ответить

Номер ответа: 2
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #2
Добавлено: 12.12.03 17:57
А лучше не париться, подключить Microsoft Scripting Library и юзать
парсер оттуда. К сожалению, пример сейчас не найду..

Ответить

Номер ответа: 3
Автор ответа:
 DanOld



Вопросов: 2
Ответов: 5
 Профиль | | #3 Добавлено: 12.12.03 18:15
Тебе нужно сделать семантический разбор строки, я бы делал так:1. Подсчет кол-во операций в строке (будем хранить в переменной kol_op)2. Вычисление количество цифр ( на 1 больше чем операций) ( kol_zifr=kol_op+1)3. Код операций (будем фиксировать операции в массиве Num_OP(kol_op), записывать числа) Нумерацию делаем с учетом приоритета выполнения 1--Это возведение в степень 2--умножение 3--деление 4--сложение и т.дПроходим по строке и находим ключевые символы ( "^","*","/","+" .....) в массив Num_OP записываем код операции (пункт 3), а в массив NUM_index записываемчисло (номер этого символа в строке)К твоему примеру("2*45^2") эти массивы и переменные будут содержать, следующие данные: kol_op=2 kol_zifr=3 Mассив NUM_OP будет содержать последовательность: 2, 1 Массив NUM_idex будет содержать последовательность: 2,4 (второй символ "*" и четвертый символ в строке это "^") Теперь позаботимся о том, что учитывалось приоритет операций, для этого делаем следующие:1. Сортируем по возрастанию массив NUM_OP, НО ПРИ ПЕРЕСТАНОВКЕ СИМВОЛОВ В ЭТОМ МАССИВЕ, НУЖНО ПЕРЕСТАВЛЯТЬ СООТВЕТСТВУЮЩИЕ ЭЛЕМЕНТЫ МАССИВА NUM_index!!!!!Массивы примут следующий вид: Mассив NUM_OP будет содержать последовательность:1,2 Массив NUM_idex будет содержать последовательность:4,2 К примеру: цикл до kol_op-1 if NUM_OP(i)>NUM_OP(i+1) then 'так званная сортировка "пузыркем" 'Перестановка в массиве NUM_OP temp=NUM_OP(i) NUM_OP(i)=NUM_OP(i+1) NUM_OP(i+1)=temp 'соответсвенная сортировка в массиве NUM_index temp=NUM_index(i) NUM_index(i)=NUM_index(i+1) NUM_index(i+1)=temp end if4. Теперь нужно производить вычисления над числами: Проходишь по массиву NUM_index, по элементно: в нашем случае первый элемент:4 -загоняешь это число в переменную temp Теперь в строке выбираешь значения по номеру temp-1 и temp+1 и записываешь в соответственно в переменные a и b. Они буду содержать для нашего примера a=3, b=5это номера в строке Text1.Text.........соответсвенно они равны 45 и 2...считываем текущую операцию из массива NUM_op в переменную cur_op, она равна 1, что соответствует ВОЗВЕДЕНИЮ В СТЕПЕНЬ....... Вот теперь можно заменить в переменной str=Text1.Text значение по номеру temp-1,temp,temp+1 результатом возведения в степень...теперь операндом с индексом 3 будет не 45^2,а 2025....Продолжаешь двигаться по массиву NUM_index, следующий будет значение в массиве Num_index=2....и проделываем тоже самое.......как ты догодался это все в цикле, в зависимости от величины kol_op Пока, писал вышесказанное придумал, более оптимальное решение...Если возникнуть проблемы пиши на dulevets@list.ru

Ответить

Номер ответа: 4
Автор ответа:
 lnu



Вопросов: 8
Ответов: 14
 Профиль | | #4 Добавлено: 12.12.03 18:24

Тебе обязательно на VB?

Если надо, могу поткинуть модуль написан для Delphi.

В VisuaFoxPro єто совсем тривиальная задачка...

Ответить

Номер ответа: 5
Автор ответа:
 dNW



Вопросов: 30
Ответов: 683
 Профиль | | #5 Добавлено: 13.12.03 09:04

Наверно у меня еще слишком мало мозгов чтобы понять все это!Как бы там ни было,Все ровно большое спасибо!

Ответить

Номер ответа: 6
Автор ответа:
 Александр



Разработчик Offline Client

ICQ: 204034 

Вопросов: 106
Ответов: 1919
 Профиль | | #6 Добавлено: 13.12.03 09:28

Вы что, народ, взяли и загрузили парня!! :(

Ответить

Номер ответа: 7
Автор ответа:
 dNW



Вопросов: 30
Ответов: 683
 Профиль | | #7 Добавлено: 13.12.03 10:22

Да нет! Все в порядке.Просто я еще ОЧЕНЬ мало смыслю в програмирований и уже замахиваюсь на вещи такого масштаба!

Ответить

Номер ответа: 8
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #8
Добавлено: 14.12.03 05:30

А ну! Сейчас же! Всем! Забыть! Про сортировку пузырьком!!!

Только метод шейкера! Он проще пузырька в 100 раз, быстрее в 10 и понятнее в 1,1 раз! Находишь максимальный и минимальный элемент в массиве и обмениваешь их с первым и последним! Продолжаешь, для части массива без двух отсортированных элементов!

Бенчмарк:

пузырек: 191,3 сек

шейкер: 53,1 сек

Ну, не в 10...

Код:

Dim a(10000)

Private Sub Command1_Click()

Randomize Timer

For i = 1 To 10000

a(i) = Rnd(Timer)

Next

End Sub

Private Sub Command2_Click()

t = Timer

For i = 1 To 9999

For j = 1 To 9999

If a(i) > a(i + 1) Then Swap a(i), a(i + 1)

Next

Next

MsgBox Timer - t

End Sub

Private Sub Command3_Click()

t = Timer

For i = 1 To 5000

Min = i

Max = i

For j = i To 10001 - i

If a(i) > a(Max) Then Max = i

If a(i) < a(Min) Then Min = i

Next

Swap a(i), a(Min)

Swap a(10001 - i), a(Max)

Next

MsgBox Timer - t

End Sub

Private Sub Swap(a, b)

t = a

a = b

b = t

End Sub

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам