栈应用C++

这篇博客涵盖了多种递归算法的应用,包括表达式求值、背包问题和链表操作。通过实例展示了如何使用递归解决实际问题,如中缀表达式转后缀表达式并计算结果、0-1背包问题的动态规划解决方案以及单链表的逆序插入和遍历。同时,还讨论了递归在前缀输出和进制转换中的应用。
摘要由CSDN通过智能技术生成

魔法机
/**
魔法机  默认顺序入栈,输入出栈序列,系统自动查看是否合法
**/
void mofaji()
{
    int i,n;
    int num[100];
    SqStack s;
    initStack(s);
    cout<<"请输入入栈元素个数(0退出):"<<endl;
    cin>>n;
    while(n)
    {
        // stack <int> s;
        cout<<"请输入出栈个数"<<endl;
        for(i=1; i<=n; i++)
            cin>>num[i];
        int k=1;
        for(i=1; i<=n; i++)
        {
            // s.push(i);
            push(s,i);
            //while(!s.empty()&& num[k]==s.top())
            while(s.top!=-1 && num[k]==s.data[s.top])
            {
                //s.pop();
                int e;
                pop(s,e);
                k++;
            }
        }
        //if(s.empty())
        if(s.top==-1)
        {
            cout<<"该出栈序列合法!"<<endl;
        }
        else
            cout<<"该出栈序列不合法!"<<endl;
        cout<<'\n';
        cout<<"请输入入栈元素个数(0退出):"<<endl;
        cin>>n;
    }
}
背包问题
/**
背包问题
**/
void knapsack1(int w[],int T,int n)
{
    SqStack S;
    initStack(S);
    int k=0,m=0;
    do
    {
        while(T>0&&k<n)
        {
            if(T>=w[k])
            {
                push(S,k);
                T=T-w[k];
            }
            k++;
        }
        if(T==0)
        {
            m++;
            StackTraverse(S,w);
        }
            pop(S,k);
            T=T+w[k];
            k++;
    }
    while(S.top!=-1||k!=n);
    cout<<"总共有"<<m<<"组装法"<<endl;
}
void test_knapsack1()
{
     int n,t;
     cout<<"请输入物品个数:";cin>>n;
     cout<<"请输入各个物品重量: ";
     int *w=new int[n];
     for(int i=0;i<n;i++)
     {
         cin>>w[i];
     }
     cout<<"请输入书包可以承受的重量:"<<endl;
     cin>>t;
   // int w[5]= {1,7,4,6,2};
    knapsack1(w,t,n);
//knapsack1(w,10,5);
}
表达式求值
#include <iostream>
#include <stack>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;
void pop_c(stack <char> &S,char &e)
{
    e=S.top();      //取栈顶元素
    S.pop();        //出栈
}
void pop_c(stack <double> &S,double &e)
{
    e=S.top();      //取栈顶元素
    S.pop();        //出栈
}
/**
四则运算表达式求值
**/
void trans(char *exp,char postexp[])
{
    char e;
    stack <char> S;
    int i=0;    //i为postexp的下标
    while(*exp!='\0')   //循环到末尾
    {
        switch(*exp)  //判断exp的值
        {
        case '(':           //判断为左括号
            S.push('(');    //左括号进栈
            exp++;          //继续扫描下一个字符
            break;
        case ')':            //判断为右括号
            pop_c(S,e);      //元素出栈并把值赋给e
            while(e!='(')   //如果不是左括号就往下循环,字符出栈,找知道左括号为止
            {
                postexp[i++]=e;     //将e存放到postexp中
                pop_c(S,e);      //元素出栈并把值赋给e
            }
            exp++;              //找到左括号说明完成了,字符数组往后遍历
            break;
        case '+':
        case '-':           //加法和减法的优先级相同,所以同理处理
            while(!S.empty())   //
            {
                e=S.top();      //检查栈顶元素,不为左括号,说明不能入栈,等待优先级高的先出栈
                if(e!='(')
                {
                    postexp[i++]=e;
                    pop_c(S,e);      //元素出栈并把值赋给e
                }
                else    break;
            }
            S.push(*exp);   //其他都出栈了,由于优先级最低,此时栈空,进栈
            exp++;      //数组往下遍历
            break;
        case '*':
        case '/':           //乘除优先级相同,同理处理
            while(!S.empty())      //遍历,遍历条件是栈顶元素的优先级不能和乘除平级,平级栈顶元素出栈
            {
                e=S.top();
                if(e=='*'||e=='/')
                {
                    postexp[i++]=e;//将e存放到postexp
                    pop_c(S,e);      //元素出栈并把值赋给e
                }
                else break;
            }
            S.push(*exp);       //没有了优先级比它高的,那就进栈
            exp++;          //数组往下遍历
            break;
        default:                        //处理数字字符
            while(*exp>='0' && *exp<='9')   //判定为数字字符,只要是数字,直接转给后缀表达式数组索引位并++
            {
                postexp[i++]=*exp;
                exp++;
            }
            postexp[i++]='#' ;  //用#标识一个数字串结束,处理几位数的情况
        }
    }
    while(!S.empty())       //处理后期还有算数符号存在的情况,全出栈并追加到后缀表达式数组中去
    {
        pop_c(S,e);      //元素出栈并把值赋给e
        postexp[i++]=e;
    }
    postexp[i]='\0';    //'\0'字符串结束符号
}
double compvalue(char *postexp)
{
    double d,a,b,c,e;
    stack <double> S;
    while(*postexp!='\0')
    {
        /**
        遍历数组,如果是数字字符,把它转换成数字,并且进栈,
        如果是算数运算符,遍历到一个,就出栈两个数,进行相应运算,再进栈
        以实现正确的顺序运算
        **/
        switch(*postexp)
        {
        case '+':
            pop_c(S,a);
            pop_c(S,b);
            c=a+b;
            S.push(c);
            break;
        case '-':
            pop_c(S,a);
            pop_c(S,b);
            c=b-a;
            S.push(c);break;
        case '*':
            pop_c(S,a);
            pop_c(S,b);
            c=b*a;
            S.push(c);break;
        case '/':
            pop_c(S,a);
            pop_c(S,b);
            if(a!=0)
            {
                c=b/a;
                S.push(c);break;
            }else{
                cout<<"除0错误"<<endl;
                exit(0);
            } break;
        default:
            d=0;
            while(*postexp>='0'&&*postexp<='9')
            {
                d=10*d+*postexp-'0';
                postexp++;
            }
            S.push(d);
 break;
        }
        postexp++;  //每进行完一轮判断,就让数组往后遍历
    }
    e=S.top();//最后会得到最后运算出来的值,返回即可
    return e;
}
void test_compvalue()
{   char e1[100],*exp=e1,postexp[100];
    string str;
    cout<<"请输入中缀表达式:";
    cin>>str;
    int length=str.copy(e1,str.size());//字符串转字符数组
    e1[length]='\0';
    trans(exp,postexp);
    double e=compvalue(postexp);
    cout<<"表达式的结果是:"<<e;}
int main()
{
    test_compvalue();
    return 0;
}
4.14 关于递归的题
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}*LinkList;
void f(int n,int i)
{
    if(n==0)
        return;
    cout<<"前n="<<n<<",前i="<<i<<endl;
    i++;
    f(n-1,i);
    cout<<"后n="<<n<<",后i="<<i<<endl;
}
//递归进制转换 num为十进制数,i为转换的进制
void change(int num,int i)
{
    if(num==0)
        return;
    change(num/i,i);
    cout<<num%i;
}
void test_change()
{
    int num,i;
   cout<<"  请输入转换的数:";
   cin>>num;
   cout<<"  输入需要转换成为的进制:";
   cin>>i;
   cout<<"  10转"<<i<<" : ";
    change(num,i);
}
//2.输入一个整数 求出各位数    123   1 2 3
void demo2(int num)
{
    if(num==0) return;
    demo2(num/10);
    cout<<num%10<<" ";
}
//3.逆序输入一个字符串 输入 abc 得到的字符串为 cba
void demo3(string str,int n)
{
    if(n==0) return;
    cout<<str.substr(n-1,1);
    demo3(str,n-1);
}
void test_demo3()
{
    string str;
    cin>>str;
    demo3(str,str.size());
}
//4.用递归的方法创建和输出一个不带头结点的单链表
//L分成两部分(第一个结点和L->next)
void demo4(LinkList &L)
{
    int i;
    LinkList p=new LNode;
    cin>>i;
    if(i==-999) return;
    p->data=i;
    p->next=NULL;
    if(L!=NULL)
    {   p->next=L;
        L=p;
    }else{
        L=p;
        cout<<"顺序输出:";
    }
    demo4(L);
    cout<<i<<" ";
}
//遍历单链表
void travel_list(LinkList &L)
{
    LinkList p;
    p=L;
   while(p)
   {
       cout<<p->data;
       p=p->next;
   }
}
void test_demo4()
{
    LinkList  L;
    L=NULL;
    cout<<"请倒序插入元素到单链表(输入-999结束):";
    demo4(L);
}
//5.求串的长度
void demo5(string str,int &i)
{
    if(str.at(i)==*str.rbegin())
    {
       i++;
       return;
    }
    i++;
    demo5(str,i);
}
void test_demo5()
{
    string str;
    cout<<"请输入字符串:";
    cin>>str;
    int i=0;
    demo5(str,i);
    cout<<"字符串长度为:";
    cout<<i;
}

int main()
{
   // f(5,0);
    //test_change();
   // demo2(100);
    //test_demo3();
    //test_demo5();
    test_demo4();
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值