c++ - 在 C++ 中使用带有 Stack 模板的字符串时遇到问题
问题描述
我有一个任务,我们必须用后缀和中缀操作做一些事情。我的教授向我们提供了所有代码,其中 main 中的一段代码为空,供我们执行某些后缀操作。我正在尝试实现他提供的带有字符串的 Stack 模板,但它不起作用。这是 main 的代码(您可以忽略所有注释掉的部分):
#include "stack.hpp"
using namespace std;
int main()
{
cout << endl << "Start" << endl;
Stack<string> stack;
//string s = "hello world";
//char s = 'h';
//stack.push(s);
//cout << endl << endl << stack.pop() << endl << endl;
return 0;
}
/*
// Auxiliary method, you probably find it useful
// Operands are all lower case and upper case characters
bool isOperand(char c){
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
// Auxiliary method, you probably find it useful
int precedence(char c)
{
if(c == '+' || c == '-'){
return 0;
}
if(c == '*' || c == '/'){
return 1;
}
if(c == '^'){
return 2;
}
return -1;
}
int main(){
cout << endl << "start" << endl;
freopen("input_postfix2infix.txt", "r", stdin);
string input;
string solution;
int line_counter = 0;
cout << endl << "before loop" << endl;
while(cin >> solution){
cin >> input;
Stack<string> stack;
string result;
//The input file is in the format "expected_solution infix_expression",
//where expected_solution is the infix_expression in postfix format
string s = "hello world";
//char s = 'h';
stack.push(s);
cout << endl << endl << stack.pop() << endl << endl;
//cout << input << endl << endl;
for(int i=0; i<input.length(); ++i){
char c = input.at(i);
if(isalnum(c))
{
string s;
s.push_back(c);
stack.push(s);
}
else
{
if(c == '+')
{
string a = stack.pop();
string b = stack.pop();
string sum = a + '+' + b;
sum = '(' + sum + ')';
stack.push(sum);
}
else if(c == '-')
{
string a = stack.pop();
string b = stack.pop();
string diff = b + '-' + a;
diff = '(' + diff + ')';
stack.push(diff);
}
else if(c == '*')
{
string a = stack.pop();
string b = stack.pop();
string prod = a + '*' + b;
prod = '(' + prod + ')';
stack.push(prod);
}
else if(c == '/')
{
string a = stack.pop();
string b = stack.pop();
string quot = b + '/' + a;
quot = '(' + quot + ')';
stack.push(quot);
}
else if(c == '^')
{
string exp = stack.pop();
string a = stack.pop();
string power = a + '^' + exp;
power = '(' + power + ')';
stack.push(power);
}
}
// WRITE CODE HERE to store in 'result' the postfix transformation of 'input'
}
result = stack.pop();
// You need to do some extra stuff here to store in 'result' the postfix transformation of 'input'
// Checking whether the result you got is correct
if(solution == result){
cout << "line " << line_counter << ": OK [" << solution << " " << result << "]" << endl;
}else{
cout << "line " << line_counter << ": ERROR [" << solution << " " << result << "]" << endl;
}
line_counter++;
}
}
*/
如果我注释掉堆栈声明(“Stack<string> stack;”),则程序编译并在运行时输出“Start”。但是,如果我包含堆栈声明,程序似乎再次成功编译,但是当我运行它时,绝对没有任何反应。这就是我注释掉所有其余代码的原因,所以我可以在较小的范围内对其进行测试,但仍然没有。我什至在教授提供的 Stack cpp 文件的末尾包含了模板字符串声明。
这是我的教授提供的 Stack.hpp:
//#include <bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
// Ideally this would not be a huge number, you could also use a vector
#define MAXSIZE 100000
using namespace std;
template<class T>
class Stack{
private:
T arr[MAXSIZE]; // the actual stack
int topIndex; // index of the top element
public:
Stack(){
topIndex = -1; // constructor
};
~Stack(){}; // destructor
void push(T c); // push c to the list
T pop(); // return and remove the top element in the stack
T peek(); // return the top element in the stack
int size(); // returns the size of the stack
void display(); // display the stack in stdout
};
这是我的教授也提供的 Stack.cpp(我在末尾添加了“模板类 Stack<string>;”):
#include "stack.hpp"
using namespace std;
template<class T>
void Stack<T>::push(T c){
if(topIndex > MAXSIZE-1){
cout<<"Stack overflow"<<endl;
return;
}
arr[topIndex + 1] = c;
topIndex++;
}
template<class T>
T Stack<T>::pop(){
if(topIndex < 0){
cout<<"Cannot delete. Stack empty."<<endl;
}
return arr[topIndex--];
}
template<class T>
T Stack<T>::peek(){
if(topIndex < 0){
cout<<"Cannot peek. Stack empty."<<endl;
}
return arr[topIndex];
}
template<class T>
int Stack<T>::size(){
return topIndex+1;
}
template<class T>
void Stack<T>::display(){
for(int i=topIndex; i>=0; --i){
cout<<arr[i]<<"\t";
}
cout<<endl;
}
template class Stack<char>;
template class Stack<int>;
template class Stack<string>;
我不明白发生了什么事。我认为在 Stack.cpp 末尾添加声明可以解决我遇到的所有问题(之前,我遇到了一堆“未定义的引用...”错误)但是,现在我也遇到了这个问题。有人可以帮我理解为什么这不起作用吗?任何帮助将不胜感激。顺便说一句,一切都与“Stack<int>”和“Stack<char>”完美配合,它只是“Stack<string>”,我遇到了这个问题。谢谢你。
我已经尝试阅读一堆与此类似的问题的其他答案,但没有一个能回答我的问题。我已经使用了显式实例化我将在 .cpp 文件末尾使用的实现的方法,但我的程序仍然无法正常工作。我不想将所有内容都移到头文件中,因为该文件最初不是我的(我只想进行细微的编辑,并且只有在绝对必要的情况下)。
解决方案
大多数编译器都sizeof(std::string)
等于 24 字节(x32 架构)或 32 字节(x64 架构)。通过在, will be或中创建100000
字符串数组。Stack<std::string>
sizeof(Stack<std::string>)
100000 * 24 = 2.28MiB
100000 * 32 = 3.05MiB
然后您尝试在自动内存区域(也称为“堆栈内存”,因为它通常是这样实现的)中创建这样的对象。这种记忆是非常有限的。实际限制取决于您的操作系统(也可能会更改),但对于 Unix 系统,默认情况下通常为 8 MiB,对于 Windows,则为 1 MiB(请参阅此问题)。
您可以修改操作系统中的自动存储量,但推荐的方法是降低MAXSIZE
或使用动态分配。后者最好用C++std::vector<T>
或std::unique_ptr<T[]>
在 C++ 中完成。
推荐阅读
- javascript - 我可以使用表达式作为对象属性的值吗?
- xamarin.forms - 动态更新的 Xamarin.Forms ContentPage 内容不响应 iOS 平台的用户操作
- python - 来自 numba 的 jit 和来自 scipy 的 hypergeom 的断言错误
- python - pd.merge 给出错误:DataFrame' 对象是可变的,因此它们不能被散列
- java - Spring Boot - Jwts.builder 无法解析方法'signWith()'
- json - 按字母顺序对 JSON 对象数组以及 dart 中属性的布尔值进行排序
- javascript - 在特定索引后随机播放数组
- sql - 循环数组游标不循环多次 - SQL SERVER
- android - LiveData 返回错误的对象
- c# - 使用 iText c# 从页眉和页脚中删除文本