数制转换
在计算机中经常面对不同数制的转换问题,如将一个十进制数N转换为d进制B。数制转换的解决方法很多,其中一个简单的转换算法是重复下述两步。直到N等于零为止。
x = N mod d
N = N div d
其中,N为需要转换的十进制数,d为转换后的进制,x值为转换后各个数位上的数,div为整除运算,mod为求余运算。算法的运行过程为:第一次求出的x值为d进制数的最低位,最后一次求出的x值为d进制数的最高位,所以上述算法是从低位到高位顺序产生d进制的各位,然后逆序输出,因为它按“后进先出”的规律进行的,所以用栈这种结构处理最合适。根据这个特点,利用栈来实现上述数制转换,即将计算过程种一次得到的d进制数码按顺序栈进栈。计算结束后,再返顺序出栈,并按出栈顺序打印输出。这样即可得到给定的十进制数对应的d进制数,由此可以得到数制转换的算法。
实现代码
利用顺序栈实现数制转换(以十进制转换为二进制为例)
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 1024
/*定义顺序栈*/
typedef int elemtype;
typedef struct SequenStack
{
elemtype data[MAXSIZE];
int top;
}SequenStack;
/*判(顺序栈)栈空*/
SequenStack * Init_SequenStack()
{
SequenStack * S;
S = (SequenStack *)malloc(sizeof(SequenStack));
if (S == NULL)
{
return S;
}
S->top = -1;
return S;
}
/* 判空栈(顺序栈)*/
int SequenStack_Empty(SequenStack * S)
{
if (S->top == -1)
{
return 1;
}
else
{
return 0;
}
}
/* 入栈(顺序栈) */
int Push_SequenStack(SequenStack * S, elemtype x)
{
if (S->top >= MAXSIZE-1)
{
return 0;
}
S->top++;
S->data[S->top] = x;
return 1;
}
/* 出栈(顺序栈) */
int Pop_SequenStack(SequenStack * S, elemtype * x)
{
if (S->top == -1)
{
return 0;
}
else
{
S->top--;
*x = S->data[S->top+1];
return 1;
}
}
/* 进制转换算法 */
void SequenStackConversion(int N)
{
int x;
SequenStack * S = Init_SequenStack();
while (N > 0)
{
Push_SequenStack(S, N % 2);
N = N / 2;
}
while (! SequenStack_Empty(S))
{
Pop_SequenStack(S, &x);
printf("%d", x);
}
}
int main()
{
int N;
printf("Please enter the decimal number you want want to convert:\n");
scanf("%d", &N);
printf("The converted binary number is:\n");
SequenStackConversion(N);
}
实现结果
利用链栈栈实现数制转换(以十进制转换为二进制为例)
#include <stdio.h>
#include <stdlib.h>
/*定义链栈*/
typedef int elemtype;
typedef struct LinkedStackNode
{
elemtype data;
struct LinkedStackNode *next;
}LinkedStackNode, *LinkedStack;
LinkedStack top;
/*链栈的初始化*/
LinkedStack Init_LinkedStack()
{
LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));
if(top != NULL)
{
top->next = NULL;
}
return top;
}
/*判栈空*/
int LinkedStack_Empty(LinkedStack top)
{
if (top->next == NULL)
{
return 1;
}
else
{
return 0;
}
}
/*入栈*/
int Push_LinkedStack(LinkedStack top, elemtype x)
{
LinkedStackNode *node;
node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));
if (node == NULL)
{
return 0;
}
else
{
node->data = x;
node->next = top->next;
top->next = node;
return 1;
}
}
/*出栈*/
int Pop_LinkedStack(LinkedStack top, elemtype * x)
{
LinkedStackNode *node;
if (top->next == NULL)
{
return 0;
}
else
{
node = top->next;
*x = node->data;
top->next = node->next;
free(node);
return 1;
}
}
/*进制转换*/
void ListStackConversion(int N)
{
int x;
LinkedStack S = Init_LinkedStack();
while (N > 0)
{
Push_LinkedStack(S, N % 2);
N = N / 2;
}
while (! LinkedStack_Empty(S))
{
Pop_LinkedStack(S, &x);
printf("%d", x);
}
}
int main()
{
int N;
printf("Please enter the decimal number you want want to convert:\n");
scanf("%d", &N);
printf("The converted binary number is:\n");
ListStackConversion(N);
}
实现结果
把顺序栈和链栈两种功能综合在一起实现数制转换(以十进制转换为十六进制为例)
/* 进制转换 */
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 100 /*定义顺序栈的长度*/
/*定义顺序栈*/
typedef int elemtype;
typedef struct SequenStack
{
elemtype data[MAXSIZE];
int top;
}SequenStack;
/*定义链栈*/
typedef int elemtype;
typedef struct LinkedStackNode
{
elemtype data;
struct LinkedStackNode *next;
}LinkedStackNode, *LinkedStack;
LinkedStack top;
/* 顺序栈初始化 */
SequenStack * Init_SequenStack()
{
SequenStack * S;
S = (SequenStack *)malloc(sizeof(SequenStack));
if (S == NULL)
{
return S;
}
S->top = -1;
return S;
}
/*链栈的初始化*/
LinkedStack Init_LinkedStack()
{
LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));
if(top != NULL)
{
top->next = NULL;
}
return top;
}
/*判栈(顺序栈)空*/
int SequenStack_Empty(SequenStack * S)
{
if (S->top == -1)
{
return 1;
}
else
{
return 0;
}
}
/* 判栈(链栈)空 */
int LinkedStack_Empty(LinkedStack top)
{
if (top->next == NULL)
{
return 1;
}
else
{
return 0;
}
}
/* 入栈(顺序栈)*/
int Push_SequenStack(SequenStack * S, elemtype x)
{
if (S->top >= MAXSIZE-1)
{
return 0;
}
S->top++;
S->data[S->top] = x;
return 1;
}
/* 出栈(顺序栈) */
int Pop_SequenStack(SequenStack * S, elemtype * x)
{
if (S->top == -1)
{
return 0;
}
else
{
S->top--;
*x = S->data[S->top+1];
return 1;
}
}
/* 入栈(链栈) */
int Push_LinkedStack(LinkedStack top, elemtype x)
{
LinkedStackNode *node;
node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));
if (node == NULL)
{
return 0;
}
else
{
node->data = x;
node->next = top->next;
top->next = node;
return 1;
}
}
/* 出栈(链栈) */
int Pop_LinkedStack(LinkedStack top, elemtype * x)
{
LinkedStackNode *node;
if (top->next == NULL)
{
return 0;
}
else
{
node = top->next;
*x = node->data;
top->next = node->next;
free(node);
return 1;
}
}
/* 使用顺序方式进行进制转换的函数 */
void SequenStackConversion(int N)
{
int x;
SequenStack * S = Init_SequenStack();
while (N > 0)
{
Push_SequenStack(S, N % 16);
N = N / 16;
}
while (! SequenStack_Empty(S))
{
Pop_SequenStack(S, &x);
switch (x)
{
case 10:
printf("A");
break;
case 11:
printf("B");
break;
case 12:
printf("C");
break;
case 13:
printf("D");
break;
case 14:
printf("E");
break;
case 15:
printf("F");
break;
default:
printf("%d", x);
break;
}
}
}
/* 使用链栈方式进行进制转换的函数 */
void ListStackConversion(int N)
{
int x;
LinkedStack S = Init_LinkedStack();
while (N > 0)
{
Push_LinkedStack(S, N % 16);
N = N / 16;
}
while (! LinkedStack_Empty(S))
{
Pop_LinkedStack(S, &x);
switch (x)
{
case 10:
printf("A");
break;
case 11:
printf("B");
break;
case 12:
printf("C");
break;
case 13:
printf("D");
break;
case 14:
printf("E");
break;
case 15:
printf("F");
break;
default:
printf("%d", x);
break;
}
}
}
void function()
{
printf("-------------------------------------------\n");
}
/* 主函数调用进制转换函数 */
int main()
{
int N, x;
printf("Please enter the decimal number you want want to convert:\n");
scanf("%d", &N);
function();
printf("Choose using sequential stack or list stack\n");
printf("1:Sequential stack 2:list stack:\n");
function();
scanf("%d", &x);
printf("The converted binary number is:\n");
switch (x)
{
case 1:
SequenStackConversion(N);
break;
case 2:
ListStackConversion(N);
break;
default:
printf("error");
break;
}
return 0;
}
值得注意的是,当十进制转换为十六进制的时候,需要考虑输出现实大于9的十六进制位数,这里我们考虑可以使用switch开关实现。
实现结果
数制转换的算法实现是利用栈的“LIFO”(后进先出)特性的简单例子。当然,也可以用数组实现,那样空间复杂度会降低,但是用栈实现时,其逻辑过程更清楚。