将Infix转换为前缀表示法
Convert Infix to Prefix Notation
我有一个任务:制作一个程序(C++),它将"中缀"表示法转换为"前缀",并使用自己的"堆栈和队列"实现。
但我在void main() { /*...*/ system("pause"); }
的最后一个字符串或在void toPrefix();
的最后一字符串得到:"Critical error detected c0000374"
和"Free Heap block modified at ... after it was freed"
有人能帮我指出我的错误吗?
Source.cpp:
#include "iostream"
#include "fstream"
#include "string"
#include "Stack.h"
#include "Queue.h"
void toPrefix(const std::string& first)
{
int length = first.length();
char test = NULL, operand = NULL;
char *ptr = &test, *op_ptr = &operand;
Queue<char> List;
std::string Output;
Stack<char> OpStack;
for (int i = length - 1; i >= 0; i--) List.push(first[i]); //
while (List.getsize() != 0)
{
List.pop(ptr);
if (test >= 48 && test <= 57) //is it number?
{
Output.insert(Output.begin(), test);
}
if (test == '*' || test == '/' || test == '-' || test == '+')
{
OpStack.push(test);
}
if (test == ')')
{
OpStack.push(test);
}
if (test == '(')
{
OpStack.pop(op_ptr);
while (operand != ')')
{
Output.insert(Output.begin(), operand);
OpStack.pop(op_ptr);
}
}
}
}
void main()
{
const std::string& first = "9-(2+2)";
toPrefix(first);
system("pause");
}
队列.h:
#include<iostream>
template <typename T>
class Queue
{
private:
struct queue_element
{
T value;
queue_element *next;
};
queue_element *first;
queue_element *last;
int size;
public:
Queue()
{
first = new(queue_element);
last = first;
first->value = -1;
first->next = 0;
size = 0;
}
Queue(T x)
{
first = new(queue_element);
last = first;
first->value = x;
first->next = 0;
size = 1;
}
int getsize()
{
return size;
}
void push(T value)
{
if (size == 0)
{
size++;
last = first;
first->value = value;
first->next = 0;
}
else
{
size++;
queue_element *temp = new(queue_element);
temp->next = 0;
temp->value = value;
last->next = temp;
last = temp;
}
}
void pop(T* ret)
{
if (size == 0)
{
std::cout << "Queue is empty!" << std::endl;
return;
}
queue_element *temp = first;
*ret = first->value;
first = first->next;
size--;
}
void peek(T *ret)
{
if (size == 0)
{
std::cout << "Queue is empty!" << std::endl;
return;
}
*ret = first->value;
}
};
堆栈.h
#include <iostream>
template <typename T>
class Stack
{
private:
struct stack_element
{
T value;
stack_element *next;
};
stack_element *first;
stack_element *last;
int size;
public:
Stack()
{
last = new(stack_element);
first = last;
last->value = -1;
last->next = first;
size = 0;
}
Stack(T x)
{
last = new(stack_element);
first = last;
last->value = x;
last->next = 0;
size = 1;
}
int getsize()
{
return size;
}
void push(T value)
{
if (size == 0)
{
size++;
last->value = value;
last->next = first;
}
else
{
size++;
stack_element *temp = new(stack_element);
temp->next = last;
temp->value = value;
last = temp;
}
}
void pop(T* ret)
{
if (size == 0)
{
std::cout << "Stack is empty!" << std::endl;
return;
}
stack_element *temp = last;
*ret = last->value;
last = last->next;
delete temp;
size--;
}
void peek(T *ret)
{
if (size == 0)
{
std::cout << "Stack is empty!" << std::endl;
return;
}
*ret = first->value;
}
};
嗯。。。我认为问题出在你的Stack
课上。
传递给toPrefix()
的字符串是"9-(2+2)"
所以Stack<char> OpStack
中的操作,在toPrefix()
中定义的,是(如果我理解得很好的话)
-
使用默认(无参数)构造函数构建
-
与
-
对应的push()
-
pop()
与(
对应 -
push()
对应于+
-
与
)
对应的push()
好吧,让我们看看中发生了什么
1)在使用默认构造函数构造之后
我们有
1a)size == 0
1b)指向相同分配的存储器区域的first
、last
、first->next
和last->next
1c)first->value == last->value == (char)-1
2)在第一次呼叫push()
(使用-
)后
我们有
2a)size == 1
2b)指向相同分配的存储器区域的first
、last
、first->next
和last->next
2c)first->value == last->value == '-'
3)在第一次呼叫pop()
之后
我们有
3a)size == 0
3b)指向相同DELETED内存区域的first
、last
、first->next
和last->next
3c)first->value == last->value == '-'
4)第二次调用push()
(带+
)
4a)size
递增
4b)写入(last->value = value;
)删除区域
4c)在删除区域中再次写入(last->next = first;
)
我想这可以解释你的问题。
附言:Rambo Ramon和Sam Varshavchik提出的"使用调试器"建议是一个很好的建议(IMHO)
p.s.2:很抱歉我的英语不好
- 表示"accepting anything for this template argument" C++概念的通配符
- 如何将ampl中的集合表示为c++中的向量
- std::is_base_of表示ctor编译错误
- 输入中的字符串数未知(以字母表示)
- 我可以信任表示整数的浮点或双精度来保持精度吗
- c++模板来表示多项式
- 询问在设计我的手臂模拟器功能表示格式1
- CMakeLists.txt中的命名空间表示法
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 如何计算Big-O表示法中的平均渐近运行时间
- 我应该如何表示我拥有的连续元素序列?
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 编译器如何在前缀和 postix 运算符之间进行区分?
- 前缀表示法 C++,分段错误(堆栈和队列)
- 将Infix转换为前缀表示法
- c++中的前缀递归表示法
- 为什么内置类型的链式前缀递增/递减不是 UB 表示C++
- 前缀表示法字符串到int的转换
- 将前缀表达式树向量转换为ORF/Karva表示法表达式树向量