C问题模拟与数据表示之构造基础数据
问题求解要抽象化为数据处理,前提是要有合适的问题模拟与数据表示或事务的数字化,也就是构造合适的数据结构。与此同时,也可以将数据区分为动态的事务性数据和静态的基础数据(常用静态数组或常量数组表示),是否能够构造合适的基础数据,对于问题求解也至关重要。1 任意进制数的转换
求n整除d的余数,就能得到n的d进制数的最低位数字,重复上述步骤,直至n为0,依次得到n的d进制数表示的最低位至最高位数字。由各位数字取出相应字符,就能得到n的d进制的字符串。#include /* 函数trans将无符号整数n翻译成d(2< d< 16)进制表示的字符串s */ #define M sizeof(unsigned int)*8 int trans(unsigned n, int d, char s[]) { static char digits[] ="0123456789ABCDEF"; /* 十六进制数字的字符 */ char buf[M+1]; int j, i = M; if(d<2||d>16) { s[0]=" "; /* 不合理的进制,置s为空字符串 */ return 0; /* 不合理的进制,函数返回0 */ } buf[i]=" "; do{ buf[--i]=digits[n%d]; /*译出最低位,对应字符存入对应工作数组中*/ n/=d; }while(n); /* 将译出在工作数组中的字符串复制到s */ for(j=0;(s[j]=buf[i])!=" ";j++,i++); /* 其中控制条件可简写成s[j]=buf[i] */ return j; } /* 主函数用于测试函数 trans() */ main() { unsigned int num = 253; int scale[]={2,3,10,16,1}; char str[33]; int i; //clrscr(); for(i=0;i (%d) Error! ",num,scale[i]); } printf(" Press any key to quit... "); getch(); } 2 阿拉伯数字转换为罗马数字
将整数n(1 n 9999)转化成罗马数字。
整数n(1 n 9999)与罗马数字表示有以下对应关系:1000 用一个字符m 来表示,有几个1000 就用几个m 来表示;
900 用两个字符cm 来表示;
500 用一个字符d 来表示;
400 用两个字符cd 来表示;
100 用一个字符c 来表示;有几个100 就用几个c 来表示;
90 用两个字符xc 来表示;
50 用一个字符l 来表示;
40 用两个字符xl 来表示;
10 用一个字符x 来表示;有几个10 就用几个x 来表示;
9 用两个字符iv 来表示;
5 用一个字符v 来表示;
4 用两个字符iv 来表示;
1 用一个字符i 来表示;有几个1 就用几个i 来表示。
为了便于程序处理,将阿拉伯数字与对应的罗马数字表示分存在两个数组中。转换时,从尽可能大的数开始考察,要转换的罗马字符能被当前考察的数相减后仅大于等于0的次数,就是该考察数所对应的罗马数字可连续出现的次数。例如数23,能连续减10两次仅大于等于0,能连续减1三次仅大于等于0,所以其罗马数字有两个字符x和3个字符i,即xxiii。
code:#include #include #include #define ROWS 4 #define COLS 4 const int nums[ROWS][COLS]={ {1000,1000,1000,1000}, {900,500,400,100}, {90,50,40,10}, {9,5,4,1}}; const char *roms[ROWS][COLS]={{"m","m","m","m"}, {"cm","d","cd","c"}, {"xc","l","xl","x"}, {"ix","v","iv","i"}}; void D2roman(int decimal,char roman[ ]); void checknum(int val); int main() { int low,high; char roman[25]; printf("请输入需要转换的范围(十进制数字):"); scanf("%d %d",&low, &high); if(low>high) { int t = low; low=high; high=t; } for(;low<=high;low++) { D2roman(low,roman); printf("%d %s ",low,roman); } getchar();getchar(); return 0; } void checknum(int val)/*检查参数合理性*/ { if(val<1||val>9999) { printf("The number must be in range 1 ~ 9999 "); exit(0); } } void D2roman(int decimal,char roman[ ])/*将整数转换成罗马数字表示*/ { int power,index; roman[0]=" "; for(power=0;power=nums[power][index]) { strcat(roman,roms[power][index]); decimal-=nums[power][index]; } }3 从键盘读入实数
将从键盘读入的实数字符列转换成实数:#define ERR 5 #define OK 6 #include /* 设实数字符列有以下几种可能形式: 数符 整数部分 数符 整数部分. 数符 整数部分.小数部分 数符 .小数部分 其中数符或为空,或为字符‘+’,或为字符‘.’,分别表示不带符号、带正号和带负号。 整数部分和小数部分至少要有一个数字符组成。 上述实数形式说明,在实数转换过程中,同一字符在不同情况下会有不同的意义。 为标记当前实数转换的不同情况,程序引入状态变量, 由状态变量的不同值表示当前实数转换过程中的不同情况。 共有以下多种不同情况: 状态变量为0 表示正准备开始转换,还未遇到任何与实数有关的字符; 状态变量为1 表示已遇数的数符(符号字符); 状态变量为2 表示正在转换实数的整数部分; 状态变量为3 表示在未遇数字字符之前先遇小数点,必须要有小数部分; 状态变量为4 表示在转换整数部分之后遇小数点,这种情况可以没有小数部分; 状态变量为5(ERR)表示转换发现错误; 状态变量为6(OK)表示转换正常结束。 程序将输入字符分成数的符号字符、数字符、小数点、其他字符等几类, 各状态遇各类字符后,应变成的新状态,如下所示。 数符 数字符 小数点 其他字符 状态0 1 2 3 ERR 状态1 ERR 2 3 ERR 状态2 OK 2 4 OK 状态3 ERR 4 ERR ERR 状态4 OK 4 OK OK */ int status; double result,sig,scale; int sign(int c) /*处理数的符号函数*/ { if(c=="-") /*若为负号,置负数标记*/ sig=-sig; } int integer(int c) /*转换整数部分,转换一位整数位*/ { result=result*10.0+c-"0"; } int decimal(int c) /*转换小数部分,转换一位小数位*/ { result+=(c-"0")*scale; scale/=10.0; } // 状态表 /*col:ckind 0符号,1数字,2小数点,3其它 row: status, */ const int statbl[ ][4]={ {1, 2,3, ERR}, /*status 0*/ {ERR,2,3, ERR}, /*status 1*/ {OK, 2,4, OK}, /*status 2*/ {ERR,4,ERR,ERR}, /*status 3*/ {OK, 4,OK, OK}}; /*status 4*/ /*转换函数表:状态0,1,2遇到数字调用integer;状态3,4遇到数字调用decimal*/ const int(*funtbl[ ][4])( )={ {sign,integer,NULL,NULL},// 状态0遇到符号调用sign {NULL,integer,NULL,NULL}, {NULL,integer,NULL,NULL}, {NULL,decimal,NULL,NULL}, {NULL,decimal,NULL,NULL}}; int readreal(double *dp) { int c,ckind; sig=1.0; result=0.0; scale=0.1; while((c=getchar( ))==" "||c==" "||c==" ");/*跳过前导空白符*/ status=0; /*置初始状态*/ for(;;) { /* 分类当前字符*/ if(c=="+"||c=="-") ckind=0; /* 数的符号字符*/ else if(c>="0"&&c<="9") ckind=1; /* 数字符*/ else if(c==".") ckind=2; /* 小数点*/ else ckind=3; /* 其它字符 */ if(funtbl[status][ckind]) /* 如有转换函数 */ (*funtbl[status][ckind])(c); /* 执行相应的函数 */ status=statbl[status][ckind]; /* 设置新的状态*/ if(status==ERR||status==OK)break; /* 结束:出错或成功 */ c=getchar(); } ungetc(c,stdin); /* 归还数的结束符 */ if(status==OK) { *dp=result *sig; /* 读入数按指针参数赋给相应变量 */ return 1; } return -1; /* 出错返回 */ } main() { double x; printf(" Please input real numbers (use nonreal char to end input): "); while(readreal(&x)==1) printf("The real number you input is: %f ",x); printf(" You have inputted nonreal char. Press any key to quit... "); getch(); }
-end-