字符串模拟数学运算,欢迎拍砖,顺便散点分吧
程序代码:
#include <stdio.h> #include <string.h> #define SIZE 100 void Inverse(char *a, int len) { //将字符串逆序;len = strlrn(a) char temp;int i; for (i = 0;i < --len;++i) temp = a[i], a[i] = a[len], a[len] = temp; } int compare(char *a, char *b) { //判断 a < b ? int a_len = strlen(a); int b_len = strlen(b); if (a_len == b_len) return strcmp(a, b) < 0; else return a_len < b_len; } void change(char *a) { //去掉字符串前的 '0' int m = 0, n = 0; while (a[m] && a[m++] == '0');--m; //求出串前 '0' 个数,如果是 全'0',m++会短路 while (a[n] = a[m+n]) ++n; //移动 } void Add(char *a, char *b, char *c) { //c = a + b; int Result, i = 0; int a_len = strlen(a); int b_len = strlen(b); memset(c, 0, a_len > b_len ? a_len + 2 : b_len + 2); //将 c置空 for (--b_len;--a_len >= 0 && b_len >= 0;--b_len) { Result = a[a_len]-'0' + b[b_len]-'0' + c[i]; c[i++] = Result % 10 + '0'; c[i] = (Result /= 10); } while (a_len >= 0) { //说明 a > b, 把 a剩余部分加进去 Result = a[a_len--]-'0' + c[i]; c[i++] = Result % 10 + '0'; c[i] = (Result /= 10); } while (b_len >= 0) { //说明 b > a Result = b[b_len--]-'0' + c[i]; c[i++] = Result % 10 + '0'; c[i] = (Result /= 10); } if (Result) c[i++] += '0'; //若有进位,特殊处理 Inverse(c, i); } void Sub(char *a, char *b, char *c) { //c = a - b;前提是 a > b int a_len, n = 0, b_len = strlen(b); for (a_len = 0;c[a_len] = a[a_len];++a_len); //strcpy(c, a)&& a_len = strlen(a); while (--a_len, --b_len >= 0) { c[n = a_len] -= b[b_len] - '0'; while (c[n] < '0') c[n] += 10, --c[--n]; } change(c); } void Subtract(char *a, char *b, char *c) { //c = a - b; int len; if (compare(a, b)) { Sub(b, a, c); len = strlen(c); Inverse(c, len); c[len] = '-', c[len+1] = '\0'; Inverse(c, len+1); } else Sub(a, b, c); } void Multiply(char *a, char *b, char *c) { //c = a * b;模拟列竖式乘法运算 int Result, i, j; int a_len = strlen(a); int b_len = strlen(b); int len = a_len + b_len; // c最多有len位 memset(c, 0, len + 1); for (i = a_len-1;i >= 0;--i) for (j = b_len-1;j >= 0;--j) { Result = (a[i]-'0') * (b[j]-'0') + c[len-2-i-j]; c[len-2-i-j] = Result % 10; c[len-1-i-j] += Result / 10; } for (i = 0;i < a_len+b_len;c[i++] += '0'); if (i && c[i-1] != '0') c[i] = '\0'; else c[--i] = '\0'; Inverse(c, i); } void Divide(char *a, char *b, char *c) { //c = a / b;模拟列竖式除法运算 int i, j = 0, m, n, o; int a_len = strlen(a); int b_len = strlen(b); char aa[SIZE], bb[9][SIZE]; memset(c, 0, a_len+1); //c最多有a_len位 aa[0] = bb[0][0] = '0';aa[1] = bb[0][1] = '\0'; //在a前添加字符‘0’,存入aa for (strcat(aa, a), strcat(bb[0], b), i = 1;i < 9;++i) Add(bb[i-1], b, bb[i]); //bb[i] = (i+1) * b for (i = 0;i < a_len-b_len+1;++i) { for (j = 0;strncmp(&aa[i], bb[j], b_len+1) >= 0 && j < 9;++j); if (c[i] = j + '0', !j) continue; //j = 0时,不用减 for (m = i+b_len, n = b_len;n >= 0;--m, --n) { aa[o = m] -= bb[j-1][n] - '0'; while (aa[o] < '0') aa[o] += 10, --aa[--o]; } } if (i) change(c); //i不为 0时, 将 c前的‘0’去掉 else strcpy(c, "0"); //i 为 0时,必有a < b, 结果为 0 } void Remainder(char *a, char *b, char *c) { //c = a % b;直接从 Divide 那复制过来的,额 int i, j = 0, m, n, o; int a_len = strlen(a); int b_len = strlen(b); char bb[9][SIZE]; memset(c, 0, a_len+1); c[0] = bb[0][0] = '0';bb[0][1] = '\0'; //上面的 aa最后就是余数了,这里直接把aa改成了 c for (strcat(c, a), strcat(bb[0], b), i = 1;i < 9;++i) Add(bb[i-1], b, bb[i]); for (i = 0;i < a_len-b_len+1;++i) { for (j = 0;strncmp(&c[i], bb[j], b_len+1) >= 0 && j < 9;++j); if (!j) continue; for (m = i+b_len, n = b_len;n >= 0;--m, --n) { c[o = m] -= bb[j-1][n] - '0'; while (c[o] < '0') c[o] += 10, --c[--o]; } } change(c); } int main() { char a[SIZE], b[SIZE], c[SIZE*2-1]; puts("Input a:");gets(a); puts("Input b:");gets(b); printf("\nCompare:\n%s %s %s\n", a, compare(a, b) ? "<" : ">=", b); Add(a, b, c); printf("\nAdd:\n%s + %s = %s\n", a, b, c); Subtract(a, b, c); printf("\nSubtract:\n%s - %s = %s\n", a, b, c); Multiply(a, b, c); printf("\nMultiply:\n%s * %s = %s\n", a, b, c); Divide(a, b, c); printf("\nDivide:\n%s / %s = %s\n", a, b, c); Remainder(a, b, c); printf("\nRemainder:\n%s %% %s = %s\n", a, b, c); puts(""); return 0; }
[ 本帖最后由 azzbcc 于 2013-1-9 12:45 编辑 ]