引入
我们学习了栈的基本操作,今天我们就看看,栈能为我们做哪些服务,以及如何灵活的使用栈的这些特性。我们就从二进制数转换为十进制数的例子说起。
方法
首先,我们先说明一下二进制转十进制的公式
公式 $n\times 2^{n-1}$
N 表示二进制的从右向左的位数,然后把所有位的和相加,就是十进制结果。
演示
二进制数:$100101$
第 1 位:$1 \times 2^{1-1}=1 \times 1=1$
第 2 位:$0 \times 2^{2-1}=0 \times 2=0$
第 3 位:$1 \times 2^{3-1}=1 \times 4=4$
第 4 位:$0 \times 2^{4-1}=0 \times 8=0$
第 5 位:$0 \times 2^{5-1}=0 \times 16=0$
第 6 位:$1 \times 2^{6-1}=1 \times 32=32$
结果是:$1+0+4+0+0+32=37$
其实就是计算非零数相加。
代码实现
清楚了计算方法之后,我们就通过代码来看看如何实现这个功能
初始化栈
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEN sizeof(int)
#define SLEN sizeof(struct Stack)
#define MAXSIZE 100
#define INCREMENT 10
struct Stack{
int *top;
int *base;
int num;
};
struct Stack *init(struct Stack *s){
s->base=(int *)malloc(MAXSIZE*LEN);
s->top=s->base;
s->num=MAXSIZE;
return s;
}
压栈、出栈、栈长
然后我们写三个函数,能够压栈、出栈、栈长
void push(struct Stack *s , char data){
if(s->top-s->base>=s->num){
s->base=(int *)realloc(s->base,(s->num+INCREMENT)*LEN);
s->top=s->base+s->num;
s->num=s->num+INCREMENT;
}
*(s->top)=data;
s->top++;
}
int pop(struct Stack *s){
if(s->top-s->base==0){
return 0;
}
return *--(s->top);
}
int length(struct Stack *s){
return s->top-s->base;
}
二进制转换
然后是二进制转换
- 根据栈长判断要转换多少位
- 从右向左转换,正好是栈后入先出的顺序
- 因为 push 压入的是 char 类型,所以要减去48,转换成数字
- 然后利用 pwo 函数,计算指数
int translate(struct Stack *s){
if(s->top-s->base==0){
return 0;
}
int sum=0,n=0,len=length(s);
for(int i=0;i<len;i++){
n=pop(s);
sum = sum+(n-48)*pow(2,i);
}
return sum;
}
main 函数主调
int main(){
struct Stack *s;
char n;
s=(struct Stack *)malloc(SLEN);
s=init(s); //初始化栈
printf("请输入二进制数:\n");
scanf("%c",&n);
//利用 while 循环批量输入数值
while(n!='#'){
push(s,n); //压栈
scanf("%c",&n); //再次要求输入
}
getchar(); //这里的 getchar 是为了接收回车符的
printf("栈的容量是:%d\n",length(s));
printf("十进制数为:%d\n",translate(s));
return 0;
}
全部代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEN sizeof(int)
#define SLEN sizeof(struct Stack)
#define MAXSIZE 100
#define INCREMENT 10
struct Stack{
int *top;
int *base;
int num;
};
struct Stack *init(struct Stack *s){
s->base=(int *)malloc(MAXSIZE*LEN);
s->top=s->base;
s->num=MAXSIZE;
return s;
}
void push(struct Stack *s , char data){
if(s->top-s->base>=s->num){
s->base=(int *)realloc(s->base,(s->num+INCREMENT)*LEN);
s->top=s->base+s->num;
s->num=s->num+INCREMENT;
}
*(s->top)=data;
s->top++;
}
int pop(struct Stack *s){
if(s->top-s->base==0){
return 0;
}
return *--(s->top);
}
int length(struct Stack *s){
return s->top-s->base;
}
int translate(struct Stack *s){
if(s->top-s->base==0){
return 0;
}
int sum=0,n=0,len=length(s);
for(int i=0;i<len;i++){
n=pop(s);
sum = sum+(n-48)*pow(2,i);
}
return sum;
}
int main(){
struct Stack *s;
char n;
s=(struct Stack *)malloc(SLEN);
s=init(s);
printf("请输入二进制数:\n");
scanf("%c",&n);
while(n!='#'){
push(s,n);
scanf("%c",&n);
}
getchar();
printf("栈的容量是:%d\n",length(s));
printf("十进制数为:%d\n",translate(s));
return 0;
}
输出结果
请输入二进制数:
10010#
栈的容量是:5
十进制数为:18
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。
评论