十、数制转换
void Conversion(int N) /*对于任意的一个非负十进制数N,打印出与其等值的二进制数*/
{
LinkStack S; int x; /*S为顺序栈或链栈*/
InitStack(&S);
while(N>0)
{ x=N%2; Push(&S, x); N=N/2; }
while(!IsEmpty(S))
{ Pop(&S,&x); printf(“%d”,x); }
}
十一、括号匹配问题
思想:在检验算法中设置一个栈
(1)若读入的是左括号,则直接入栈,等待相匹配的同类右括号。
(2)若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。
(3)如果输入序列已读尽,而栈中仍有等待匹配的左括号;或者读入了一个右括号,而栈中已无等待匹配的左括号,均属不合法的情况。
(4)当输入序列和栈同时变为空时,说明所有括号完全匹配。
void BracketMatch(char *str)
{
StackLink S; int i; char ch;
InitStack(&S);
for(i=0; str[i]!='\0'; i++)
{
switch ( str[i] )
{
case '(':
case '[':
case '{': Push( &S, str[i] ) ; break;
case ')':
case ']':
case '}':
if( IsEmpty(S) )
{ printf("\n右括号多余!"); return;}
else
{
GetTop (&S,&ch);
if(Match(ch,str[i])) Pop(&S,&ch);
else { printf("\n对应的左右括号不同类!");
return;
}
}
}/*switch*/
}/*for*/
if(IsEmpty(S))
printf("\n括号匹配!");
else
printf("\n左括号多余!");
}
int Match(char ch1,char ch2)
{
switch(ch1)
{
case '(': if(ch2==')') return 1;
case '[': if(ch2==']') return 1;
case '{': if(ch2=='}') return 1;
default: return 0;
}
return 0;
}
十二、表达式求值
(1) 无括号算术表达式求值
表达式运算及运算符优先级
3+4*5 # ± */ **
① 0 1 2 3
②
(2) 算术表达式处理规则
规定优先级表;
设置两个栈:OVS(运算数栈)和OPTR(运算符栈);
自左向右扫描,遇操作符则与OPTR栈顶优先级比较:当前操作符>OPTR栈顶则进OPTR栈;
当前操作符≤ OPTR栈顶,OVS栈顶、次顶和OPTR栈顶退栈,形成运算T(i), T(i)进OVS栈。
(3) 带括号算术表达式
实现算符优先算法时需要使用两个工作栈:一个称作运算符栈operator;另一个称作操作数栈operand。
算法的基本过程如下:
A.初始化操作数栈operand和运算符栈operator,并将表达式起始符“#”压入运算符栈;
B.读入表达式中的每个字符,若是操作数则直接进入操作数栈operand,若是运算符,则与运算符栈operator的栈顶运算符进行优先权比较,并做如下处理:
若栈顶运算符的优先级低于刚读入的运算符,则让刚读入的运算符进operator栈;
若栈顶运算符的优先级高于刚读入的运算符,则将栈顶运算符退栈,送入θ,同时将操作数栈operand退栈两次,得到两个操作数a、b,对a、b进行θ运算后,将运算结果作为中间结果推入operand栈;
若栈顶运算符的优先级与刚读入的运算符的优先级相同,说明左右括号相遇,只需将栈顶运算符(左括号)退栈即可。当operator栈的栈顶元素和当前读入的字符均为“#”时,说明表达式起始符“#”与表达式结束符“#”相遇,整个表达式求值完毕。
十三、打印杨辉三角形
void YangHuiTriangle(int N)
{
int n, i, x, temp;
SeqQueue Q;
InitQueue(&Q);
EnterQueue(&Q,1);//第一行元素入队
for(n=2;n<=N;n++)
{
EnterQueue(&Q, 1);//入队列
for(i=1;i<=n-2;i++)
{
DelQueue(&Q, &temp);//出队列的数据赋给temp
printf("%d ", temp);
GetHead(&Q, &x);
temp=temp+x;
EnterQueue(&Q, temp);
}
DelQueue(&Q, &x);//出队列
printf("%d ", x);
EnterQueue(&Q, 1);
printf("\n");
}
while (!IsEmpty(&Q))
{
DelQueue(&Q, &x);
printf("%d ", x);
}
}
十四、键盘输入循环缓冲区
void main()
{//模拟键盘输入循环缓冲区
char ch1,ch2;
SeqQueue Q;
int f;
InitQueue(&Q);
for(;;)
{
for(;;) //第1个进程
{
printf("A");
if(kbhit())
{
ch1=getch();
if(ch1==';'||ch1==',') break; //第1个进程正常中断
f=EnterQueue(&Q,ch1);
if(f==FALSE) //循环队列满时强制中断第1个进程
{
printf("循环队列已满!\n");
break;
}
}//end if
}//end for
while(!IsEmpty(&Q)) //第2个进程
{
DelQueue(&Q,&ch2);
putchar(ch2); //显示输入缓冲区的内容
}
if(ch1==';')break;
}//end for
}
十五、挂号看病
void SeeDoctor()
{
LinkQueue Q;
int flag;
InitQueue(&Q);
flag=1;
while(flag)
{
printf("\n请输入命令:");
ch=getch();
switch(ch)
{
case 'a':printf("\n病历号:");
scanf("%d",&n);
EnterQueue(&Q,n);
break;
case 'n':if(!IsEmpty(&Q)){
DeleteQueue(&Q,&n);
printf("\n病历号为%d的病人就诊",n);
}
else
printf("\n无病人等候就诊");
break;
case 'q':printf("\n今天停止挂号,下列病人依次就诊:\n");
while(!IsEmpty(&Q))
{
DeleteQueue(&Q,&n);
printf("%d\n",n);
}
flag=0;
break;
default:printf("\n非法命令!");
}
}
}
十六、求两个集合的差
1.已知:以单链表表示集合,假设集合A用单链表LA表示,集合B用单链表LB表示,设计算法求两个集合的差,即A-B。
2.算法思想:由集合运算的规则可知,集合的差A-B中包含所有属于集合A而不属于集合B的元素。具体做法是,对于集合A中的每个元素e,在集合B的链表LB中进行查找,若存在与e相同的元素,则从LA中将其删除。
3.算法实现
void Difference (LinkList LA,LinkList LB) /*此算法求两个集合的差集*/
{
Node *pre;*p, *r;
pre=LA; p=LA->next; /*p向表中的某一结点,pre始终指向p的前驱*/
while(p!=NULL)
{ q=LB->next; /*扫描LB中的结点,寻找与LA中*P结点相同的结点*/
while (q!=NULL && q->data!=p->data) q=q->next;
if (q!=NULL)
{ r=p; pre->next=p->next; p=p->next; free(r); }
else
{ pre=p; p=p->next; }
}
}
十七、双向链表应用举例
1.已知:设一个循环双链表L=(a,b,c,d)编写一个算法将链表转换为L=(b,a,c,d)。
2.算法思想:实际上是交换表中前两个元素的次序。
3.算法实现:
void swap(DLinkList L)
{ DNode *p,*q,*h;
h=L->next; /* h指向表中的第一个结点,即a */
p=h->next; /* p指向b结点 */
q=h->prior; /* 保存a结点的前驱 */
h->next=p->next;
p->next->prior=h; /*变换指针指向*/
p->prior=q; p->next=h;
L->next=p;
}
十八、一元多项式的表示及相加
一个一元多项式Pn(x)可按升幂的形式写成:Pn(x)=p0+p1x+p2x2+p3x3+ … +pnxn
在计算机内,可以用一个线性表P来表示: P=(p0,p1,p2, …,pn)
用单链表存储多项式的结点结构如下:
typedef struct Polynode
{
int coef; /* 系数 */
int exp; /* 指数 */
Polynode *next;
} Polynode , * Polylist;
建立多项式链表
算法描述:输入多项式的系数和指数,用尾插法建立一元多项式的链表。
Polylist polycreate()
{ Polynode *head, *rear, *s; int c,e;
rear=head =(Polynode *)malloc(sizeof(Polynode));
/*建立多项式的头结点,rear 始终指向单链表的尾*/
scanf(“%d,%d”,&c,&e); /*键入多项式的系数和指数项*/
while(c!=0) /*若c=0,则代表多项式的输入结束*/
{ s=(Polynode*)malloc(sizeof(Polynode)); /*申请新的结点*/
s->coef=c ; s->exp=e ;rear->next=s ; /*在当前表尾做插入*/
rear=s; scanf(“%d,%d”,&c,&e); /*按照指数从小到大输入*/
}
rear->next=NULL; /*将表的最后一个结点的next置NULL,以示表结束*/
return(head);
}
十九、两个多项式相加
运算规则:两个多项式中所有指数相同的项的对应系数相加,若和不为零,则构成“和多项式”中的一项;所有指数不相同的项均复制到“和多项式”中。
若pa->exp < pb->exp,则结点pa所指的结点应 是“和多项式”的一项,令指针pa后移;
若pa->exp > pb->exp,则结点pb所指的结点应是“和多项式”中的一项,将结点pb插入在结点pa之前,且令指针pb在原来的链表上后移;
若pa->exp = pb->exp,则将两个结点中的系数相加,当和不为零时修改结点pa的系数域,释放pb结点;若和为零,则和多项式中无此项,释放pa和pb结点。
void PolyAdd(Ploylist La, Ploylist Lb)
{
Ploynode *pa , *pb ,*tail,*temp ; float x ;
pa=La->next ; pb=Lb->next ; tail=La;
while ( pa!=NULL && pb!=NULL )
{ if (pa->exp < pb->exp)
{ tail->next=pa ; tail=pa ; pa=pa->next ; }
/* 将pa所指的结点合并,pa指向下一个结点 */
else if (pa->exp > pb->exp)
{ tail->next=pb ; tail=pb ; pb=pb->next ; }
/* 将pb所指的结点合并,pb指向下一个结点 */
else
{ x=pa->coef+pb->coef ;
if (abs(x)<=1.0e-6) /* 如果系数和为0,删除两个结点 */
{
temp=pa ; pa=pa->next ; free(temp) ;
temp=pb ; pb=pb->next ; free(temp) ;
}
else /* 如果系数和不为0,修改其中一个结点的系数域,删除另一个结点 */
{
tail->next=pa ; pa->coef=x ;
tail=pa ; pa=pa->next ;
temp=pb ; pb=pb->next ; free(pb) ;
}
}
} /* end of while */
if (pa==NULL) tail->next=pb ;
else tail->next=pa ;
}
二十、单链表的就地逆置
void Reverse (LinkList L)
{
Node *p,*q; /* p为工作指针,r为p的后继以防断链 */
p=L->next; /* 从第一个元素结点开始 */
L->next=NULL; /* 先将头结点L的next域置为NULL */
while(p!=NULL) /* 依次将元素结点摘下 */
{
q=p->next; /* 暂存p的后继 */
p->next=L->next; /* 将p结点插入到头结点之后 */
L->next=p;
p=q;
}
}
二十一、从顺序表L中删除所有值为x的元素
void delx(SeqList *L, int x) //删除所有值为x的元素
{
int i = 0; int j = 0;
while (i <= L->last)
{
if (L->elem[ i ] != x)
{ L->elem[ j ] = L->elem[ i ]; i++; j++; }
else
i++;
}
L->last = j - 1;
printf("creat last=%d\n", L->last);
}
二十二、汉诺塔
void hanoi(int n,char x,char y,char z)
{
if(n==1)
move(x,1,z);//将编号为1的圆盘从x移到z
else
{
hanoi(n-1,x,z,y);//将x上编号为1至n-1的圆盘移到y,z作辅助塔
move(x,n,z);//将编号为n的圆盘从x移动到z
hanoi(n-1,y,x,z);//将y上编号为1至n-1的圆盘移到z,x作辅助塔
}
}
二十三、八皇后问题
二十四、停车场管理系统
二十五、迷宫
这道题的代码暂时不完整
struct
{
int i;//当前方块的行号
int j;//当前方块的列号
int di;//下一可走的方块
}Stack[MaxSize];//定义栈
int top=-1;//初始化栈
void mgpath()//路径为(1,1)->(M-2,N-2)
{
int i,j,di,find,k;
top++;//初始方块进栈
Stack[top].i=1;
Stack[top].j=1;
Stack[top].di=-1;
mg[1][1]=-1;
while(top>-1)//栈不空时循环
{
i=Stack[top].i;
j=Stack[top].j;
di=Stack[top].di;
if(i=M-2&&j=N-2)//找到了出口,输出路径
{
printf("迷宫路径如下:")
for(k=0;k<=top;k++)
{
printf("\t(%d%d)",Stack[k].i,Stack[k].j);
if((k+1)%5==0)
printf("\n");
return;
}
find=0;
while(di<4&&find==0)//找下一个可走方块
{
d++;
switch(di)
{
//往上走
case 0:
i=Stack[top].i-1;
j=Stack[top].j;
break;
//往右走
case 1:
i=Stack[top].i;
j=Stack[top].j+1;
break;
//往下走
case 2:
i=Stack[top].i+1;
j=Stack[top].j;
break;
//往左走
case 3:
i=Stack[top].i;
j=Stack[top].j-1;
break;
}
if(mg[i][j]==0)
find=1;
}
if(find==1)//找到了下一个可走方块
{
Stack[top].di=di;//修改原栈顶元素di值
top++;//下一个可走方块进栈
Stack[top].i=i;
Stack[top].j=j;
Stack[top].di=-1;
mg[i][j]=-1;//避免重复走到该方块
}
else//没有路径可走,则退栈
{
mg[Stack[top].i][Stack[top].j]=0;//让该位置变为其他路径可走方块
top--;
}
}
printf("没有可走路径\n");
}
二十六、使用顺序栈实现十进制整数到r进制(2<=r<=8)的转换。
#include<stdlib.h>
#include<stdio.h>
#include<stddef.h>
/*定义栈结构*/
typedef struct
{
char data[50];
int top;
}SeqStack,*PSeqStack;
/*初始化栈,构造一个空栈,如果成功,则返回栈的地址*/
PSeqStack Init_SeqStack()
{
PSeqStack s;
s=(PSeqStack)malloc(sizeof(SeqStack));
if(s)
{
s->top=-1;
}
return s;
}
/* 判断栈是否为空,如果为空,则返回1,否则返回0*/
int Empty_SeqStack(PSeqStack s)
{
if(s->top==-1)
{
return 1;
}
else
{
return 0;
}
}
/*入栈操作,栈不满时,入栈一个元素,成功返回1,失败返回0*/
int Push_SeqStack(PSeqStack s,char x)
{
if(s->top==49)
{
return 0;
}
else
{
s->top=s->top+1;
s->data[s->top]=x;
return 1;
}
}
/*出栈操作,栈不空时,出栈一个元素,用参数*x保存,成功返回1,失败返回0*/
int Pop_SeqStack(PSeqStack s,char *x)
{
if(Empty_SeqStack(s))
{
return 0;
}
else
{
*x=s->data[s->top];
s->top=s->top-1;
return 1;
}
}
/*取栈顶元素操作,栈不空时,获取栈顶元素,成功返回1,失败返回0*/
int GetTop_SeqStack(PSeqStack s,char *x)
{
if(Empty_SeqStack(s))
{
return 0;
}
else
{
*x=s->data[s->top];
return 1;
}
}
/*销毁栈*/
void Destroy_SeqStack(PSeqStack *s)
{
if(*s)
{
free(*s);
}
*s=NULL;
}
/*十进制转换成r进制(2,8,16)*/
int Conversion(int num,int r)
{
PSeqStack s;
char x;
if(!r)
{
printf("基数不能为0");
return -1;
}
s=Init_SeqStack();
if(!s)
{
printf("初始化栈空间失败");
return -1;
}
while(num)
{
if(num%r>9)
{
Push_SeqStack(s,num%r+'A'-10); /*余数大于9,则进栈ABCDEF*/
}
else
{
Push_SeqStack(s,num%r+'0'); /*余数小于10,则进栈数字字符*/
num=num/r;
}
}
while(!Empty_SeqStack(s))
{
Pop_SeqStack(s,&x);
printf("%c",x);
}
return 0;
}
int main()
{
int r, num;
printf("请输入一个十进制整数:");
scanf("%d",&num);
printf("请输入要转换成的进制:");
scanf("%d",&r);
Conversion(num,r);
return 0;
}
二十七、用顺序栈判断是否为回文数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 80
//定义顺序栈结构
typedef struct
{
char elem[MAX];
int top;
}STACK;
void Init_Stack(STACK *pS)
{
pS->top = -1; //top为栈顶元素在数组elem中的下标,由于开始没有元素,则为-1
}
int Push(STACK *pS, char e)
{
if(pS->top >= MAX-1)
return 0;
pS->top++; //改变栈顶位置
pS->elem[pS->top] = e;
return 1;
}
int Pop(STACK *pS, char *pe)
{
if(pS->top == -1)
return 0;
*pe = pS->elem[pS->top];
pS->top--;
return 1;
}
int main()
{
char str[80], c1,c2,*p;
STACK S;
int len,i=1;
int len1;
int sign=0;
Init_Stack(&S);
printf("请输入一串字符串:");
gets(str);
p = str;
len=strlen(str);
len1=strlen(str);
if(len%2==0)len=len/2;
else
{
sign=1;
len=len/2;
}
//将'&'前面的字符依次入栈
while(i<=len && *p != '\0')
{
if(!Push(&S, *p))
{
printf("栈空间溢出!");
exit(0);
}
p++;
i++;
}
if(sign)
{
p++;
}
//每取一个字符就和从栈中弹出的一个字符比较,如果相等
//则继续取下一个。
while(i<=len1 && *p != '\0')
{
c1 = *p;
if(!Pop(&S, &c2))
{
printf("栈已为空,不是回文,'&'前面的字符少!\n");
exit(0);
}
if( c1 != c2)
{
printf("对应字符不相等,不是回文!\n");
exit(0);
}
p++;
}
if(Pop(&S, &c2))
{
printf("'&'前的字符比后面多,栈内还有字符,不是回文!\n");
exit(0);
}
else
printf("是回文!\n");
return 0;
}
二十八、使用链栈实现含括号的算术表达式的求值(注意:运算数可为十进制的无符号整数或实数)。
该代码参考该博主的原创文章
https://blog.csdn.net/qq_43312665/article/details/103791494
#include<stdio.h>
#include<stdlib.h>
#define Stack_Init_Size 100 //栈容量
#define StackIncrement 10 //栈增量
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char SElemType;
typedef int Status;
typedef struct SNode {
SElemType data;
struct SNode* next;
}SNode, * LinkStack;
LinkStack InitStack()//注意这个初始化方式!!!!!!
{
LinkStack s = (SNode*)malloc(sizeof(SNode));
if (!s)
exit(OVERFLOW);
s->next = NULL;
return s;
}
void Push(LinkStack s, SElemType e)
{
LinkStack p = (SNode*)malloc(sizeof(SNode));
if (p == NULL)
exit(OVERFLOW);
p->data = e;
p->next = NULL;
p->next = s->next;
s->next = p;//与单链表的头插法相似
}
SElemType Pop(LinkStack s)
{
LinkStack q;
q = s->next;
SElemType e = q->data;
s->next = q->next;
free(q);//删除单链表的第一个元素
return e;
}
void DestroyStack(LinkStack s)
{
free(s);
}
void ClearStack(LinkStack s)
{
s->next = NULL;
}
Status StackEmpty(LinkStack s)
{
if (s->next == NULL)
return TRUE;
else
{
return FALSE;
}
}
int StackLength(LinkStack s)
{
int i = 0;
SNode* p = s->next;
while (p != NULL)
{
i++;
p = p->next;
}
return i;
}
SElemType GetTop(LinkStack l)
{
return l->next->data;
}
void StackTravers(LinkStack s)
{
SNode* p = s->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int In(char e)//判断读入字符是否为运算符
{
if (e == '+' || e == '-' || e == '*' || e == '/' || e == '(' || e == ')' || e == '#')
return 1;//是
else
return 0; //不是
}
char Precede(char a, char b)//比较运算符的优先级
{
char f;
if (a == '+' || a == '-')
{
if (b == '+' || b == '-' || b == ')' || b == '#')
f = '>';
else if (b == '*' || b == '/' || b == '(')
f = '<';
}
else if (a == '*' || a == '/')
{
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
f = '>';
else if (b == '(')
f = '<';
}
else if (a == '(')
{
if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
f = '<';
else if (b == ')')
f = '=';
}
else if (a == ')')
{
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
f = '>';
}
else if (a == '#')
{
if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
f = '<';
else if (b == '#')
f = '=';
}
return f;
}
char Operate(char a, char theta, char b)//运算
{
char c;
a = a - '0';
b = b - '0';
if (theta == '+')
c = a + b + '0';
else if (theta == '-')
c = a - b + '0';
else if (theta == '*')
c = a * b + '0';
else if (theta == '/')
c = a / b + '0';
return c;
}
int EvaluateExpression()
{
LinkStack OPTR=InitStack();//寄存运算符
Push(OPTR, '#');
LinkStack OPND = InitStack();//寄存操作数和运算结果
char ch, a, b, theta,x;
ch = getchar();
while (ch != '#' || GetTop(OPTR) != '#')
{
if (!In(ch))//如果不是运算符
{
Push(OPND, ch);
ch = getchar();
}
else//如果是运算符
{
switch (Precede(GetTop(OPTR),ch))//比较运算符的优先级
{
case '<':
Push(OPTR, ch);//刚输入的运算符优先级更高,则运算符入栈
ch = getchar();
break;
case '>': //刚输入的运算符优先级更低,则进行一次运算
theta = Pop(OPTR);//原来栈里的运算符出栈
b = Pop(OPND);
a = Pop(OPND);//取出两个运算数
Push(OPND, Operate(a, theta, b));
break;
case '=': //输入运算符的优先级相等
x = Pop(OPTR);
ch = getchar();
break;
}
}
}
return GetTop(OPND) - '0';
}
int main()
{
printf("请输入算数表达式,以#结束\n");
printf("例如\t 1*(2-1)# \t\n");
printf("运行结果是:%d\n", EvaluateExpression());
return 0;
}
二十九、使用链栈实现将含括号的中缀算术表达式转换成后缀算术表达式。(注意:运算数均为个位数)
后缀表达式(逆波兰表达式)规则:
从左到右遍历表达式的每个数字和符号,遇到是数字就入栈,遇到是符号就将处于栈顶的两个数字出栈进行运算,运算结果进栈,直到最后结果。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char Data;
struct Node *Next;
}LinkStack;
LinkStack *Input;
LinkStack *CreateStack ()
{
LinkStack *S;
S=malloc(sizeof(struct Node));
S->Next=NULL;
return S;
}
int IsEmpty (LinkStack *S)
{
return S->Next==NULL;
printf("NULL");
}
void Push (char item ,LinkStack *S)
{
struct Node *TmpCell;
TmpCell=malloc(sizeof(struct Node));
TmpCell->Data=item;
TmpCell->Next=S->Next;
S->Next=TmpCell;
}
char Pop (LinkStack *S)
{
struct Node *FirstCell;
char TopElem;
if(IsEmpty(S))
{
printf("Stack is Empty!");
return NULL;
}
else
{
FirstCell=S->Next;
S->Next=FirstCell->Next;
TopElem=FirstCell->Data;
free(FirstCell);
return TopElem;
}
}
char Precede(char dest,char input)
{
char back;
switch(input)
{
case '+':
case '-': if(dest=='*'||dest=='/')
back='<';
else if(dest=='+'||dest=='-') /*!!!注意考虑结合性 !!! */
back='<' ;
else
back='>';
break;
case '*':
case '/': if(dest=='+'||dest=='-')
back='>';
else if(dest=='*'||dest=='/') /*!!!注意考虑结合性 !!! */
back='=';
else
back='<';
break;
default : printf(" ERROR ");
break;
}
return back;
}
void calculate(char input[])
{
int i=0;
char TopElem,PreTopElem,PrecedeResult;
LinkStack *FirstItem;
for(i=0;input[i]!='\0';i++)
{
if (input[i]>='0'&&input[i]<='9'||input[i]=='.'||input[i]>='a'&&input[i]<='z') //输出数字部分
printf("%c",input[i]);
else if(input[i]=='(') //将左括号压栈
{
Push (input[i] ,Input);
}
else if(input[i]==')') //遇到右括号,将栈内元素弹出打印直到遇到左括号 (左括号不打印)
{
TopElem = Pop (Input);
while((TopElem!='(')&&(!IsEmpty(Input))) //一定要防止进入死循环
{
printf(" %c",TopElem);
TopElem = Pop (Input);
//printf(" #%c#",TopElem);
}
}
else if(input[i]=='+'||input[i]=='-'||input[i]=='*'||input[i]=='/')
{
printf(" ");
if (IsEmpty (Input)) //栈空则进栈
{
Push (input[i] ,Input);
}
else
{
FirstItem=Input->Next;
if(FirstItem->Data!='(') //栈顶元素非左括号
{
PrecedeResult=Precede(FirstItem->Data,input[i]); //和栈顶元素比较
//printf("%c%c",PreTopElem,PrecedeResult);
if(/*PreTopElem=='('&&*/PrecedeResult=='=') //结合性处理部分
{
TopElem = Pop (Input);
printf("%c ",TopElem);
Push (input[i] ,Input);
}
else if(PrecedeResult=='>') //元素优先级大于栈顶元素优先级则进栈
{
Push (input[i] ,Input);
}
else //小于等于则输出Top元素,直到大于则进栈
{
while(!IsEmpty (Input))
{
TopElem = Pop (Input);
printf("%c ",TopElem);
if(!IsEmpty (Input))
{
FirstItem=Input->Next;
PrecedeResult=Precede(FirstItem->Data,input[i]);
//printf("%c",PrecedeResult);
}
if(IsEmpty (Input))
{
Push (input[i] ,Input);
break; // !!!为空进栈则陷入死循环 !!!
}
else if(PrecedeResult=='>')
{
//printf(":::>_<:::");
Push (input[i] ,Input);
break;
}
}
}
}
else if(FirstItem->Data=='(') //栈顶元素是左括号则元素进栈
Push (input[i] ,Input);
}
}
}
while(!IsEmpty (Input))
{
TopElem = Pop (Input);
printf(" %c",TopElem);
}
}
int main()
{
char input[100];
Input=CreateStack ();
printf("请输入中缀算术表达式:\n");
gets(input);
printf("转换后的后缀算术表达式为;\n");
calculate(input);
printf("\n\n");
return 0;
}
三十、使用队列模拟cpu的时间片轮转调度算法
#include<stdio.h>
#include<stdlib.h>
#define MAX 10 //最大进程数
int Time; //时间片
int process_amount; //进程数量
int current_number = 0; //当前执行的“号码牌”
int index = 0; //就绪队列要发的“号码牌”,初始值为0
struct PCB
{
char name[10]; //进程名字
int arrival_time; //到达时间
int service_time; //服务时间
int completion_time; //完成时刻
int sign_completion; //标志是否完成调用,0表示没完成,1表示完成
int remaining_time; //剩余服务时间
int number; //进程在就绪队列里的“号码牌”
}process[MAX];
void input() //初始化进程的信息
{
int i;
printf("请输入时间片:\n");
scanf("%d",&Time);
printf("请输入进程名称、到达时间、服务时间:\n");
for(i = 0; i < process_amount; i ++)
{
printf("%d号进程:\n",i+1);
scanf("%s%d%d",process[i].name,&process[i].arrival_time,&process[i].service_time);
printf("\n");
process[i].remaining_time = process[i].service_time;
process[i].sign_completion = 0;
process[i].number = 0; //“号码牌”初始为0
}
}
void BubbleSort() //冒泡排序算法对进程抵达时间先后排序
{
int i,j,n = process_amount;
for(i = 0; i < n - 1; i++)
for(j = 0; j < n - 1 - i; j++)
{
if(process[j].arrival_time > process[j+1].arrival_time)
{
process[n] = process[j+1];
process[j+1] = process[j];
process[j] = process[n];
}
}
}
void RunProcess() //时间片轮转调用过程
{
int time = process[0].arrival_time; //给当前时间赋初值
int sum = 0; //记录完成的进程数
int i,j;
while(sum < process_amount)
{
for(i = 0; i < process_amount; i++)
if(current_number == process[i].number && process[i].sign_completion == 0)
{
if(process[i].remaining_time <= Time) //剩余服务时间少于等于一个时间片
{
time = time + process[i].remaining_time;
process[i].sign_completion = 1;
process[i].completion_time = time;
process[i].remaining_time = 0;
printf("%s ",process[i].name);
sum++;
current_number++;
for(j = i + 1; j < process_amount; j++) //检测后面有没有新进程到达
if(process[j].arrival_time <= time && process[j].number == 0)
{
index++;
process[j].number = index;
}
}
else if(process[i].remaining_time > Time)//剩余服务时间大于一个时间片
{
time = time + Time;
process[i].remaining_time -= Time;
printf("%s ",process[i].name);
current_number++;
for(j = i + 1; j < process_amount; j++) //检测后面有没有新进程到达
if(process[j].arrival_time <= time && process[j].number == 0)
{
index++;
process[j].number = index;
}
index++;
process[i].number = index;
}
}
if(index < current_number && sum < process_amount) // 还有没执行的进程,且没进入就绪队列
{
for(i = 0; i <= process_amount; i++)
if(process[i].sign_completion == 0)
{
time = process[i].arrival_time;
index++;
process[i].number = index;
break;
}
}
}
}
void output() //打印信息
{
int i;
printf("程序名 到达时间 服务时间 完成时间 周转时间 带权周转时间\n");
for(i = 0; i < process_amount; i++)
{
float weight_time = (float)(process[i].completion_time - process[i].arrival_time)/process[i].service_time;
printf(" %s\t %d\t %d\t %d\t %d\t\t%.2f\n",process[i].name,process[i].arrival_time,process[i].service_time,
process[i].completion_time,process[i].completion_time-process[i].arrival_time,weight_time);
}
}
int main()
{
int f;
printf("模拟时间片轮转法实现进程调度\n");
printf("请输入总进程数:\n");
scanf("%d",&process_amount);
input();
BubbleSort();
printf("进程运行顺序:\n");
RunProcess();
printf("\n");
output();
printf("\n");
return 0;
}
单词本
#include<stdio.h>
#include<string.h>
#define MaxStrSize 256
/* 根据用户需要自己定义大小 */
typedef struct
{
char ch[MaxStrSize];
/* ch是一个可容纳256个字符的字符数组 */
int length;
} SString;
/* 定义顺序串类型 */
int PartPosition (SString s1,SString s2,int k)
{
int i,j;
i=k-1;
/* 扫描s1的下标,因为c中数组下标是从0开始,串中序号相差1 */
j=0;
/* 扫描s2的开始下标 */
while(i<s1.length && j<s2.length)
{
if(s1.ch[i]==s2.ch[j])
{
i++;j++;
/* 继续使下标移向下一个字符位置 */
}
else
{
i=i-j+1; j=0;
}
}
if (j>=s2.length)
return i-s2.length;
else
return -1;
/* 表示s1中不存在s2,返回-1 */
/* 表示s1中存在s2,返回其起始位置 */
}
/* 函数结束 */ /*件一个文本文件,在里面输入想要的文本*/
void CreatTextFile()
{
SString S;
char fname[10],yn;
FILE *fp;
printf("输入要建立的文件名:");
scanf("%s",fname);
fp=fopen(fname,"w");
yn='n';/* 输入结束标志初值 */
while(yn=='n'||yn=='N')
{
printf("请输入一行文本:");
gets(S.ch);
gets(S.ch);
S.length=strlen(S.ch);
fwrite(&S,S.length,1,fp);
fprintf(fp,"%c",10);/* 是输入换行 */
printf("结束输入吗?y or n :");
yn=getchar();
}
fclose(fp);/* 关闭文件 */
printf("建立文件结束!\n");
} /*输入2进行计算出现次数,输入3可以确定文本出现的位置,以此实现检索单词的出现在文本文件中的行号,次数以及位置*/
void SubStrCount()
{
FILE *fp;
SString S,T;/* 定义两个串变量 */
char fname[10];
int i=0,j,k;
printf("输入文本文件名:");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要统计计数的单词:");
scanf("%s",T.ch);
T.length=strlen(T.ch);
while(!feof(fp))
{ /* 扫描整个文本文件 */
/* fread(&S.ch,1,sizeof(S),fp);//读入一行文本 */
memset(S.ch,'\0',256);
fgets(S.ch,100,fp);
S.length=strlen(S.ch);
k=0; /* 初始化开始检索位置 */
while(k<S.length-1) /* 检索整个主串S */
{
j=PartPosition(S,T,k);/* 调用串匹配函数 */
if(j<0 ) break;
else
{
i++;/* 单词计数器加1 */
k=j+T.length;/* 继续下一字串的检索 */
}
}
}
printf("\n单词%s在文本文件%s中共出现%d次\n",T.ch,fname,i);
}/* 统计单词出现的个数 */
void SubStrInd()
{
FILE *fp;
SString S,T; /* 定义两个串变量 */
char fname[10];
int i,j,k,l,m;
int wz[20]; /* 存放一行中字串匹配的多个位置 */
printf("输入文本文件名:");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要检索的单词:");
scanf("%s",T.ch);
T.length=strlen(T.ch);
l=0; /* 行计数器置0 */
while(!feof(fp))
{ /* 扫描整个文本文件 */
/* fread(&S,sizeof(S),1,fp);
//读入一行文本 */
memset(S.ch,'\0',256);
fgets(S.ch,256,fp);
S.length=strlen(S.ch);
l++; /* 行计数器自增1 */
k=0;/* 初始化开始检索位置 */
i=0; /* 初始化单词计数器 */
while(k<S.length-1) /* 检索整个主串S */
{
j=PartPosition(S,T,k); /* 调用串匹配函数 */
if(j<0) break;
else {
i++;/* 单词计数器加1 */
wz[i]=j;/* 记录匹配单词位置 */
k=j+T.length;/* 继续下一字串检索 */
}
}
if(i>0)
{
printf("行号:%d,次数:%d,位置分别为:",l,i);
for(m=1;m<=i;m++) printf("%4d",wz[m]+1); printf("\n");
}
}
}
void CreatTextFile(),SubStrCount(),SubStrInd();
int xz;
int print()
{
printf("===============================================\n");
printf("|| 文本文件的检索、字串的统计及定位 ||\n");
printf("||=========================================== ||\n");
printf("|| 1. 建立文本文件 ||\n");
printf("|| 2. 单词字串的计数 ||\n");
printf("|| 3. 单词字串的定位 ||\n");
printf("|| 4. 退出整个程序 ||\n");
printf("===============================================\n");
printf(" 请选择(1--4)\n ");
scanf("%d",&xz);
switch(xz) {
case 1 : CreatTextFile();break;
case 2 : SubStrCount();break;
case 3 : SubStrInd();break;
case 4 : return 0;
default:printf("选择错误,重新选 \n");
}
return 0;
}
/*用此函数来退出文本文件的单词检索*/
void end()
{
printf("谢谢使用文本文件的单词检索!\n");
}
/*主函数,利用无限循环可以进行连续的操作*/
int main()
{
while(1)
{
CreatTextFile(),SubStrCount(),SubStrInd();
}print();
return 0;
}