7-20 表達式轉換 (25 分)
歷時三個半小時終於完成。
這道題的難點主要是在處理數字前的正負號上,同時還應該注意數字有小數點並且不是一位數字。
因爲在做題之前同學給我說過這道題,也知道幾個坑,所以做題的過程比較順利。
我的步驟如下:
1、先完成不考慮數字前的正負號的程序。
2、考慮數字前的正負號,完善程序。
通過上面的步驟,做題的過程比較的順利,把難題變成了簡單的的題目。
在第二步的時候比較燒腦,因爲我的想法比較簡單,就是把所有的可能全都列出來,所以要花很多的時間考慮,驗證。
總結
1、考慮問題要全面,在數字前正負號時要儘量列出所有的可能。
2、開始做題時有一個大體的思路就行,不必考慮的很周到。
3、要善於猜測試點。。在考試時測試點不會告訴我們,而是需要自己取探索。
坑
**這個題的一個坑就是,會在有的正數前加正號,但輸出的時候不用輸出正號。**我就一直沒過這個測試點,直到搜到了測試數據。
AC代碼
#include <stdio.h>
#include <stdlib.h>
/**
* 帶有頭結點
*/
typedef struct Node *Stack;
struct Node{
char s;
Stack Next;
};
//操作
Stack CreateStack(); //初始化棧
void Push(Stack p,char str); //入棧
int IsEmpty(Stack p); //判斷是不是爲空
char Pop(Stack p); //出棧
char GetTop(Stack p); //得到棧頂元素
void majoy(Stack p,char *s); //後綴表達式
int main()
{
Stack p = CreateStack();
char S[50] = {0};
scanf("%[^\n]",S);
majoy(p,S); //得到後綴表達式
system("pause");
return 0;
}
//後綴表達式
void majoy(Stack p,char *S)
{
int flag = 0;
char *ptr = S;
while(*ptr)
{
//處理數字
if((*ptr >= '0' && *ptr <= '9') || *ptr == '.')
{
if(flag) printf(" ");
//處理小數點
while((*ptr >= '1' && *ptr <= '9') || *ptr == '.'){
printf("%c",*ptr);
ptr++;
flag = 1;
}
}
/* 可有可無,爲了防止指針錯誤可以用這個
//處理開始的-5
else if((*ptr == '-' || *ptr == '+') && ptr == S)
{
ptr++;
if(*(ptr-1) == '+') printf("");
else printf("-");
while((*ptr >= '1' && *ptr <= '9') || *ptr == '.'){
printf("%c",*ptr);
ptr++;
flag = 1;
}
}*/
//專門處理-5這種情況
else if((*ptr == '-' || *ptr == '+') && (*(ptr-1)>'9' || *(ptr-1)<'0') && *(ptr-1) != ')' && (*(ptr+1)>='1' && *(ptr+1)<='9'))
{
ptr++;
if(flag) printf(" ");
if(*(ptr-1) == '+') printf("");
else printf("-");
while((*ptr >= '1' && *ptr <= '9') || *ptr == '.'){
printf("%c",*ptr);
ptr++;
flag = 1;
}
}
//處理左括號
else if(*ptr == '(')
{
Push(p,*ptr);
ptr++;
}
//處理右括號
else if(*ptr == ')')
{
//將裏面的全部拋出
while(GetTop(p) != '(')
{
printf(" %c",Pop(p));
}
Pop(p);
ptr++;
}
//處理加減號
else if(*ptr == '-' || *ptr == '+')
{
//處理空棧,或遇到左括號
if(IsEmpty(p) || GetTop(p) == '(')
{
Push(p,*ptr);
ptr++;
}
//全部拋出直到空棧或左括號
else
{
while(!IsEmpty(p))
{
if(GetTop(p) == '(') break;
else printf(" %c",Pop(p));
}
Push(p,*ptr);
ptr++;
}
}
//處理乘除號
else if(*ptr == '*' || *ptr == '/')
{
//處理空棧,或遇到左括號
if(IsEmpty(p) || GetTop(p) == '(')
{
Push(p,*ptr);
ptr++;
}
//遇到加減號同上
else if(GetTop(p) == '-' || GetTop(p) == '+')
{
Push(p,*ptr);
ptr++;
}
//處理出棧的情況
else
{
while(!IsEmpty(p) && (GetTop(p) == '*' || GetTop(p) == '/'))
{
if(GetTop(p) == '(') break;
else printf(" %c",Pop(p));
}
Push(p,*ptr);
ptr++;
}
}
}
//最後輸出剩下運算符
while(!IsEmpty(p))
{
printf(" %c",Pop(p));
}
}
//初始化棧
Stack CreateStack()
{
Stack q;
q = (Stack)malloc(sizeof(struct Node));
q->s = '\0';
q->Next = NULL;
return q;
}
//入棧
void Push(Stack p,char str)
{
Stack ptr;
ptr = CreateStack();
ptr->s = str;
ptr->Next = p->Next; //注意指向的位置
p->Next = ptr;
}
//出棧
char Pop(Stack p)
{
Stack ptr;
char str;
if(IsEmpty(p)){
printf("棧空\n");
return '\0';
}
ptr = p->Next;
str = ptr->s;
p->Next = ptr->Next;
free(ptr);
return str;
}
//判斷是不是爲空
int IsEmpty(Stack p)
{
return (p->Next == NULL);
}
//得到棧頂元素
char GetTop(Stack p)
{
if(IsEmpty(p)) return '\0';
else return p->Next->s;
}
參考文獻:https://blog.csdn.net/SiKongPop/article/details/77972879#comments.