題目: 設計一個進位轉換程式,使用順序棧設計一個把十進位數轉換為十六進位數的介面,實現當通過鍵盤輸入一個非負的十進位數,可以在終端輸出對應的十六進位數。 例如: 100 --> 0x64 --> 100%16 = 4 --> 100/16 = 6 6%16 = 6 題目分析: 該題需要對用戶 ...
題目:
設計一個進位轉換程式,使用順序棧設計一個把十進位數轉換為十六進位數的介面,實現當通過鍵盤輸入一個非負的十進位數,可以在終端輸出對應的十六進位數。
例如:
100 --> 0x64 --> 100%16 = 4 --> 100/16 = 6 6%16 = 6
題目分析:
該題需要對用戶輸入的十進位數用短除法取餘,並且把取餘的數從棧頂存儲到順序棧中,在從棧頂依次輸出數據,體現棧的”先進後出“的特點;
-
因為轉換的是十六進位,所以需要考慮當餘數大於9時用字母A~F進行表示;
-
順序棧記憶體儲的數據會存在字母A~F情況,所以在出棧輸出時,統一採用 ”%c”輸出,那麼在入棧時,需將存儲的數據轉換成ASII碼進行存儲
-
因為採用的是順序棧,需要提前決定棧的容量,所以需要創建一個足夠大的順序棧
演算法實現:
/********************************************************************* * * name : SeqStack_BaseConversion * function : 根據用戶輸入的非負數十進位數,利用順序棧轉換為十六進位數 併在終端輸出 * argument : * @Manager :順序棧的地址 * * retval : 調用成功返回新的棧地址 * author : [email protected] * date : 2024/04/25 * note : none * * *****************************************************************/ void SeqStack_BaseConversion(SeqStack_t *Manager) { //定義一個字元變數 用於存儲用戶輸入的十進位數 DataType_t data = 0; printf("Please input a Decimal number :\n "); scanf("%d", &data); //對讀取到的數進行判斷 if(data < 0 ) { printf("Please input the correct number !\n"); getchar(); return; } //定義一個迴圈變數 DataType_t i = 0; //對獲取的非負十進位數進行取餘操作,並且將餘數存儲進順序棧中 for (i = data; i > 16;i = i /16) { if(i>16) { //餘數入棧 if((i%16) > 9) { SeqStack_Push(Manager, (i % 16)+55); } else SeqStack_Push(Manager, (i % 16)+48); continue; } SeqStack_Push(Manager, i+48); } SeqStack_Push(Manager, i+48); //輸出十六進位數 printf("%d = 0x", data); for (int i = Manager->Top;i>=0 ;i--) { printf("%c", SeqStack_Pop(Manager)); } printf("\n"); return; }
整體代碼展示:
/*******************************************************************
*
* file name: SequenceStack_demo.c
* author : [email protected]
* date : 2024/04/25
* function : 該案例是利用順序棧實現一個將十進位轉換成十六進位
* note : None
*
* CopyRight (c) 2023-2024 [email protected] All Right Reseverd
*
* *****************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改
typedef int DataType_t;
//構造記錄順序棧SequenceStack各項參數(棧底地址+棧容量+棧頂元素的下標)的結構體
typedef struct SequenceStack
{
DataType_t * Bottom; //記錄棧底地址
unsigned int Size; //記錄棧容量
int Top; //記錄棧頂元素的下標
}SeqStack_t;
/*********************************************************************
*
* name : SeqStack_Create
* function : 創建一個空的順序棧,併為記錄順序棧信息的結構體
申請堆記憶體,併進行初始化即可!
* argument :
* @size :棧的容量大小
*
* retval : 調用成功返回順序棧的地址
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
//創建順序表並對順序棧進行初始化
SeqStack_t * SeqStack_Create(unsigned int size)
{
//1.利用calloc為順序棧的管理結構體申請一塊堆記憶體
SeqStack_t *Manager = (SeqStack_t *)calloc(1,sizeof(SeqStack_t));
if(NULL == Manager)
{
perror("calloc memory for manager is failed");
exit(-1); //程式異常終止
}
//2.利用calloc為所有元素申請堆記憶體
Manager->Bottom = (DataType_t *)calloc(size,sizeof(DataType_t));
if (NULL == Manager->Bottom)
{
perror("calloc memory for Stack is failed");
free(Manager);
exit(-1); //程式異常終止
}
//3.對管理順序棧的結構體進行初始化(元素容量 + 最後元素下標)
Manager->Size = size; //對順序棧中的容量進行初始化
Manager->Top = -1; //由於順序棧為空,則棧頂元素的下標初值為-1
return Manager;
}
/*********************************************************************
*
* name : SeqStack_IsFull
* function : 判斷順序棧是否已滿
* argument :
* @Manager :順序棧的地址
*
* retval : 調用成功返回bool型,滿了則返回true,沒滿返回false
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
bool SeqStack_IsFull(SeqStack_t *Manager)
{
return (Manager->Top + 1 == Manager->Size) ? true : false;
}
/*********************************************************************
*
* name : SeqStack_Push
* function : 根據棧的特性,把新元素從棧頂入棧,也就是從數組的尾部進行元素插入
* argument :
* @Manager :順序棧的地址
@Date :要入棧的數據
*
* retval : 調用成功返回bool型,滿了則返回true,沒滿返回false
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
//入棧
bool SeqStack_Push(SeqStack_t *Manager, DataType_t Data)
{
//1.判斷順序棧是否已滿
if ( SeqStack_IsFull(Manager) )
{
printf("SeqStack Full is Full!\n");
return false;
}
//2.如果順序棧有空閑空間,則把新元素添加到順序棧的棧頂
Manager->Bottom[++Manager->Top] = Data;
return true;
}
/*********************************************************************
*
* name : SeqStack_IsEmpty
* function : 判斷順序棧是否為空
* argument :
* @Manager :順序棧的地址
*
* retval : 調用成功返回bool型,空了則返回true,沒空返回false
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
bool SeqStack_IsEmpty(SeqStack_t *Manager)
{
return (-1 == Manager->Top) ? true : false;
}
/*********************************************************************
*
* name : SeqStack_Pop
* function : 根據棧的特性,把元素從棧頂出棧,也就是把元素從數組的尾部把元素刪除
* argument :
* @Manager :順序棧的地址
*
* retval : 調用成功返回新的棧地址
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
//出棧
DataType_t SeqStack_Pop(SeqStack_t *Manager)
{
DataType_t temp = 0; //用於存儲出棧元素的值
//1.判斷順序棧是否為空
if ( SeqStack_IsEmpty(Manager) )
{
printf("SeqStack is Empty!\n");
return;
}
//2.由於刪除了一個元素,則需要讓順序棧的棧頂元素下標-1
temp = Manager->Bottom[Manager->Top--];
return temp;
}
/*********************************************************************
*
* name : SeqStack_BaseConversion
* function : 根據用戶輸入的非負數十進位數,利用順序棧轉換為十六進位數
併在終端輸出
* argument :
* @Manager :順序棧的地址
*
* retval : 調用成功返回新的棧地址
* author : [email protected]
* date : 2024/04/25
* note : none
*
* *****************************************************************/
void SeqStack_BaseConversion(SeqStack_t *Manager)
{
//定義一個字元變數 用於存儲用戶輸入的十進位數
DataType_t data = 0;
printf("Please input a Decimal number :\n ");
scanf("%d", &data);
//對讀取到的數進行判斷
if(data < 0 )
{
printf("Please input the correct number !\n");
getchar();
return;
}
//定義一個迴圈變數
DataType_t i = 0;
//對獲取的非負十進位數進行取餘操作,並且將餘數存儲進順序棧中
for (i = data; i > 16;i = i /16)
{
if(i>16)
{
//餘數入棧
if((i%16) > 9)
{
SeqStack_Push(Manager, (i % 16)+55);
}
else
SeqStack_Push(Manager, (i % 16)+48);
continue;
}
SeqStack_Push(Manager, i+48);
}
SeqStack_Push(Manager, i+48);
//輸出十六進位數
printf("%d = 0x", data);
for (int i = Manager->Top;i>=0 ;i--)
{
printf("%c", SeqStack_Pop(Manager));
}
printf("\n");
return;
}
int main(int argc, char const *argv[])
{
//創建一個容量足夠大的順序棧
SeqStack_t *SequenceStack = SeqStack_Create(1000000000);
//執行進位轉換演算法
while(1)
{
SeqStack_BaseConversion(SequenceStack );
}
return 0;
}
結果展示:
演算法設計待優化點:
- 順序棧的容量是否能夠隨著用戶輸入值所需空間大小變化
- 用戶不輸入整型數,演算法怎麼識別並返回初始狀態