zoukankan      html  css  js  c++  java
  • 【思考题】任意长度有理数乘法运算

    目标需求:

    //描述:
    //长数相乘
    //请编程实现:两个任意长度的数相乘,请输出结果.
    //详细要求以及系统约束
    //1)两个数可能是小数、整数、正数、负数;
    //2)输入输出均为字符串形式,输入的字符串以“”结束,输出的结果字符串也必须以“”结束;
    //3)输入的字符串不能是空字符串或非法字符串,否则返回-1,其他情况返回0;
    //4)输出的结果字符串需要过滤掉整数位前以及小数位后无效的0,小数位为全0的,直接输出整数位;
    //例1:相乘结果为11.345,此数值前后均不可以带0,“011.345”或者“0011.34500”等等前后带无效0的均视为错误输出。
    //例2:080 × 0.125 结果是“10”
    //5)输出的结果如果是正数或0需要过滤掉前面的+号。
    //例1:相乘结果为+121,则“+121”为错误输出,“121”为正确输出。
    //输入:
    //输入两个任意长度的数
    //输出:
    //输出相乘的结果,如果输入的数不规范,输出结果为空
    //样例输入:
    //100000
    //500000
    //样例输出:
    //50000000000

    思路:

    首先实现字符串加法,去除乘数以及被乘数的小数点,计算结果小数点位置,被乘数逐位与乘数相乘并进行相对的左移位(乘10),然后对这些逐位相乘结果进行相加即可。

    得到结果再进行截头截尾(去除结果字符串的开始的0串和小数末尾的0串)。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void str_z(char* s1, char* s2, char **s1z, char **s2z, int *sign){
    	int s1sign=1,s2sign=1;
    
    	if(s1[0]=='-'){
    		s1sign=-1;
    		*s1z = &s1[1];
    	}
    	else
    		*s1z = s1;
    	if(s2[0]=='-'){
    		s2sign=-1;
    		*s2z = &s2[1];
    	}
    	else
    		*s2z = s2;
    	*sign = s1sign*s2sign;
    }
    
    void zheng_xiao_fenli(char *s1, char* s2, int *xiaoshu_cnt, char **s1_num, char **s2_num){
    	int s1len, s2len;
    	int k1, k2, s1_xiaoshu_cnt=0, s2_xiaoshu_cnt=0;
    
    	s1len = strlen(s1);
    	s2len = strlen(s2);
    
    	for(k1=s1len-1; k1>=0; k1--){
    		if(s1[k1]>='0'&&s1[k1]<='9')
    			continue;
    		else if(s1[k1]=='.')
    			s1_xiaoshu_cnt += s1len-k1-1;
    		else{
    			exit(0); //非法字符
    		}
    	}
    
    	if(s1_xiaoshu_cnt==0){
    		*s1_num = s1;
    	}
    	else{
    		*s1_num = (char*)malloc(sizeof(char)*s1len);
    		/*if(*s1_num==NULL){
    			printf("malloc failed!
    ");
    			exit(0);
    		}*/
    		memcpy(*s1_num, s1, sizeof(char)*(s1len-s1_xiaoshu_cnt-1));
    		memcpy(*s1_num+s1len-s1_xiaoshu_cnt-1, s1+s1len-s1_xiaoshu_cnt, sizeof(char)*s1_xiaoshu_cnt);
    		*(*s1_num+s1len-1) = '';
    	}
    
    	for(k2=s2len-1; k2>=0; k2--){
    		if(s2[k2]>='0'&&s2[k2]<='9')
    			continue;
    		else if(s2[k2]=='.')
    			s2_xiaoshu_cnt += s2len-k2-1;
    		else{
    			exit(0); //非法字符
    		}
    	}
    
    	if(s2_xiaoshu_cnt==0){
    		*s2_num = s2;
    	}
    	else{
    		*s2_num = (char*)malloc(sizeof(char)*s2len);
    		/*if(*s2_num==NULL){
    			printf("malloc failed!
    ");
    			exit(0);
    		}*/
    		memcpy(*s2_num, s2, sizeof(char)*(s2len-s2_xiaoshu_cnt-1));
    		memcpy(*s2_num+s2len-s2_xiaoshu_cnt-1, s2+s2len-s2_xiaoshu_cnt, sizeof(char)*s2_xiaoshu_cnt);
    		*(*s2_num+s2len-1) = '';
    	}
    
    	*xiaoshu_cnt = s1_xiaoshu_cnt+s2_xiaoshu_cnt;
    }
    
    char* str_add(char* s1, char* s2){
    	int s1len,s2len,anslen;
    	int k1,k2,ansk,c,s;
    	char *ans,*ansrtn;
    
    	s1len=strlen(s1);
    	s2len=strlen(s2);
    
    	anslen=s1len>s2len?s1len+1:s2len+1;
    	ans = (char*)malloc(sizeof(char)*(anslen+1));
    	/*if(ans==NULL){
    		printf("malloc failed!
    ");
    		exit(0);
    	}*/
    	k1 = s1len-1;
    	k2 = s2len-1;
    	ansk = anslen-1;
    	s=0; c=0;
    	while(k1>=0||k2>=0){
    		if(k1>=0&&k2>=0){
    			c = s1[k1--]+s2[k2--]-'0'-'0'+s;
    			ans[ansk--] = c%10+'0';
    			s = c/10;
    		}
    		else if(k1>=0){
    			c = s1[k1--]-'0'+s;
    			ans[ansk--] = c%10+'0';
    			s = c/10;
    		}
    		else if(k2>=0){
    			c = s2[k2--]-'0'+s;
    			ans[ansk--] = c%10+'0';
    			s = c/10;
    		}
    	}
    	ans[0] = s+'0';
    	ans[anslen] = '';
    	for(ansk=0; ansk<anslen; ansk++){
    		if(ans[ansk]!='0')
    			break;
    	}
    	if(ansk!=0){
    		ansrtn = (char*)malloc(sizeof(char)*(anslen-ansk+1));
    		if(ansrtn==NULL){
    			printf("malloc failed!
    ");
    			exit(0);
    		}
    		strcpy(ansrtn, &ans[ansk]);
    		free(ans);
    		return ansrtn;
    	}
    	else
    		return ans;
    }
    
    char* str_mul(char* s1, char* s2){
    	int s1len, s2len, k1, k2, k;
    	char* mul_temp, *temp, *del_temp;
    	int mul_temp_len;
    	char* add_temp;
    
    	s1len = strlen(s1);
    	s2len = strlen(s2);
    
    	add_temp = (char*)malloc(sizeof(char)*2);
    	/*if(add_temp==NULL){
    		printf("malloc failed!
    ");
    		exit(0);
    	}*/
    	add_temp[0] = '0';  add_temp[1] = '';
    	for(k1=0; k1<s1len; k1++){
    		mul_temp = (char*)malloc(sizeof(char)*2);
    		/*if(mul_temp==NULL){
    			printf("malloc failed!
    ");
    			exit(0);
    		}*/
    		mul_temp[0] = '0';  mul_temp[1] = '';
    		if(s1[k1]=='0')
    			continue;
    		for(k=s1[k1]-'0'; k>0; k--){
    			del_temp = mul_temp;
    			mul_temp = str_add(mul_temp, s2);
    			free(del_temp);
    		}
    		mul_temp_len = strlen(mul_temp);
    		temp = (char*)malloc(sizeof(char)*(mul_temp_len+s1len-k1));
    		/*if(temp==NULL){
    			printf("malloc failed!
    ");
    			exit(0);
    		}*/
    		memset(temp, '0', sizeof(char)*(mul_temp_len+s1len-k1));
    		memcpy(temp, mul_temp, sizeof(char)*mul_temp_len);
    		temp[mul_temp_len+s1len-k1-1] = '';
    		free(mul_temp);
    		mul_temp = temp;
    		add_temp = str_add(mul_temp, add_temp);
    	}
    
    	//printf("%s", add_temp);
    	return add_temp;
    }
    
    int main(void){
    	char s1[100];
    	char s2[100];
    	int sign, xs_cnt, k, kk, kp;
    	char *s1z, *s2z;
    	char *s1zheng, *s1xiao, *s2zheng, *s2xiao, *s1_num, *s2_num;
    	char *ans; int anslen, xs_cnt_temp;
    
    	gets(s1);
    	gets(s2);
    
    	str_z(s1, s2, &s1z, &s2z, &sign);
    	zheng_xiao_fenli(s1z, s2z, &xs_cnt, &s1_num, &s2_num);
    	ans = str_mul(s1_num, s2_num);
    	anslen = strlen(ans);
    
    	printf("
    ");
    	if(sign==-1)
    		printf("-");
    	if(xs_cnt==0){
    		printf("%s", ans);
    	}
    	else{
    		if(anslen<=xs_cnt){
    			for(k=anslen-1; k>=0; k--){
    				if(ans[k]!='0')
    					break;
    			}
    			printf("0.");
    			xs_cnt_temp = xs_cnt-anslen;
    			while(xs_cnt_temp--){
    				printf("0");
    			}
    			for(kk=0; kk<=k; kk++){
    				printf("%c", ans[kk]);
    			}
    		}
    		else{
    			for(k=0; k<anslen-xs_cnt; k++){
    				printf("%c", ans[k]);
    			}
    			for(kk=anslen-1; kk>=k; kk--){
    				if(ans[kk]!='0')
    					break;
    			}
    			if(kk!=k-1){
    				printf(".");
    				for(kp=k; kp<=kk; kp++){
    					printf("%c", ans[kp]);
    				}
    			}
    		}
    	}
    
    	system("pause");
    	return 0;
    }

    结果演示:



  • 相关阅读:
    delphi 让子窗体显示最大化
    Delphi 中拖动无边框窗口的5种方法
    Delphi 非主窗体(即子窗体)在任务栏显示按钮
    电脑快捷键大全
    picpick快捷键
    is()
    animate()
    :animated
    css() 方法返回或设置匹配的元素的一个或多个样式属性。
    outerWidth()
  • 原文地址:https://www.cnblogs.com/xhyzjiji/p/6159373.html
Copyright © 2011-2022 走看看