1. 程式人生 > >用c程式設計 可混合運算的計算器

用c程式設計 可混合運算的計算器

功能 
         有優先順序的運算
八進位制與十六進位制 
十六進位制與八進位制 

一元多項式求和

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10
char OP[]={'+','-','*','/','(',')','='};
typedef char ElemType;
struct node
{
	int coef;    //係數  
	int exp;   //指數  
	struct node * next;//指標域
}chainLink;//建立chainLink的node結點物件
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;
typedef struct
{
    int *base;
    int *top;
    int stackSize;
}SqStack;

void InitStack(sqStack *s)
{
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !s->base )
    {
        exit(0);
    }
	
    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

void initStack(SqStack *s)
{
    s->base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));
    if( !s->base )
    {
        exit(0);
    }
	
    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

void Push(sqStack *s, ElemType e)
{
    if( s->top - s->base >= s->stackSize )
    {
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if( !s->base )
        {
            exit(0);
        }
    }
	
    *(s->top) = e;
    s->top++;
}

void Pop(sqStack *s, ElemType *e)
{
    if( s->top == s->base )
    {
        return;
    }
    *e = *--(s->top);
}

void push(SqStack *s, int e)
{
    if( s->top - s->base >= s->stackSize )
    {
        s->base = (int *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(int));
        if( !s->base )
        {
            exit(0);
        }
    }
	
    *(s->top) = e;
    s->top++;
}

void pop(SqStack *s, int *e)
{
    if( s->top == s->base )
    {
        return;
    }
    *e = *--(s->top);
}

int StackLen(sqStack s)
{
    return (s.top - s.base);
}

int stackLen(SqStack s)
{
    return (s.top - s.base);
}

char  GetTop(sqStack *s)
{
	char e;
	if(s->top == s->base)   
		return -1;
	e = *(s->top-1);
	return e;
}

int  getTop(SqStack *s)
{
	int e;
	if(s->top == s->base)   
		return -1;
	e = *(s->top-1);
	return e;
}
int judge(char theta)
{	
	int i;
	if(theta == '+')
		i=0;
	else if(theta == '-')
		i=1;
	else if(theta == '*')
		i=2;
	else if(theta == '/')
		i=3;
	else if(theta == '(')
		i=4;
	else if(theta == ')')
		i=5;
	else
		i=6;
	return i;
}
int precede(char theta1,char theta2)
{
	int  std_cherry[7][7]=
	{
		
		1, 1,-1,-1,-1, 1, 1,
			1, 1,-1,-1,-1, 1, 1,
			1, 1, 1, 1,-1, 1, 1,
			1, 1, 1, 1,-1, 1, 1,
			-1,-1,-1,-1,-1, 0,-2,
			1, 1, 1, 1,-2, 1, 1,
			-1,-1,-1,-1,-1,-2, 0,
	};
	int i,j;
	i = judge(theta1);
	j = judge(theta2);
	return std_cherry[i][j];
}
int OPerate(int a,char theta,int b)
{
	int result;
	switch(theta)
	{
	case '+':
		result = a+b;
		break;
	case '-':
		result = a-b;
		break;
	case '*':
		result = a*b;
		break;
	case '/':
		result = a/b;
		break;
	}
	return result;
}
int In(char *c,char *OP)
{
	int i,comp = 0;
	for(i = 0; i < 7; i++)
	{
		if( c[0] == OP[i])
			comp = 1;
	}
	return comp;
}

int EvaluateEcpression()
{
	sqStack OPTR;
	SqStack OPND;
	char c[10],theta,x;
	int a,b,put;
	InitStack(&OPTR);	
	Push(&OPTR,'=');
	initStack(&OPND);	
	scanf("%s",c);	
	while(c[0] != '=' || GetTop(&OPTR) != '=')
	{
		if(!In(c,OP))	
		{
			put = atoi(c);
			//	printf("%d\n",put);
			push(&OPND,put);
			scanf("%s",c);
		}
		else 
			switch(precede(GetTop(&OPTR),c[0]))
		{
				case -1:
					Push(&OPTR,c[0]); 
					scanf("%s",c);
					break;
				case 0:
					Pop(&OPTR,&x); 
					scanf("%s",c);
					break;
				case 1: 
					Pop(&OPTR,&theta);
					pop(&OPND,&b); 
					pop(&OPND,&a);
					push(&OPND,OPerate(a,theta,b));
					//				printf("%d\n",OPerate(a,theta,b));
					
					break;
		} 
		
	}
    return getTop(&OPND);	
}


void BtoD()
{
    ElemType c;
    sqStack s;
    int len, i, sum = 0;
	
    InitStack(&s);
	
    printf("請輸入二進位制數,輸入#符號表示結束!\n");
    scanf("%c", &c);
    while( c != '#' )
    {
        Push(&s, c);
        scanf("%c", &c);
    }
	
    getchar();  // 把'\n'從緩衝區去掉
	
    len = StackLen(s);
    printf("棧的當前容量是: %d\n", len);
	
    for( i=0; i < len-1; i++ )
    {
        Pop(&s, &c);
        sum = sum + (c-48) * pow(2, i);
    }
	
    printf("轉化為十進位制數是: %d\n", sum);
	
    return 0;
}


void DtoB()
{
	int  c,d;
    SqStack s;
    int len, i;
	
    InitStack(&s);
	
	printf("請輸入十進位制數: ");
    scanf("%d", &c);
	printf("轉化為二進位制數是: "); 
	while(c > 0)
    {
		//	printf("%d",c%2);
        push(&s, c%2);
		c = c - c%2;
		c = c/2;
    }
	
	len = stackLen(s);
	for(i = 0; i < len; i++)
	{
		pop(&s,&d);
		printf("%d",d);
	}
	printf("\n棧的當前容量是: %d\n", len);
	
    return 0;
}


void OtoH()
{  
	
	int i,j,k,s=0; 
	int a;
	char p[30];  
	int result=0;  
	printf("輸入你想要轉化的八進位制數: \n");
	scanf("%d",&a);
	for(i=1;a!=0;i*=8)  
	{  
		if(a%10>7)  
		{   
			s=1;  
			break;  
		}  
		else  
		{  
			result+=(a%10)*i;  
			a=a/10;  
		}  
	}  
	for(j=0;result!=0;j++)  
	{  
		p[j]=result%16;  
		result=result/16;  
		if(p[j]<10)  
			p[j]+=48;  
		else  
		{  
			switch(p[j])  
			{  
			case 10: p[j]='A';  
				break;  
			case 11: p[j]='B';  
				break;  
			case 12:    p[j]='C';  
				break;  
			case 13:    p[j]='D';  
				break;  
			case 14:    p[j]='E';  
				break;  
			case 15:    p[j]='F';  
				break;  
			}  
		}  
	}  
	if(s==1)  
		printf("您的輸入有誤!請重新輸入\n");  
	else   
	{  
		printf("\n轉換後的數為:");  
		for(k=j-1;k>=0;k--)  
		{  
			printf("%c",p[k]);  
		}  
		printf("\n");  
	}  
}  

void HtoO()
{ 	
	int i,j,k,s=0;  
	char a[10];
	int result=0;  
	int b[30];  
	int p[30]; 
	scanf("%s",&a);
	for(k=0;;k++)  
	{  
		if(a[k]=='\0')  
			break;  
	}  
	
	for(i=0;i<k;i++)  
	{  
		if(a[i]<='9'&&a[i]>='1')  
			b[i]=a[i]-48;  
		else  
		{  
			switch(a[i])  
			{  
			case 'A': b[i]=10;  
				break;  
			case 'B': b[i]=11;  
				break;  
			case 'C':   b[i]=12;  
				break;  
			case 'D':   b[i]=13;  
				break;  
			case 'E':   b[i]=14;  
				break;  
			case 'F':   b[i]=15;  
				break;  
			case 'a': b[i]=10;  
				break;  
			case 'b': b[i]=11;  
				break;  
			case 'c':   b[i]=12;  
				break;  
			case 'd':   b[i]=13;  
				break;  
			case 'e':   b[i]=14;  
				break;  
			case 'f':   b[i]=15;  
				break;  
			default: s=1;  
			}  
		}  
	}  
	for(j=k-1,i=1;j>=0;j--,i*=16)  
	{  
		result+=b[j]*i;  
	}  
	for(j=0;result!=0;j++)  
	{  
		p[j]=result%8;  
		result=result/8;  
	}  
	if(s==1)  
		printf("您的輸入有誤!請重新輸入\n");  
	else   
	{  
		printf("\n轉換後的數為:");  
		for(k=j-1;k>=0;k--)  
		{  
			printf("%d",p[k]);  
		}  
		printf("\n");  
	}  
} 


struct node *create()                    //定義建立多項式函式,並返回連結串列頭指標
{
	struct node *h = NULL, *q, *p;//定義結構體頭指標h,標記指標p和q,p是創造新節點的標記指標,q是連結連結串列的指標;
	int i = 1, N;                             //定義多項式的項數N及標記數i
	printf("請輸入多項式的項數: ");
	scanf("%d",&N);
	p = 0;//指標初始化;
	q = 0;//本地指標初始化;
	for (; i <= N; i++)
	{
		p = (struct node *)malloc(sizeof(chainLink));            //為一個新節點分配空間
		printf("請輸入第 %i 項的係數:\t",i);
		scanf("%d",&(*p).coef);
		printf("請輸入第 %i 項的指數: \t",i);
		scanf("%d",&(*p).exp);
		if (i == 1) { h = p; q = p; }                           //建立頭節點
		else
		{
			q->next = p;
			q = p;
		}
	}
	q->next = NULL;//p,q都成為新連結串列的尾指標;
	p->next = NULL;
	return h;
}
void display(struct node  *h)
{
	struct node *p;                 //定義標記指標,輸出連結串列
	p = h;
	while (p != NULL)
	{
		if (p->coef == 0)
		{
			struct node *d;
			d = h;
			while (d->next != p)
			{
				d = d->next;
			}
			d->next = p->next;
			p = p->next;//刪去係數為0的節點;
		}
		else
		{
			if (p->coef<0)                 //係數為負時應加上括號,讓式子容易看清;
			{
				if (p->exp == 0) printf("%d+",(*p).coef);
				else printf("(%d)*X^%d+",(*p).coef,(*p).exp);
			}
			else
			{
				if (p->exp == 0) printf("%d+",(*p).coef);
				else if (p->exp!=0&&p->exp!=1)
				{
					printf("%d*X^%d+",(*p).coef,(*p).exp);
				}
				else printf("%d*X+",(*p).coef);
			}
			p = p->next;
		}
	}
	printf("\b \b \n");
	
}
struct node *order(struct node *h)     //定義排序函式,並返回整理後的連結串列的頭指標
{
	struct node *p, *q, *t, *h1, *h2;       //定義三個結構體標記指標和兩個頭指標
	h1 = h;              //建立一個新的連結串列,頭指標為h,指向原連結串列的第一個節點,之後將原連結串列中的節點一個一個的插入此連結串列,進行排序
	h2 = h1->next;                      //將原來的連結串列建立成待排序連結串列
	h1->next = NULL;                    //截斷第一個原連結串列中的節點
	while (h2 != NULL)
	{
		q = h1;
		p = q->next;
		t = h2;                  //從待排序連結串列中選出一個節點準備插入到新連結串列中
		h2 = h2->next;           //移動待排序連結串列的頭指標,便於進行下一次挑選
		t->next = NULL;
		if (t->exp>q->exp)            //應插入頭指標之前的情況
		{
			t->next = q;
			h1 = t;
			continue;
		}
		if (p == NULL&&t->exp <= q->exp) q->next = t;     //應插入表尾的情況
		while (p != NULL)
		{
			if (t->exp>p->exp)
			{
				q->next = t;
				t->next = p;
				break;
			}
			else
			{
				q = q->next;
				p = p->next;
			}
		}
		if (p == NULL) q->next = t;
	}
	return h1;                //新連結串列即為按降冪順序排好的連結串列,返回其頭指標
}
struct node *add(struct node *h1, struct node *h2)   //定義加法函式,並返回結果的連結串列的頭指標
{
	struct node *p, *q, *head, *r;          //定義結構體頭指標head和標記指標p,q,r
	p = h1;
	q = h2;
	head = (struct node *)malloc(sizeof(chainLink));    //為結果多項式分配頭指標
	if (p->exp >= q->exp) { head = h1; p = p->next; }
	else
	{
		if (p->exp<q->exp) { head = h2; q = q->next; }
		else { p->coef = p->coef + q->coef; head = p; p = p->next; q = q->next; }
	}
	r = head;
	while (p != NULL&&q != NULL)
	{
		if (p->exp>q->exp) { r->next = p; p = p->next; }
		else
		{
			if (p->exp<q->exp) { r->next = q; q = q->next; }
			else { p->coef = p->coef + q->coef; r->next = p; p = p->next; q = q->next; }
		}
		r = r->next;
	}
	if (p == NULL&&q == NULL) r->next = NULL;
	else
	{
		if (p == NULL) r->next = q;
		if (q == NULL) r->next = p;
	}
	return head;
}


void polynomail()
{
	struct node *h1, *h2, *h3;//定義3個頭指標;
	printf("請輸入第一個多項式:\n");
	h1 = create();//創造第一個線性連結串列;
	printf("\n您輸入的第一個多項式為:\n");
	display(h1);//把多項式顯示出來;
	h1 = order(h1);
	printf("\n降冪排列後的第一個多項式為:\n");
	display(h1);
	printf("\n");
	printf("\n請輸入第二個多項式:\n");
	h2 = create();//創造第二個線性連結串列;
	printf("\n您輸入的第二個多項式為:\n");
	display(h2);//把多項式顯示出來;
	h2 = order(h2);
	printf("\n降冪排列後的第二個多項式為:\n");
	display(h2);
	printf("\n");
	h3 = add(h1, h2);//利用加函式將多項式相加;
	printf("\n第一個多項式和第二個多項式相加後:\n");
	display(h3);
	system("pause");
	return 0;
}

void phead(void)
{
	printf("*******************************************************\n");
	printf("********************Tom's calclater********************\n");
	printf("*******************************************************\n");
	printf("\n***************  請選擇需要的計算操作:*****************\n");
}
void thead(void)
{
	printf("*******************************************************\n");
	printf("請輸入相應的數字,並進行一步計算: ");
}

void main()  
{  
	int i,j,q=0; 
	int tom;
	phead();
	
	do  
	{   
		
		printf("0、退出\n1、進位制轉化\n2、計算器\n3、一元多項式加法\n");  
		thead();
		scanf("%d",&i);  
		switch (i)  
		{  
		case 1:  thead(); 
			printf("\n請要轉化的的進位制:\n0、退出\n1、二進位制到十進位制\n2、十進位制到二進位制\n3、八進位制到十六進位制\n4、十六進位制到八進位制\n");  
			scanf("%d",&j);  
			switch(j)  
			{  
			case 1: printf("\n請輸入您想要轉化的數:");  
				BtoD(); 
				break;  
			case 2: printf("\n請輸入您想要轉化的數:");  
				DtoB(); 
				break;  
			case 3: printf("\n請輸入您想要轉化的數:");  
				OtoH(); 
				break;  
			case 4: printf("\n請輸入您想要轉化的數:");  
				HtoO();
				break;  
			case 0:   
				
				printf("謝謝使用!!");  
				
			}  
			break;  
			case 2: printf("\n請輸入你想要計算的表示式(在以空格隔開每個輸入!):\n");
				tom = EvaluateEcpression();
				printf("表示式的計算結界是 %d\n",tom);
				break;
			case 3: 
				polynomail();
				break;
			case 0: printf("\n謝謝使用!\n");  
				break;
				
		}  
	}while(q==1);  
}