1.堆栈(顺序栈,链式栈)队列(顺序队列,链式队列)
2.栈扩容
新开辟一个更大的栈,将之前的数据压入这个新栈
3.进制转换
数字n转化为m进制(m为16进制以下)
#include<stdio.h> int main(){ int i,a,b,c,d,n,m,top; char zhan[100],yu[]={"0123456789ABCDEF"};//余数 scanf("%d %d",&n,&m); top=0; while(n!=0){ zhan[top++]=yu[n%m]; n=n/m; } if(n%m!=0) zhan[top++]=yu[n%m]; for(i=top-1;i>=0;i--) printf("%c",zhan[i]); return 0; }
3.括号匹配
一开始提交的时候出现了超栈的情况,由于栈顶指针初值为0,第一个是右括号时会出现zhan[-1]的情况,把top初值改为1后就成功通过了。
bool isValid(char * s){ char zhan[10005]; int top,ss;//栈指针,字符串指针 top=1;ss=0; zhan[0]='1'; while(s[ss]!='\0'){ if(s[ss]=='('||s[ss]=='['||s[ss]=='{') zhan[top++]=s[ss]; else{ if((s[ss]==')'&&zhan[top-1]=='(')||(s[ss]==']'&&zhan[top-1]=='[')||(s[ss]=='}'&&zhan[top-1]=='{')) { top--; } else{ return false; } } ss++; } if(top!=1) return false; return true; }
4.n对括号有多少种合法匹配序列(与栈混洗有关系)
1
5.算术表达式求值
关于中缀表达式,后缀表达式这类问题,里面涉及到一些输入问题,之前也因为输入问题被卡过,大一的时候学过但是现在都忘记
(45条消息) 喵呜 来啦来啦:C语言gets(),scanf()与getchar()函数的区别_gets和getchar的区别_爱吃榴莲的喵星人的博客-CSDN博客这个讲scanf与gets的感觉很清晰
scanf函数是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量中。所以如果数字后紧挨着字符,输入十进制时并不会把字符也读入。
scanf :当遇到回车,空格和tab键会认为输入结束,但是回车,空格和tab键仍会留在输入的缓冲区中。(如果后续需要输入字符,记得getchar()把回车,空格先吞去)
gets:可接受回车键之前输入的所有字符,回车键不会留在输入缓冲区中
至于getchar
图1;
图2,
图3:
图二图三表明输入之后的回车会进入到缓冲区并可被getchar;但图一输入1之后的回车却并被输出出来,很奇怪。(45条消息) getchar与scanf的区别_getchar和scanf的区别_冀然的编程学习的博客-CSDN博客
后缀表达式求值
题目:剑指 Offer II 036. 后缀表达式 - 力扣(Leetcode)
判断是否是数字时需要用ASCII码((45条消息) ASCII码字符对照表 阿斯克码表_我爱沐兮的博客-CSDN博客)
int zhuan(char *a){//字符串转化为十进制 int i,zhi; i=0; if(a[0]=='-') i=1; zhi=0; while(a[i]!='\0') {zhi=zhi*10+a[i]-48;//不是单纯相加 i++;//循环要加1 }if(a[0]==45) zhi=0-zhi; printf("%d ",zhi); return zhi; } int suan(int a,int b,char c){//数值计算 if(c=='+') return a+b; if(c=='-') return a-b; if(c=='*') return a*b; if(c=='/') return a/b; return 0;//即使前面有返回,最后也要写一个返回 } int evalRPN(char ** tokens, int tokensSize){ int i,r,zhan[10000],top; top=0; for(i=0;i<tokensSize;i++){ if((tokens[i][0]>=48&&tokens[i][0]<=57)||(tokens[i][0]=='-'&&tokens[i][1]!='\0')) { r=zhuan(tokens[i]); zhan[top++]=r; } else{ r=suan(zhan[top-2],zhan[top-1],tokens[i][0]); zhan[top-2]=r; top--; } } return zhan[0]; }
这里字符转化成数字的时候不是直接相加
while循环要更改每次一该变的变量
一个函数即使前面有返回,最后也要来个return,不然可能会报错
中缀表达式转后缀
题目:P1175 表达式的转换 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)(没做)
直接中缀转后缀
(45条消息) C语言常见问题——数组初始化的四种方法_易水卷长空的博客-CSDN博客
数组不初始化,值是随机的,也可能由于编译器的版本初始值为0.,一定要初始化
#include<stdio.h>//中缀转后缀,数字大于0 ,以#结尾 int ji(char a){//级别 if(a=='*'||a=='/') return 2; if(a=='+'||a=='-') return 1; } int main(){ int i,j,sp1,sp2,zp; char s[1000],shi[100][10],zhan[100]; scanf("%s",s); i=0; sp1=0;sp2=0;zp=0; while(s[i]!='#'){//除#外,还有运算符,括号,数字 if(s[i]>=48&&s[i]<=57){//数字 shi[sp1][sp2]=s[i]; i++; sp2++; while(s[i]>=48&&s[i]<=57) shi[sp1][sp2++]=s[i++]; shi[sp1][sp2]='\0';//一定要赋'\0',便于之后的输出 ,不在开始赋值因为数据量过大 i--; sp2=0; sp1++; } else{if(s[i]=='(')//左括号 zhan[zp++]='('; else{ if(s[i]==')')//右括号 {while(zhan[--zp]!='(') shi[sp1++][sp2]=zhan[zp]; } else{//运算符 while(zp!=0&&zhan[zp-1]!='('&&ji(s[i])<=ji(zhan[zp-1])){ { shi[sp1++][sp2]=zhan[--zp]; shi[sp1-1][sp2+1]='\0'; } } zhan[zp++]=s[i]; } } } i++; } if(zp!=0){//弹出剩余的运算符 shi[sp1++][sp2]=zhan[--zp]; shi[sp1-1][sp2+1]='\0'; } for(i=0;i<=sp1;i++){//输出 j=0; while(shi[i][j]!='\0') printf("%c",shi[i][j++]); printf(" "); } return 0; }
结果:(我感觉例子挺全的)
#include<string.h>包括
中缀表达式直接求值
中缀表达式直接求值其实就是 在中缀表达式转后缀 的基础上,把运算符进入表达式的时候直接弹出两个数计算之后再压入表达式,最后表达式中只有一个数字就是结果。
既然中缀表达式可以直接求值,那么转换为后缀表达式的价值何在?【清华大学2019年考研题】
(1)中缀表达式→后缀表达式→求值
(2)中缀表达式→求值
6.递归与回溯
7.栈混洗
8.队列应用
9.单调栈和单调队列