数据结构与算法分析课后习题第三章(7)

本文介绍了一个自定义的双向链表实现,并通过具体实例展示了如何使用栈来检查符号配对、评估后缀表达式以及进行表达式的转换。此外,还提供了从中缀到后缀再到中缀表达式的转换程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.19 Rewrite the List class without using header an tail nodes and describe the differences between the class and the class provided in Section 3.5

3.21 Write a program to check for balancing symbols: (/**/,(),[],{})

3.22 Write a program to evaluate a postfix expression.

3.23 a. Write a program to convert an infix expression that includes (, ), +, -, * and  / to postfix.

b. Add the exporientiation operator to your repertoire.

c. Write a program to convert a postfix expression to infix.

//3.19 list.hpp

#ifndef LIST_HPP__
#define LIST_HPP__

#include <iosfwd>

template< typename Object >
class List {
private:
 class Node {
 public:
  Node(const Object& val = Object(), Node* n = 0, Node* p = 0)
   : next(n), prev(p), data(val){}

 public:
  Node* next;
  Node* prev;
  Object data;
 };
public:
 List() : theSize(0), head(0), tail(0) {}
 ~List()
 {
  clear();
 }
 
 bool empty() const { return theSize == 0; }
 const int size() const { return theSize; }

 void push_back(const Object& val)
 {
  if(empty())
  {
   Node* newnode = new Node(val);
   head = newnode;
   tail = newnode;
   ++theSize;
  }
  else
  {
   Node* newnode = new Node(val, 0, tail);
   tail->next = newnode;
   tail = newnode;
   ++theSize;
  }
 }

 void pop_back()
 {
  if(empty())
   return;

  Node* p = tail;
  tail = tail->prev;
  tail->next = 0;
  delete p;
  --theSize;
 }

 void push_front(const Object& val)
 {
  if(empty())
  {
   Node* newnode = new Node(val);
   head = newnode;
   tail = newnode;
   ++theSize;
  }
  else
  {
   Node* newnode = new Node(val,head,0);
   head->prev = newnode;
   head = newnode;
   ++theSize;
  }
 }

 void pop_front()
 {
  if(empty())
   return;

  Node* p = head;
  head = head->next;
  head->prev = 0;
  delete p;
  --theSize;
 }

 void clear()
 {
  while(!empty())
  {
   if(head == tail)
   {
    delete head;
    --theSize;
   }
   else
   {
    pop_back();
   }
  }
 }

 void print(std::ostream& out)
 {
  if(empty())
   return;
  
  Node* p = head;
  while(p->next != 0)
  {
   out << p->data << "/n";
   p = p->next;
  }

  out << p->data << "/n";
 }

private:
 List(const List&);
 List& operator=(const List&);

 Node* head;
 Node* tail;
 int theSize;
};

#endif

//3.21 stack.hpp

#ifndef STACK_HPP__
#define STACK_HPP__

template< typename Object >
class Stack {
public:
 Stack(const int size = 0)
 { init(size); }
 
 const int size() const { return theSize; }
 bool empty() const { return theSize == 0; }
 const int capacity() const { return theCapacity; }

 void push(const Object& val)
 {
  if(theSize == theCapacity)
   reserve(2 * theCapacity + 1);

  objects[theSize++] = val;
 }

 void pop()
 {
  if(theSize > 0)
   --theSize;
 }

 Object top()
 {
  return objects[size() - 1];
 }

private:
 void resize(const int newSize)
 {
  if(newSize > theCapacity)
   reserve(newSize * 2 + 1);
  theSize = newSize;
 }

 void reserve(const int newCapacity)
 {
  if(newCapacity < theSize)
   return;

  Object* old = objects;

  objects = new Object[newCapacity];

  for(int i = 0; i < theSize; ++i)
   objects[i] = old[i];

  theCapacity = newCapacity;

  delete[] old;
 }

 void init(const int size)
 {
  objects = new Object[size + SPARE_CAPACITY];
  theSize = 0;
  theCapacity = size + SPARE_CAPACITY;
 }

 Stack(const Stack&);
 Stack& operator=(const Stack&);

 Object* objects;
 int theSize;
 int theCapacity;
 enum { SPARE_CAPACITY = 16 };

};

#endif

//main.cpp

#include "stack.hpp"
#include <iostream>
#include <string>

using namespace std;

void testPair()
{
 Stack<string> stack;
 string s(""), expected("");
 while(s != "e" && s != "E")
 {
  cout << "Enter symbols to test, e to end: /n";
  cin >> s;
  
  
  if(s == expected)
  {
   stack.pop();
   if(!stack.empty())
   {
    string temp = stack.top();
    if(temp == "(")
    {
     expected = ")";
    }  
    else if(temp == "[")
    {
     expected = "]";
    }
    else if(temp == "{")
    {
     expected = "}";
    }
    else if(temp == "/*")
    {
     expected = "*/";
    }
   }

  }
  else if(s != "e" && s != "E")
  {
   

   if(s == "(")
   {
    stack.push(s);
    expected = ")";
   }  
   else if(s == "[")
   {
    stack.push(s);
    expected = "]";
   }
   else if(s == "{")
   {
    stack.push(s);
    expected = "}";
   }
   else if(s == "/*")
   {
    stack.push(s);
    expected = "*/";
   }
   else
   {
    expected = "";
   }
  }
  else
   break;
 }

 if( stack.empty() )
 {
  cout << "You entered symbol form pairs/n";
 }
 else
 {
  cout << "The symbols you entered do not form pairs/n";
 }
 
}

int main()
{
 while(true)
 testPair();

 
 
 return 0;
}

//3.22  stack.hpp

#ifndef STACK_HPP__
#define STACK_HPP__

template< typename Object >
class Stack {
public:
 Stack(const int size = 0)
 { init(size); }
 
 const int size() const { return theSize; }
 bool empty() const { return theSize == 0; }
 const int capacity() const { return theCapacity; }

 void push(const Object& val)
 {
  if(theSize == theCapacity)
   reserve(2 * theCapacity + 1);

  objects[theSize++] = val;
 }

 void pop()
 {
  if(theSize > 0)
   --theSize;
 }

 Object top()
 {
  return objects[size() - 1];
 }

private:
 void resize(const int newSize)
 {
  if(newSize > theCapacity)
   reserve(newSize * 2 + 1);
  theSize = newSize;
 }

 void reserve(const int newCapacity)
 {
  if(newCapacity < theSize)
   return;

  Object* old = objects;

  objects = new Object[newCapacity];

  for(int i = 0; i < theSize; ++i)
   objects[i] = old[i];

  theCapacity = newCapacity;

  delete[] old;
 }

 void init(const int size)
 {
  objects = new Object[size + SPARE_CAPACITY];
  theSize = 0;
  theCapacity = size + SPARE_CAPACITY;
 }

 Stack(const Stack&);
 Stack& operator=(const Stack&);

 Object* objects;
 int theSize;
 int theCapacity;
 enum { SPARE_CAPACITY = 16 };

};

#endif

//main.cpp

#include "stack.hpp"
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

int parsePostfixExp(string input)
{
 Stack<int> stack;
 
 for(size_t i = 0; i < input.length(); ++i)
 {
  if(input[i] != '+' && input[i] != '-' && input[i] != '*' && input[i] != '/')
  { 
   char temp[] = {input.at(i)};
   stack.push(atoi(temp)); 
  }
  else
  {
   int num1, num2;
   num1 = stack.top();
   stack.pop();
   num2 = stack.top();
   stack.pop();

   switch(input[i])
   {
   case '+':
    stack.push(num2 + num1);
    break;
    
   case '-':
    stack.push(num2 - num1);
    break;

   case '*':
    stack.push(num2 * num1);
    break;

   case '/':
    stack.push(num2 / num1);
    break;

   default:
    break;
   }
  }
 }

 if(stack.size() == 1)
 { return stack.top(); }
 else
 { return -1; }
}

int main()

 string input;
 cin >> input;

 cout << parsePostfixExp(input);
 
 return 0;
}

//3.23 stack.hpp

#ifndef STACK_HPP__
#define STACK_HPP__

template< typename Object >
class Stack {
public:
 Stack(const int size = 0)
 { init(size); }
 
 const int size() const { return theSize; }
 bool empty() const { return theSize == 0; }
 const int capacity() const { return theCapacity; }

 void push(const Object& val)
 {
  if(theSize == theCapacity)
   reserve(2 * theCapacity + 1);

  objects[theSize++] = val;
 }

 void pop()
 {
  if(theSize > 0)
   --theSize;
 }

 Object top()
 {
  if(!empty())
   return objects[size() - 1];
  return Object();
 }

private:
 void resize(const int newSize)
 {
  if(newSize > theCapacity)
   reserve(newSize * 2 + 1);
  theSize = newSize;
 }

 void reserve(const int newCapacity)
 {
  if(newCapacity < theSize)
   return;

  Object* old = objects;

  objects = new Object[newCapacity];

  for(int i = 0; i < theSize; ++i)
   objects[i] = old[i];

  theCapacity = newCapacity;

  delete[] old;
 }

 void init(const int size)
 {
  objects = new Object[size + SPARE_CAPACITY];
  theSize = 0;
  theCapacity = size + SPARE_CAPACITY;
 }

 Stack(const Stack&);
 Stack& operator=(const Stack&);

 Object* objects;
 int theSize;
 int theCapacity;
 enum { SPARE_CAPACITY = 16 };

};

#endif

//infix to postfix itopconvert.hpp

#include "stack.hpp"
#include <string>

std::string infixToPostfix(const std::string& input)
{
 std::string retVal;
 enum priority{ UNUSE = -2, LOWEST = -1, LOW = 0, MID = 1, HIGH = 2, HIGHER = 3, HIGHEST = 4};

 struct Symbol {
  char symbol;
  priority pri;
  bool parFlag;
 };

 Stack<Symbol> stack;
 Symbol item;

 for(size_t i = 0; i < input.length(); ++i)
 {
  int data = input.at(i);
  if(data != '+' && data != '-' && data != '*' && data != '/'
   && data != '(' && data != ')' && data != '^')
  {
   retVal.push_back(data);
  }
  else
  {
   switch(data)
   {
   case '+':
    item.symbol = '+';
    item.parFlag = false;
    item.pri = LOW;
    break;

   case '-':
    item.symbol = '-';
    item.parFlag = false;
    item.pri = LOW;
    break;

   case '*':
    item.symbol = '*';
    item.pri = MID;
    item.parFlag = false;
    break;

   case '/':
    item.symbol = '/';
    item.parFlag = false;
    item.pri = MID;
    break;

   case '(':
    item.symbol = '(';
    item.parFlag = true;
    item.pri = HIGHEST;
    break;

   case ')':
    item.symbol = ')';
    item.parFlag = false;
    item.pri = LOWEST;
    break;

   case '^':
    item.symbol = '^';
    item.parFlag = false;
    item.pri = HIGHER;
    break;

   default:
    break;
   }

   if(stack.empty() || stack.top().pri < item.pri || stack.top().parFlag == true)
   {
    stack.push(item);
   }
   else if(item.symbol == ')')
   {
    while(stack.top().symbol != '(')
    {
     retVal.push_back(stack.top().symbol);
     stack.pop();
    }
    stack.pop();   
   }
   else if(stack.top().pri >= item.pri)
   {
    while(!stack.empty() && stack.top().pri >= item.pri && stack.top().symbol != '(')
    {
     retVal.push_back(stack.top().symbol);
     stack.pop();
    }

    stack.push(item);
   }
  }
 }

 while(!stack.empty())
 {
  retVal.push_back(stack.top().symbol);
  stack.pop();
 }

 return retVal;
}

//postfix to infix ptoiconvert.hpp

#ifndef PTOICONVERT_HPP__
#define PTOICONVERT_HPP__

#include <string>

std::string postfixToInfix(std::string input)
{
 Stack<std::string> stack;

 for(size_t i = 0; i < input.length(); ++i)
 {
  if(input[i] != '+' && input[i] != '-' && input[i] != '*'
   && input[i] != '/' && input[i] != '^')
  { 
   char a[] = {input[i],'/0'};
   stack.push(a); 
  }
  else
  {
   std::string num1, num2,temp;

   if(!stack.empty())
   {
    num1 = stack.top();
    stack.pop();
   }

   switch(input[i])
   {
   case '+':
    if(!stack.empty())
    {
     temp = stack.top() + "+" + num1;
     stack.pop();
     stack.push(temp);
    }
    break;

   case '-':
    if(!stack.empty())
    {
     temp = stack.top() + "-" + num1;
     stack.pop();
     stack.push(temp);
    }
    break;

   case '*':
    if(!stack.empty())
    {
     temp = stack.top() + "*" + num1;
     stack.pop();
     stack.push(temp);
    }
    break;

   case '/':
    if(!stack.empty())
    {
     temp = stack.top() + "/" + num1;
     stack.pop();
     stack.push(temp);
    }
    break;

   case '^':
    if(!stack.empty())
    {
     temp = stack.top() + "^" + num1;
     stack.pop();
     stack.push(temp);
    }
    break;

   default:
    break;
   }
  }
 }

 if(stack.size() == 1)
 { return stack.top(); }
 else
 { return "-1"; }
}

#endif

//main.cpp

#include "itopconvert.hpp"
#include "ptoiconvert.hpp"
#include <iostream>

using namespace std;

int main()

 string input;
 cin >> input;

 cout << postfixToInfix(infixToPostfix(input));

 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值