6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
1

Перевод инфиксной формы в постфиксную

17.12.2012, 19:38. Показов 2770. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу программу для перевода из инфиксной системы в постфиксную, при работе программы выдает ошибку EAccessviolation, и указывает на Stack. Помогите исправить ошибку,замучался уже

Delphi
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
procedure TForm1.PostFix(s: string; var stack: Tstringlist);
var
Temp:TstringList;
Ms: TMemoryStream;  
begin
Temp:=TStringList.Create;   // создаем вирт. список
Ms:=TMemoryStream.Create;
Ms.WriteBuffer( s[1], Length( s ) ); 
Ms.Position := 0;
with TParser.Create( Ms ) do  // создаем парсер памяти
       begin
   while Token <>toEof do                //  пока токены не кончились
   begin
   if (TokenString[1] in ['0'..'9'] ) then    // если токен - число
   begin
   Stack[Stack.Count-1] := Stack[Stack.Count-1] + TokenString; // помещаем токен в стек ([COLOR="Red"]ЗДЕСЬ ОШИБКУ ВЫДАЁТ[/COLOR]
   end
        else
        Stack.Add(TokenString);   // добавляем токен в конец стека
 //если токен символ
         if ( TokenString[1] in ['+','-','/','*'] ) then
         begin
            // если стек пустой,то помещаем знак в стек
            if Temp.Count = 0 then
               Temp.Add( TokenString )
            else
            begin
               // если приоритет текущей операции выше,чем предыдущей,то помещаем знак в стек
              
               if GetPriority( TokenString[1] ) > GetPriority( Temp.Strings[Temp.Count-1][1] ) then
                  Temp.Add( TokenString )
               else
               begin
                  // иначе извлекаем из стека,пока не встретим операцию с более высоким приоритетом
                  while true do
                  begin
                     Stack.Add( Temp.Strings[Temp.Count-1] );
                     Temp.Delete( Temp.Count-1 );
                     if Temp.Count = 0 then Break;
                     if GetPriority( TokenString[1] ) > GetPriority( Temp.Strings[Temp.Count-1][1] ) then
                        Break;
                  end;
                  // добавляем в стек текущую операцию
                  Temp.Add( TokenString );
               end;
            end;
         end;
        
         if ( TokenString[1] in ['('] ) then
            Temp.Add( TokenString );
       
         if ( TokenString[1] in [')'] ) then
         while true do
         begin
            if Temp.Count = 0 then Break;
            if Temp.Strings[Temp.Count-1] = '(' then
            begin
               Temp.Delete( Temp.Count-1 );
               Break;
            end;
            Stack.Add( Temp.Strings[Temp.Count-1] );
            Temp.Delete( Temp.Count-1 );
         end;
         NextToken;
      end;
   end;
   Ms.Free;
   // если по окончанию работы с формулой в стеке что-то осталось,то извлекаем все в выходной стек
   if Temp.Count <> 0 then
      while Temp.Count <> 0 do
      begin
         Stack.Add( Temp.Strings[Temp.Count-1] );
         Temp.Delete( Temp.Count-1 );
      end;
   Temp.Free;
end;
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.12.2012, 19:38
Ответы с готовыми решениями:

Перевод из инфиксной в постфиксную
ПОМОГИТЕ ПОЖАААЛУЙСТА!!! НУЖНА ПРОГРАММА ПЕРЕВОД ИЗ ИНФИКСНОЙ В ПОСТФИКСНУЮ ФОРМУ ( ГДЕ САМО...

Перевод из инфиксной в постфиксную
#define _CRT_SECURE_NO_WARNINGS #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;math.h&gt; ...

Перевод из инфиксной в постфиксную запись
Суть моей программы: перевод из инфиксной в постфиксную запись. Но проблема в том, что функция...

Перевод из инфиксной записи в постфиксную
Программа очень сырая и вообще не работает вовсе. Как исправить ее? def rpn(s): lex=parse(s)...

14
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
17.12.2012, 23:26 2
Вызов этого метода PostFix покажи. То, что ты передаёшь как Stack, инициализировано?
0
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
18.12.2012, 12:51  [ТС] 3
Вот вызов:
Delphi
1
2
3
4
5
6
7
8
9
10
procedure TForm1.Button1Click(Sender: TObject);
  var
  SS:string;
  ST:TStringList;
   begin
    ss:=Edit1.Text;
   postfix(ss,st);
   Edit2.Text:=st[1]  ;
 
   end;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
18.12.2012, 14:04 4
Инициализируй ST (создай его, через st := TStringList.Create) перед тем как передавать в postfix, у тебя элементарное обращение к объекту, которого не существует.
0
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
18.12.2012, 17:11  [ТС] 5
Точно!Спасибо,исправил! Теперь другая ошибка, List Index out of bounds (-1), вылазает когда мы в Edit2 записываем st[1]
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
18.12.2012, 21:26 6
Обязательно использовать в качестве стека StringList?

Delphi
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
function PostFix(s : string) : string;
 
type
   TokenType = (tkOpen, tkPlus, tkMinus, tkMult, tkDiv, tkClose, tkNumber);
const
   Chars: array[TokenType] of Char = ( '(', '+', '-', '*', '/', ')', ' ' );
   Priority : array[TokenType] of Byte = (0, 1, 1, 2, 2, 5, 10);
 
   function GetToken(Ch : Char) : TokenType;
   var i : TokenType;
   begin
      for i := Low(TokenType) to High(TokenType) do
         if Chars[i] = Ch then Result := i;
   end;
 
var
   toknStack : TStack<TokenType>;
 
   function GetStack(var s : string): TokenType;
   var T: TokenType;
   begin
      T := toknStack.Pop;
      if T <> tkOpen then s := s + ' ' + Chars[T];
      Result := T;
   end;
 
var
   ms : TMemoryStream;
   CurrToken, From : TokenType;
   tt : Char;
 
   tts : TokenType;
begin
   toknStack := TStack<TokenType>.Create;
   ms := TMemoryStream.Create;
   ms.WriteBuffer(AnsiString(s)[1], Length(s));
   ms.Position := 0;
   with TParser.Create(ms) do
   try
      while Token <> toEOF do
      begin
         tt := Token;
         case Token of
            toInteger, toFloat, toSymbol :
               Result := Result + ' ' + TokenString;
            else
            begin
               CurrToken := GetToken(Token);
               case CurrToken of
                  tkOpen :
                     toknStack.Push(tkOpen);
                  tkClose :
                     repeat
                        From := GetStack(Result);
                     until From = tkOpen;
                  tkPlus, tkMinus, tkMult, tkDiv :
                  begin
                     if toknStack.Count > 0 then tts := toknStack.Peek;
                     while (toknStack.Count > 0) and
                           (Priority[CurrToken] <= Priority[toknStack.Peek]) do GetStack(Result);
 
                     toknStack.Push(CurrToken);
                  end;
               end;
            end;
         end;
         NextToken;
      end; { while }
 
      while toknStack.Count > 0 do GetStack(Result);
 
   finally
      Free;
   end;
   Ms.Free;
end;
 
// Вызов :
procedure TForm1.Button1Click(Sender: TObject);
begin
   Edit5.Text := PostFix('(2 + 3)*4 + 5');
end;
Плюсы (по непонятной прихоти разработчиков TParser должны быть выделены пробелами, иначе они распознатся вместе с предыдущим/последующим символом. Скажем, '(2+3)*4+5', хотя знаки умножения прекрасно распознаются и без пробелов)
0
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
24.12.2012, 18:26  [ТС] 7
А как теперь функции объявить эти?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
24.12.2012, 18:35 8
Какие "эти", и зачем их надо объявлять?
0
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
24.12.2012, 18:47  [ТС] 9
Решил попробовать как ты написал,но где эти функции объявлять не пойму:
function PostFix(s : string) : string; // эту в разделе type вместе с кодом ?
function GetToken(Ch : Char) : TokenType;
function GetStack(var s : string): TokenType;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
24.12.2012, 19:28 10
А не надо ничего нигде объявлять. Просто функция PostFix должна располагаться выше места, откуда она вызывается. Это совершенно самостоятельная и самодостаточная функция. Всё, что ей необходимо, объявляется внутри неё. Снаружи ничего не нужно.
0
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
24.12.2012, 19:47  [ТС] 11
Тогда вот так: [DCC Hint] Unit1.pas(84): H2077 Value assigned to 'tts' never used

З.Ы. Я наверное уже надоел

Если всё таки со TStringList делать,попробовал вызов вот так,List Index out of bounds (-1) все равно,не пойму почему :
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
  var
  SS:string;
  ST:TStringList;
  i:integer;
   begin
    ss:=Edit1.Text;
 
   st := TStringList.Create;
   postfix(ss,st);
   for i:=0 to st.Count-1 do
   Edit2.Text:=st[i]; // Сюда переводит
 
   end;
Добавлено через 7 минут
Даже вот так:
[DCC Hint] Unit1.pas(85): H2077 Value assigned to 'tts' never used
[DCC Hint] Unit1.pas(69): H2077 Value assigned to 'tt' never used
[DCC Fatal Error] Unit1.pas(115): F2084 Internal Error: AV21F7E19F-R00000000-0
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
24.12.2012, 19:54 12
Цитата Сообщение от phreaker228 Посмотреть сообщение
Тогда вот так: [DCC Hint] Unit1.pas(84): H2077 Value assigned to 'tts' never used
Во-первых - это не ошибка, и даже не предупреждение, а всего-навсего хинт. А во-вторых, строки с tts и tt вообще можно вышвырнуть, они нужны были для отладки. Вот так:

Delphi
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
function PostFix(s : string) : string;
 
type
   TokenType = (tkOpen, tkPlus, tkMinus, tkMult, tkDiv, tkClose, tkNumber);
const
   Chars: array[TokenType] of Char = ( '(', '+', '-', '*', '/', ')', ' ' );
   Priority : array[TokenType] of Byte = (0, 1, 1, 2, 2, 5, 10);
 
   function GetToken(Ch : Char) : TokenType;
   var i : TokenType;
   begin
      for i := Low(TokenType) to High(TokenType) do
         if Chars[i] = Ch then Result := i;
      // На предупреждение не обращаем внимание, других символов
      // (кроме перечисленных в Chars) в строке быть не может, так что всё нормально
   end;
 
var
   toknStack : TStack<TokenType>;
 
   function GetStack(var s : string): TokenType;
   var T: TokenType;
   begin
      T := toknStack.Pop;
      if T <> tkOpen then s := s + ' ' + Chars[T];
      Result := T;
   end;
 
var
   ms : TMemoryStream;
   CurrToken, From : TokenType;
begin
   toknStack := TStack<TokenType>.Create;
   ms := TMemoryStream.Create;
   ms.WriteBuffer(AnsiString(s)[1], Length(s));
   ms.Position := 0;
   with TParser.Create(ms) do
   try
      while Token <> toEOF do // Пока есть ещё токены
      begin
         case Token of // В зависимости от того, какой токен прочитали, делаем следующее:
 
            toInteger, toFloat, toSymbol : // Если это числа (целое, вещественное) или строка
               Result := Result + ' ' + TokenString; // То просто пишем этот токен в выходную строку
            else
            begin
               CurrToken := GetToken(Token); // Иначе (токен - символ) надо узнать, какой именно символ
               case CurrToken of
                  tkOpen : // Если это открывающаяся скобка
                     toknStack.Push(tkOpen); // Скобка пишется в стек. Это алгоритм перевода в постфикс
                  tkClose : // Закрывающая скобка
 
                     // Из стека выталкиваются все операции, до левой скобки (включительно)
                     repeat
                        From := GetStack(Result);
                     until From = tkOpen;
 
                  tkPlus, tkMinus, tkMult, tkDiv : // Знаки "минус", "плюс", "умножить"
                  begin
 
                     // Выталкиваем из стека и пишем в строку - результат все операции с приоритетом
                     // выше или равным текущему, а саму текущую операцию пишем в стек. Это тоже алгоритм
                     while (toknStack.Count > 0) and
                           (Priority[CurrToken] <= Priority[toknStack.Peek]) do GetStack(Result);
 
                     toknStack.Push(CurrToken);
                  end;
               end;
            end;
         end;
         NextToken; // Переходим к следующему токену
      end; { while }
 
      while toknStack.Count > 0 do GetStack(Result); // Здесь закончили, вытаскиваем из стека всё, что там осталось
 
   finally
      Free;
   end;
   Ms.Free;
end;
Цитата Сообщение от phreaker228 Посмотреть сообщение
Если всё таки со TStringList делать
Это без меня. Использовать список строк там, где нужен стек - нафиг, нафиг.
1
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
24.12.2012, 21:09  [ТС] 13
[DCC Fatal Error] Unit1.pas(112): F2084 Internal Error: AV21F7E19F-R00000000-0
Наверное дело в компиляторе,получается переполнение..у меня делфи 2010,у тебя компилируется?

Добавлено через 43 минуты
С компиляцией проблему решилНо считает немного неправильно!

Добавлено через 18 минут
Последняя просьба Напиши комментарии к строчкам,кое-где не понятно,что делается!
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32793 / 21133 / 8144
Регистрация: 22.10.2011
Сообщений: 36,393
Записей в блоге: 8
25.12.2012, 13:56 14
Всё нормально компилируется и работает (если учесть то, что написано в самом низу 6-го поста). Тестировалось в XE2.

Комментарии добавлены в предыдущий пост.
1
6 / 6 / 0
Регистрация: 22.12.2010
Сообщений: 91
25.12.2012, 15:17  [ТС] 15
Огромное спасибо! Все допилил,теперь работает как нужно
0
25.12.2012, 15:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.12.2012, 15:17
Помогаю со студенческими работами здесь

Перевод из инфиксной записи в постфиксную
Всем привет! Ребята, помогите пожалуйста решить задачу. Нужно написать программу с использованием...

Перевод выражения из инфиксной в постфиксную форму
Перевести выражение из инфиксной в постфиксную форму. Вот мой код. Почему то на некоторых примерах...

Перевод арифметического выражения из инфиксной форму в постфиксную
Помогите написать код, попытки были но неудачные . polsk=raw_input(&quot;vvedi polskyy &quot;) #infix or...

Преобразования инфиксной формы в постфиксную
Во входном файле задана корректная инфиксная форма арифметического выражения , содержащая ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru