在 C++ 中将字符串与 Stack 模板一起使用时遇到问题
Having trouble with using string with Stack template in C++
我有一个任务,我们必须用后缀和中缀操作做一些事情。我的教授向我们提供了所有代码,并在 main empty 中有一段代码供我们执行某些后缀操作。我正在尝试实现他提供的带有字符串的 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 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(我在最后添加了“模板class Stack;”):
#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 末尾添加声明可以解决我遇到的所有问题(之前,我遇到了一堆“undefined reference too...”错误)但是,现在我也遇到了这个问题。有人可以帮我理解为什么这不起作用吗?任何帮助将不胜感激。顺便说一句,一切都与“Stack”和“Stack”完美配合,它只是“Stack”,我遇到了这个问题。谢谢。
我已经尝试阅读了很多其他类似问题的答案,但其中 none 回答了我的问题。我已经使用了显式实例化我将在 .cpp 文件末尾使用的实现的方法,但我的程序仍然无法运行。我不想将所有内容都移动到头文件中,因为该文件最初不是我的(我只想进行较小的编辑,并且只有在我绝对必须这样做的情况下)。
大多数编译器 sizeof(std::string)
等于 24 字节(x32 架构)或 32 字节(x64 架构)。通过在 Stack<std::string>
中创建 100000
字符串数组,sizeof(Stack<std::string>)
将是 100000 * 24 = 2.28MiB
或 100000 * 32 = 3.05MiB
.
然后您尝试在自动内存区域(也称为“堆栈内存”,因为它通常是这样实现的)中创建这样的对象。此内存非常有限。实际限制取决于您的 OS(也可能会更改),但对于 Unix 系统,默认情况下通常为 8 MiB,对于 Windows 则为 1 MiB(请参阅 this question) .
您可以修改 OS 中的自动存储量,但推荐的方法是降低 MAXSIZE
或使用动态分配。后者最好用 C++ 中的 std::vector<T>
或 std::unique_ptr<T[]>
来完成。
我有一个任务,我们必须用后缀和中缀操作做一些事情。我的教授向我们提供了所有代码,并在 main empty 中有一段代码供我们执行某些后缀操作。我正在尝试实现他提供的带有字符串的 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
这是我的教授提供的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(我在最后添加了“模板class Stack
#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 末尾添加声明可以解决我遇到的所有问题(之前,我遇到了一堆“undefined reference too...”错误)但是,现在我也遇到了这个问题。有人可以帮我理解为什么这不起作用吗?任何帮助将不胜感激。顺便说一句,一切都与“Stack
我已经尝试阅读了很多其他类似问题的答案,但其中 none 回答了我的问题。我已经使用了显式实例化我将在 .cpp 文件末尾使用的实现的方法,但我的程序仍然无法运行。我不想将所有内容都移动到头文件中,因为该文件最初不是我的(我只想进行较小的编辑,并且只有在我绝对必须这样做的情况下)。
大多数编译器 sizeof(std::string)
等于 24 字节(x32 架构)或 32 字节(x64 架构)。通过在 Stack<std::string>
中创建 100000
字符串数组,sizeof(Stack<std::string>)
将是 100000 * 24 = 2.28MiB
或 100000 * 32 = 3.05MiB
.
然后您尝试在自动内存区域(也称为“堆栈内存”,因为它通常是这样实现的)中创建这样的对象。此内存非常有限。实际限制取决于您的 OS(也可能会更改),但对于 Unix 系统,默认情况下通常为 8 MiB,对于 Windows 则为 1 MiB(请参阅 this question) .
您可以修改 OS 中的自动存储量,但推荐的方法是降低 MAXSIZE
或使用动态分配。后者最好用 C++ 中的 std::vector<T>
或 std::unique_ptr<T[]>
来完成。