问答题

【程序说明】 下列文法可用来描述化学分子式的书写规则(例如,A12(C03)、Cu(OH)2): λ→β|βλ β→δ|δn δ→ξ|ξθλ 其中,λ是一个分子式;δ或是一个元素,或是一个带括号的(子)分子式,元素或是一个大写字母(记为ξ),或是一个大写字母和一个小写字母(记为ξθ);β或是一个δ,或是在δ之后接上一个整数n,δn表示β有n个δ的元素或(子)分子式。一个完整的分子式由若干个β组成。 当然一个正确的分子式除符合上述文法规则外,还应满足分子式本身的语义要求。下面的程序输入分子式,按上述文法分析分子式,并计算出该分子式的分子量。例如,元素H的原子量是1,元素O的原子量是16。输入分子式H2O,程序计算出它的分子量为重18(1×2+16)。程序中各元素的名及它的原子量从文件atom.dat中读入。 【程序】 #include <stdio.h> #include <string.h> #define MAXN 300 #define CMLEN 30 struct elem{ char name[3];/*元素名*/ double v; /*原子量*/ }nTbl[MAXN]; char cmStr[CMLEN], *pos; int c; FILE *fp; double factor(); double atom() /*处理文法符号δ*/ { char w[3]; int i; double num; while((c = *pos++)=="|| c==’\t’); /* 略过空白字符 */ if(c==’\n’) return 0.0; if(c>=’A’ && c<=’Z’){/* 将元素名存入W*/ w[i=0]=c; c=*pos++; if(c>=’a’ && c<=’z’) w[++i]=c; else pos--; w[++i]=’\0’; for(i=0; nTbl[i].v>0.0; i++) if(strcmp(w, nTbl[i].name)==0) return nTbl[i].v; printf("\n 元素表中没有所输入的元素: \t%s\n",w); return -1.0; } else if(c==’(’){ if((num = (1) <0.0)return -1.0; /* 包括可能为空的情况 */ if(*pos++ !=’)’){ printf(" 分子式中括号不匹配!\n"); return -1.0; } return num; } printf("分子式中存在非法字符: \t%c\n",c); return -1.0; } double mAtom() /* 处理文法符号β*/ { double num; int n=1; if((num = (2) )<0.0) return -1.0; c = *pos++; if(c>=’0’&& c <=’9’){ n=0; while(c>=’0’ && c<=’9’){ n= (3) ; c=*pos++; } } pos--; return num *n; } double factor() /* 处理文法符号λ */ { double num=0.0, d; if((num=mAtom())<0.0) return -1.0; while(*pos>=’A’ && *pos<= ’Z’ || *pos==’(’){ if((d= (4) <0.0) return -1.0; } return num; } void main() { char fname[]="atom.dat"; /*元素名及其原子量文件*/ int i; double num; if((fp=fopen(fname, "r"))==NULL){/* 以读方式打开正文文件*/ printf("Can not open %s file.\n", fname); return;/* 程序非正常结束 */ } i=0; while(i<MAXN && fscanf(fp, "%s%lf", nTbl[i].name, &nTbl[i].v) == 2)i++; fclose(fp); nTbl[i].v=-1.0; while(I){ /* 输入分子式和计算分子量循环,直至输入空行结束*/ printf ("\n 输入分子式!(空行结束)\n"); gets(cmStr); pos=cmStr; if(cmStr[0]==’\0’)break; if((num=factor())>0.0) if (*pos != ’\0’)printf("分子式不完整!\n"); else printf(" 分子式的分子量为 %f\n", num); } }

【参考答案】

(1) factor() (2) atom() (3) n* 10+c-’0’ (4) mAtom()或factor()......

(↓↓↓ 点击下方‘点击查看答案’看完整答案 ↓↓↓)
热门 试题

问答题
【程序说明】著名的四色定理指出任何平面区域图均可用4种颜色着色,使相邻区域着不同的颜色。本程序对给定的区域图找出所有可能的不超过4种颜色的着色方案。程序中用1~4表示4种颜色。要着色的N个区域用0~N-1编号,区域相邻关系用adj[][]矩阵表示,矩阵的i行j列的元素为1,表示区域i与区域j相邻:矩阵的i行j列的元素为0,表示区域i与区域j不相邻。数组color[]用来存储着色结果,color[i]的值为区域i所着颜色。【程序】#include<stdio.h>#define N 10void output(int color[]) *输出一种着色方案* {int i;for(i=0; i<N; i++)printf( %4d , color[i]);pfintf( n );}int back(int *ip,int color[]) *回溯* {int c=4;while(c==4){if(*ip<=0)return 0;--(*ip);c= (1) ;color[*ip]=-1;}return c;} *检查区域i,对c种颜色的可用性* int colorOK(int i, int c, int adj[][N], int color[]){int j;for(j=0; j<i; j++)if( (2) )return 0;return 1;} *为区域i选一种可着的颜色* int select(int i,int c,int adj[][N], int color[])int k;for(k = c; k<=4; k++)if( (3) )return k;return 0;int coloring(int adj[][N]) *寻找各种着色方案* {int color[N], i, c, cnt;for(i=0; i<N; i++)cotor[i]=-1;i=c=0;cnt=0;while(1){if((c= (4) ==0){c=back(&i, color);if(c==0)return cnt;}else{(5) ; i++;if(i==N){output(color);++cnt;c=back(&i, color);}else c = 0;}}}void main(){int adj[N][N]={{0,1,0,1,1,1,1,1,1,1},{1,0,1,1,0,1,1,1,1,0},{0,1,0,1,0,1,1,0,1,1},{1,1,1,0,1,1,0,0,1,1},{1,0,0,1,0,1,0,0,0,0},{1,1,1,1,1,0,1,0,0,1},{1,1,1,0,0,1,0,0,1,0},{1,1,0,0,0,0,0,0,1,1},{1,1,1,1,0,0,1,1,0,1},{1,0,1,1,0,1,0,1,1,0}};printf( 共有%d组解. n ,coloring(adj));}
问答题
【说明】“背包问题”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,…,wn。希望从N件物品中选择若干件物品,所选物品的重量之和恰能放入该背包,即所选物品的重量之和等于S。如下程序均能求得“背包问题”的一组解,其中程序1是“背包问题”的递归解法,而程序2是“背包问题”的非递归解法。【程序1】#include<stdio.h>#define N 7#define S 15int w[N+1]={0,1,4,3,4,5,2,7};int knap(int s, int n){if(s==0) return 1;if(s<0 || (s>0 && n<1))return 0;if( (1) ){ *考虑物品n被选择的情况* printf( %4d ,w[n]);return 1;}return (2) ; *考虑不选择物品n的情况* }main(){if(knap(S,N))printf( OK! n );else printf( N0! n );}【程序2】#include<stdio.h>#define N 7#define S 15typedef struct{int s;int n;int job;}KNAPTP;int w[N+1]={0,1,4,3,4,5,2,7};int knap(int s, int n);main(){if(knap(S,N)) printf( 0K! n );else printf( N0! n );}int knap(int s, int n){KNAPTP stack[100],x;int top, k, rep;x.s=s;x.n=n;x.job=0;top=1; stack[top]=x;k=0;while( (3) ){x=stack[top];rep=1;while(!k && rep){if(x.s==0) k=1; *已求得一组解* else if(x.s<0 || x.n<=0) rep=0;else{x.s= (4) ;x.job=1;(5) =x;}} *while* if(!k){rep=1;while(top>=1 && rep){x=stack[top--];if(x.job==1){x.s +=w[x.n+1];x.job=2;stack[++top]=x;(6) ;} *if* } *while* } *if* *while* if(k){ *输出一组解* while(top>=1){x=stack[top--];if(x.job==1)printf( %4d t ,w[x.n+1]);}}return k;}