NOTICE: 本題代碼是按照源碼順序貼上的,複製可直接運行
環境: Visual Stdio Code
說明:本篇轉換思路參考 小甲魚-進制轉換 不要噴,小編口水過敏~謝謝各位少俠
分析:
用棧實現進制轉換需要有:棧的初始化函數、入棧函數、出棧函數、顯示棧元素等函數。而且需要考慮一個問題:怎麼才能讓輸入的一個整型二進制數(如:1100)按位一 一入棧?
入棧原理圖:
即:我們可以利用 char 類型進行存儲,這樣計算機自動將每一位設置一個地址,這樣就能實現按位入棧,從而能夠按位出棧。
代碼:
初始化:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define STACK_INIT_SIZE 10 // 存儲空間初始分配量
#define STACKINCREMENT 1 // 存儲空間分配增量
#define OK 1
#define ERROR 0
typedef int Status;
typedef char SElemType;
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
Status InitStack(SqStack &S)
{ // 初始化
S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) return ERROR;
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}//InitStack
銷燬:
Status DestroyStack(SqStack &S)
{ // 銷燬
if(S.base)
{
delete S.base;
S.stacksize = 0;
S.base = S.top = NULL;
}
return OK;
}//DestroyStack
入棧:
Status Push(SqStack &S, SElemType e)
{ // 入棧
if(S.top - S.base == S.stacksize)
{
S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if(!S.base) return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top ++= e;
return OK;
}//Push
出棧:
Status Pop(SqStack &S, SElemType *e)
{ // 出棧
if(S.top == S.base) return ERROR;
*e = *--S.top;
return OK;
}//Pop
打印棧容量:
Status StackLength(SqStack &S)
{ // 棧的容量
return S.top - S.base;
}//StackLength
顯示棧:
Status StackTraverse(SqStack &S)
{ // 打印棧
SElemType *p = (SElemType *)malloc(sizeof(SElemType));
p = S.top;
if(!p) return ERROR;
else
{
p--;
while(p >= S.base)
{
printf("%d\t", *p);
p--;
}
}
return OK;
}//StackTraverse
主函數:
int main()
{
int i, length, sum = 0;
SqStack S;
SElemType e;
if(InitStack(S)) printf("\n初始化棧成功!\n");
StackTraverse(S);
printf("\n請輸入想要轉換的二進制數:\n");
scanf("%c", &e);
while(e != '\n')
{
Push(S, e);
scanf("%c", &e);
}
getchar();
length = StackLength(S);
printf("\n棧的當前容量爲:%d\n", length);
printf("\n當前的棧爲:\n");
StackTraverse(S);
for(i = 0; i < length; i ++)
{
Pop(S, &e);
sum += (e-48) * pow(2, i);
printf("\n這個 e 爲:%d\n", e);
}
printf("\n對應的十進制爲%d\n", sum);
DestroyStack(S); // 養成用完就釋放內存的好習慣!!!!
return 0;
}
注意:
值得一提的是,在主函數中的出棧操作時,如果寫成
Pop(S, e);
就只會將最後一個字符複製 StackLength(S) 次,並出棧,從而產生一個錯的結果,如下圖所示:
而一個空格(即: \n)的 ASCII 碼正好是10,也就是將 10 “copy” 了 4 次!當然,本篇代碼沒問題(在小編的環境下運行不報錯)。
結果示意圖:
THE END!