一步一步复习数据结构和算法基础-栈的应用(2)

来源:互联网 发布:网络扫描工具 安卓 编辑:程序博客网 时间:2024/06/06 01:51

先前写了括号匹配,这里再给出两个栈的应用-回文数和进制转换;

首先是回文数,回文数理解起来很简单的,但是--我写的太麻烦了。。。。。。

看来还是需要加强自己的代码质量,这里权当复习。。。

回文数在我的理解中就是中心对称的字符串(assa)。所以如果想用栈来解决回文数的判断我的理解是一半字符串入栈,然后依次和后面一半的字符串进行逐字符的比较。

但是要注意对于字符串长度为奇数的字符串,要把中间的字符去掉(如asdfgfdsa)。这里我用了两个栈来判断回文数。

void Judge(SqStack s,SqStack tmps){char ch;int flag=0,temp;while((ch = getchar())!='\n'){Push(&s,ch);}flag = StackLength(&s);temp = flag;while(flag != (temp/2)){Push(&tmps,GetTop(&s));Pop(&s);flag--;}if(temp%2==1)Pop(&tmps);while(flag){if(GetTop(&s) != GetTop(&tmps))break;flag--;}if(flag == 0)printf("这是回文字符.\n");else printf("这不是回文字符.\n");}

这个代码是越看越挫啊。。。。。

不管这些还有一个基于栈的应用:进制转换。

进制转换的内容很多,但是可以触类旁通,这里写写十进制转换为其它进制的程序:

十进制转各进制 
要将十进制转为各进制的方式,只需除以各进制的权值,取得其余数,第一次的余数当个位数,第二次余数当十位数,
其余依此类推,直到被除数小于权值,最后的被除数当最高位数。 
一、十进制转二进制 
如:55转为二进制 
2|55 
27――1 个位 
13――1 第二位 
6――1 第三位 
3――0 第四位 
1――1 第五位 
最后被除数1为第七位,即得110111 
二、十进制转八进制 
如:5621转为八进制 
8|5621 
702 ―― 5 第一位(个位) 
87 ―― 6 第二位 
10 ―― 7 第三位 
1 ―― 2 第四位 
最后得八进制数:127658 
三、十进制数十六进制 
如:76521转为十六进制 
16|76521 
4726 ――5 第一位(个位) 
295 ――6 第二位 
18 ――6 第三位 
1 ―― 2 第四位 
最后得1276516 

有了这些进制转换的代码不难写:


void SysConvert(int number,SqStack s,int newscale)//number转换的数字(10进制) s进制转换利用的栈,newscale转换后新的进制。{while(number){Push(&s,number%newscale);number /= newscale;}StackTraverse(&s);}

进制转换之后的数字就保存在栈里面,遍历栈即可。

下面给出完整代码:

#include <stdio.h>#include <stdlib.h>#define STACK_INIT_SIZE 100//栈空间的初始分配量#define STACKINCREMENT 10//存储空间的分配增量typedef char SElemType;typedef struct{SElemType *base;//在构造栈之前和销毁栈之后,base的数值为NULLSElemType *top;//栈顶指针int stacksize;//显示栈当前的容量}SqStack;//创建一个空栈int InitStack(SqStack *s);//销毁栈int DestroyStack(SqStack *s);//清空栈int ClearStack(SqStack *s);//判断栈是否为空栈int StackEmpty(SqStack *s);//计算栈的长度int StackLength(SqStack *s);//获取栈顶元素int GetTop(SqStack *s);//将一个元素推入站内int Push(SqStack *s,SElemType data);//将一个元素退出栈int Pop(SqStack *s);//对于栈内的每一个元素调用函数int StackTraverse(SqStack *s);int InitStack(SqStack *s){s->base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);//为栈分配基础空间if(!s->base)exit(1);//分配失败的话就退出s->top = s->base;//栈顶指针指向栈底s->stacksize = STACK_INIT_SIZE;//初始化栈的大小return 1;}int Push(SqStack *s,SElemType data){if(s->top-s->base >= s->stacksize)//如果栈的空间不够再增加{s->base = (SElemType *)realloc(s->base,(s->stacksize + STACKINCREMENT)*sizeof(SElemType));if(!s->base)exit(1);//在原来空间的基础上额外增加空间s->top = s->base + s->stacksize;//栈顶指针加1s->stacksize += STACKINCREMENT;//栈大小增加}*s->top++ = data;//元素入栈,栈顶指针加1return 1;//入栈成功}int Pop(SqStack *s){if(s->base == s->top) return 0;//如果栈为空栈返回出栈失败(*--s->top);//栈顶指针减1return 1;//出栈成功}int GetTop(SqStack *s){if(s->base == s->top)return 0;//空栈返回失败return *(s->top-1); //返回栈顶元素}int StackLength(SqStack *s){SElemType *tmp = s->top;//设置临时变量和栈顶指针相同int flag = 0;while(tmp != s->base)//栈顶指针逐个减1知道栈底{flag ++;tmp--;}return flag;//返回栈的长度}int DestroyStack(SqStack *s){free(s->base);//释放掉栈的分配空间s->base = s->top = NULL;//栈顶和栈底指向NULLs->stacksize = 0;//栈的长度还原为0return 1;}int ClearStack(SqStack *s){s->top = s->base;//栈清空最方便只需要将栈顶指针指向栈底return 1;}int StackTraverse(SqStack *s){SElemType *tmp = (s->top-1);if(s->top == s->base)return 0;while(1){printf("%d",*tmp);if(tmp == s->base) break;//这个地方我刚刚犯了一个错误就是忽视栈底base指针指向的区域也有一个数据tmp--;}return 1;}void Judge(SqStack s,SqStack tmps){char ch;int flag=0,temp;while((ch = getchar())!='\n'){Push(&s,ch);}flag = StackLength(&s);temp = flag;while(flag != (temp/2)){Push(&tmps,GetTop(&s));Pop(&s);flag--;}if(temp%2==1)Pop(&tmps);while(flag){if(GetTop(&s) != GetTop(&tmps))break;flag--;}if(flag == 0)printf("这是回文字符.\n");else printf("这不是回文字符.\n");}void SysConvert(int number,SqStack s,int newscale)//number转换的数字(10进制) s进制转换利用的栈,newscale转换后新的进制。{while(number){Push(&s,number%newscale);number /= newscale;}StackTraverse(&s);}int main(){SqStack s;int number,newscale;InitStack(&s);scanf("%d%d",&number,&newscale);SysConvert(number,s,newscale);ClearStack(&s);DestroyStack(&s);return 0;}


原创粉丝点击