计算机可以用二、十、八以及十六四种数制表示数据,利用栈的特性设计程序自动实现数制之间的转化。需要注意的是,在程序中要能实现带小数部分的数值的转化。
思想:
本实验要求利用栈来实现数值转换,关于数值转换,我们知道手工运算时,整数部分的结果是先进后出,所以采用栈的特性。小数部分是先进先出,所以采用队的特性。
由于要分开小数部分和整数部分。故在输入数时采用字符输入,以 ‘.’ 为分隔符,前面的给到整数,后面的给到小数,然后分别执行就可以了。
1.定义栈(实现整数部分的进制转换)
2.定义队列(实现小数部分的转换)
3.初始化栈,输入栈,输出栈,实现进制转换
4.初始化队,输入队,输出队,实现进制转化
5.主函数实现
6.结果
源代码附上:
#include <stdio.h>
#include <malloc.h>
#include<process.h>
#include <math.h>
#include<string.h>
#define OVERFLOW -2
#define STACK_INIT_SIZE 20//存储初始化分配量
#define STACKINCREMENT 10//存储空间分配铮亮
#define size 10 //小数部分大小
//整数部分转化
typedef int SElemType;
//顺序表示及实现
typedef struct
{
SElemType * base;
SElemType * top;
intStackSize;
}SqStack;
//初始化栈
void InitStack(SqStack *s){
s->base=(SElemType*)malloc (STACK_INIT_SIZE * sizeof(SElemType));
if(!s->base)exit(OVERFLOW);
s->top=s->base;
s->StackSize=STACK_INIT_SIZE;
}
//输入栈
voidPush(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)exit(OVERFLOW);
s->top=s->base+s->StackSize;
s->StackSize+=STACKINCREMENT;
}
*s->top++ =e;
}
//输出栈
intPop(SqStack *s,SElemType *e) {
if (s->top==s->base)
return 0;
s->top=s->top-1;
*e = *s->top;
}
//判空栈
intStackEmpty(SqStack s) {
if (s.top ==s.base) { return 1; }
else { return 0;}
}
//实现10进制的任意进制转化
voidConversion(int N,int m) {
SElemType e;
SqStacks;
InitStack(&s);
while(N){
Push(&s,N%m);N= N/m;
}
printf("换后的%d进制数为:",m);
while(StackEmpty(s)!=1) {
Pop(&s,&e);
if(e>=10) {printf("%c",e-10+'A'); }
else printf("%d",e);
//printf("\n");
}
}
//小数部分转化
typedfstruct
{
char data[10]; //读取转制后的小数部分
int front,rear; //队首尾指针
}Queue; //循环队列
//初始化队列
void init_Queue(Queue* q)
{
q->front=q->rear=0;
}
//入队
int push_Queue(Queue *q,int x)
{
if((q->rear+1)%size==q->front) //判断队满
{
printf("队列满!不允许入队\n");
return 0;
}
else
{
q->rear=(q->rear+1) % size;
q->data[q->rear]=x;
return 1;
}
}
//出队
int pop_Queue(Queue *q,int *x)
{
if(q->rear==q->front)
{
printf("队空!");
return 0;
}
else
{
q->front=(q->front+1)%size;
*x=q->data[q->front]; //读取队头元素
return 1;
}
}
//实现小数部分进制转换
voidConversionxiao(double N,int m) {
Queueq,*cq=&q;
init_Queue(cq);
// 依次求得小数部分的每一位并入队
int zz;
int innum;
{
innum=(((int)(N*m)))%10; //取出小数点前的部分
N=N*m-innum; //得到减去小数点前段的部分继续与aim相乘
push_Queue(cq,innum);
}
//出队列
printf(".") ;
if(pop_Queue(cq,&zz)){
for(inti=(cq->front)%size;i!=(cq->rear+1)%size;i=(i+1)%size)
printf("%d",cq->data[i]);
}
}
int main() {
char a[20];
printf("请输入一个十进制浮点数: "); //以字符串形式输入一个浮点数
gets(a);
int m;
printf("请输入一个几进制数m的值:");
//读取小数点位置
int i;
int pos;//小数点位置
for(i=0;i<strlen(a);++i)
{
if(a[i]=='.')
pos=i;
break;
}
}
int bnum;//整数值
for(i=0;i<pos;i++)
{
bnum=bnum*10+a[i]-'0';
}
scanf("%d",&m);
Conversion(bnum,m);
//求小数部分
int c=1;
intanum=a[pos+1]-'0';
for(i=pos+2;i<strlen(a);i++)
{
anum=anum*10+(a[i]-'0');
c++;
}
double small=((double)anum)/pow(10,c);
Conversionxiao(small,m);
return 0;
}