Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [VBA Excel] Реализация польской записи (нотации), Решение формулы по польской записи 
V
    Опции темы
tuhovsky
Дата 28.2.2010, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.1.2010

Репутация: нет
Всего: нет



deleted

Это сообщение отредактировал(а) tuhovsky - 6.3.2010, 16:40
PM MAIL   Вверх
alex77755
Дата 28.2.2010, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 18.4.2009

Репутация: нет
Всего: нет



Решение польской записи осуществляется реализуется разнесением чисел по регистрам с последующим выполнением действий
Так как это предлагается сделать в Ёкселе, необходимо разделять цифры. Пример для двух цифр с разделителем "!"
выполняется при нажатии "Ентер" в ячейке 125!56!*

Код

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$A$2" Then
Dim Z1, z2, Znak, S
Dim M() As String
S = Range("A1").Value
M = Split(S, "!")

Range("A2").Value = Val(M(0))
Range("A3").Value = M(2)
Range("A4").Value = Val(M(1))
Range("A5").Value = "="
Select Case M(2)
Case "+"
Range("A6").Value = Val(M(0)) + Val(M(1))
Case "-"
Range("A6").Value = Val(M(0)) - Val(M(1))
Case "*"
Range("A6").Value = Val(M(0)) * Val(M(1))
Case "/"
Range("A6").Value = Val(M(0)) / Val(M(1))
End Select
End If
End Sub

PM MAIL   Вверх
tuhovsky
Дата 28.2.2010, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.1.2010

Репутация: нет
Всего: нет



deleted

Это сообщение отредактировал(а) tuhovsky - 6.3.2010, 16:41
PM MAIL   Вверх
Sanaff
Дата 28.2.2010, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 15.9.2009
Где: г. Северодвинск

Репутация: -1
Всего: 1



Цитата

Можно ли для уровня студента первокурсника, с обычными while for if массивом и функцией val, без "наворотов", вот просто одна программа, без функций без сложностей, и всё сразу делает, выводит все числа и ответ,

Разделение на числа - там без наворотов можно, примерно как у Вас. А польская запись - посложнее будет, Вы алгоритм видели? . я подумаю, как попроще сделать...
--------------------
Программист - это локальный бог ©ICQ 373-628-456
PM MAIL WWW ICQ   Вверх
tuhovsky
Дата 28.2.2010, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.1.2010

Репутация: нет
Всего: нет



deleted

Это сообщение отредактировал(а) tuhovsky - 6.3.2010, 16:40
PM MAIL   Вверх
Sanaff
Дата 1.3.2010, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 15.9.2009
Где: г. Северодвинск

Репутация: -1
Всего: 1



Не только с последним числом, но и с тройными произведениями a*b*c не работает
Завтра попробую выложить правильный код

--------------------
Программист - это локальный бог ©ICQ 373-628-456
PM MAIL WWW ICQ   Вверх
FallFan
Дата 2.3.2010, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 30.3.2008
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Основа алгоритма была взята с Википедии (http://ru.wikipedia.org/wiki/Обратная_польская_запись), код не оптимизирован. Если вставить этот код в модуль (*.bas), то эти функции можно будет вызывать как стандартные в Excel (необходимо в окне выбора функции выбрать "определенные пользователем")

Function Normal_to_POLIZ(InputString As String) As String - преобразовывает нормальную запись в ПОЛИЗ
   InputString  - выражение в нормальном ввиде (можно и с пробелами)

Function POLIZ_Solve(POLIZ_Expression As String) As Double - вычисление выражения написанного в ПОЛИЗ (для проверки)
   POLIZ_Expression - выражение в в иде ПОЛИЗ, между числами и операторами разделитель пробел (" ") с другим разделителем работать не будет (можно исправить в функции Split)

Function Priority(Func As String) As Byte - функция определения приоритета операции (необходима для работы Normal_to_POLIZ)

Код

Option Explicit

Function Normal_to_POLIZ(InputString As String) As String
Dim OutLine As String
Dim Stack() As String
Dim Brick() As String
Dim Workstring As String
Dim c1 As Integer
Dim c2 As Integer
Dim c3 As Integer
Dim c4 As Integer
Dim c6 As Integer
Dim cS As Integer
Dim i As Integer

OutLine = ""
Workstring = ""

'Убираем пробелы
For i = 1 To Len(InputString)
    If Mid(InputString, i, 1) <> " " Then Workstring = Workstring + Mid(InputString, i, 1)
Next

'Разбиваем выражение на элементы "число и "оператор"
c1 = 1

For i = 1 To Len(Workstring)
    If IsNumeric(Mid(Workstring, i, 1)) Then
        ReDim Preserve Brick(c1)
        Brick(c1) = Brick(c1) + Mid(Workstring, i, 1)
    Else
        c1 = c1 + 1
        ReDim Preserve Brick(c1)
        Brick(c1) = Mid(Workstring, i, 1)
        c1 = c1 + 1
    End If
Next

'Построение выражения ПОЛИЗ (ПОЛьская Инверсная Запись
cS = 0
ReDim Stack(cS)
Stack(cS) = ""

For c3 = 1 To UBound(Brick)
    If IsNumeric(Brick(c3)) Then
        OutLine = OutLine + Brick(c3) + " "
    Else
        If Priority(Brick(c3)) > Priority(Stack(cS)) Then
            cS = cS + 1
            ReDim Preserve Stack(cS)
            Stack(cS) = Brick(c3)
        Else
            OutLine = OutLine + Stack(cS) + " "
            ReDim Preserve Stack(cS)
            Stack(cS) = Brick(c3)
            For c6 = cS To 1 Step -1
                If Priority(Stack(c6)) <= Priority(Stack(c6 - 1)) Then
                    OutLine = OutLine + Stack(c6 - 1) + " "
                    Stack(c6 - 1) = Stack(c6)
                    cS = cS - 1
                    ReDim Preserve Stack(cS)
                End If
            Next
        End If
    End If
Next

For c4 = cS To 1 Step -1
    OutLine = OutLine + Stack(c4) + " "
Next

'Вывод результата
Normal_to_POLIZ = OutLine

End Function
Function POLIZ_Solve(POLIZ_Expression As String) As Double

Dim BrickS() As String
Dim c7 As Integer
Dim c8 As Integer
Dim c9 As Integer

c9 = 0
c7 = 0
BrickS = Split(Trim(POLIZ_Expression))

Do Until UBound(BrickS) = 0 Or c7 = 100
    If Not (IsNumeric(BrickS(c7))) Then
        Select Case BrickS(c7)
            Case "+"
                BrickS(c7 - 2) = CDbl(BrickS(c7 - 2)) + CDbl(BrickS(c7 - 1))
                BrickS(c7 - 1) = ""
                BrickS(c7) = ""
            Case "-"
                BrickS(c7 - 2) = CDbl(BrickS(c7 - 2)) - CDbl(BrickS(c7 - 1))
                BrickS(c7 - 1) = ""
                BrickS(c7) = ""
            Case "*"
                BrickS(c7 - 2) = CDbl(BrickS(c7 - 2)) * CDbl(BrickS(c7 - 1))
                BrickS(c7 - 1) = ""
                BrickS(c7) = ""
            Case "/"
                BrickS(c7 - 2) = CDbl(BrickS(c7 - 2)) / CDbl(BrickS(c7 - 1))
                BrickS(c7 - 1) = ""
                BrickS(c7) = ""
            Case "^"
                BrickS(c7 - 2) = CDbl(BrickS(c7 - 2)) ^ CDbl(BrickS(c7 - 1))
                BrickS(c7 - 1) = ""
                BrickS(c7) = ""
        End Select
        For c8 = 0 To UBound(BrickS)
            If BrickS(c8) <> "" Then
                BrickS(c9) = BrickS(c8)
                c9 = c9 + 1
            End If
        Next
        ReDim Preserve BrickS(UBound(BrickS) - 2)
        c7 = -1
        c9 = 0
    End If
    c7 = c7 + 1
Loop

POLIZ_Solve = BrickS(0)

End Function

Function Priority(Func As String) As Byte

Priority = 0

Select Case Func
    Case "^"
        Priority = 3
    Case "*"
        Priority = 2
    Case "/"
        Priority = 2
    Case "+"
        Priority = 1
    Case "-"
        Priority = 1
End Select

End Function


PM   Вверх
tuhovsky
Дата 6.3.2010, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.1.2010

Репутация: нет
Всего: нет



спс, программка с польскими приоритетами сильная, но препод не поверит мне, так что пришлось доработать свою:

я дописал свой бред, добавил правильную работу типа ...*...*...*... несколько одинаковых знаков подряд, код получился на 111 строк XD, принёс один из всей группы и сдал)))
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0490 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.