[C/C++]OJ练习题:输出两个带分数的差[格式控制]

2017-11-29 18:50:22来源:CSDN作者:Shenpibaipao人点击

分享
第七城市th7cn

>题目

    计算并输出两个带分数的差。例如1.75可记为1[3/4]。每个测试数据只有一行,输出结果如a[b/c] ,要求控制输出格式:1.要求化简;2.a为0时,只输出[b/c];3.b为0时,只输出a;4.a、b都为0时,输出0。

     输入数据格式不保证值的不为0性,即对于a[b/c],a可能为0,此时输入为[b/c],如[1/2];b也可能为0,此时输入为a,如3;a、b同时为0时,输入为0

    输入数据:

        15[6/35],8[4/7]

        [1/2],-1

        -[1/2],-[1,2]

    输出:

        6[3/5]

        1[1/2]

        0


>分析

     1.字符串转int值

     这题读入一个字符串,要求从字符串中读取字符并还原为数字。这个我们可以利用一个栈来实现:

// 从字符串栈里构建int值 int buildNum(char* numStack,int top){	if(top == 0) return 0;	int sum = 0;	for(int i=0;i<top;i++){		sum*=10;		sum+=numStack[i]-'0';	}	return sum;}
    例如当栈中内容为字符串"1245"时,最后返回的sum为1245(int)。

    2.分析缺省值

    我们给出a、b、c的初始值为0,当其缺省时即为0;a、[b/c]无法同时缺省。

  • 1.a、b都为0时(也就是输入0的情况),abc应该都为0,但作为分母,c显然不能为0,因此应当手动给c赋值为1;
  • 2.仅a缺省时,b、c必然不能缺省,也就是说b、c必然都不为0;
  • 3.仅[b/c]缺省时(此时bc都为初始值0),a不能缺省,但a可能为0,注意到这时候c也必须为1;(注意,这种情况实际上被包含于'情况1'(a=b=c=0 包含 b=c=0))
// 检查缺省值(0) void checkNum(int& a, int& b,int& c){	if(a缺省){// 仅a缺省时 		//TODO check (b==0 || c==0) Then ...	}	else if(c==0 && b==0) c=1;// b、c缺省时,c实际上应为1 }
    3.假分式化简

    假分式化简必然要用到最大公约数和最小公倍数:

// 最大公因数 int gcd(int a,int b){	return b?gcd(b,a%b):a;}// 最小公倍数 int lcm(int a,int b){	if(a==0 && b==0) return 0;	return (a*b/gcd(a,b));}

    4.需要注意负号'-'的存在,可能会影响结果

    5.输出时的格式控制


>代码

#include <iostream>#define maxSize 200using namespace std;// 数字表 numList[i][numList[i+1]/numList[i+2]]int numList[6] = {0};// 符号位 int symbol[2] = {1};// 取绝对值 int abs(int num){	return num>0?num:num*-1;}// 最大公因数 int gcd(int a,int b){	return b?gcd(b,a%b):a;}// 最小公倍数 int lcm(int a,int b){	if(a==0 && b==0) return 0;	return (a*b/gcd(a,b));}// 是否为数字 bool isDigit(char c){	return '0'<=c && c<='9';}// 从字符串栈里构建int值 int buildNum(char* numStack,int top){	if(top == 0) return 0;	int sum = 0;	for(int i=0;i<top;i++){		sum*=10;		sum+=numStack[i]-'0';	}	return sum;}// 检查缺省值 void checkNum(int& a, int& b,int& c){	if(c==0 && b!=0){//a缺省时,a和b分别应为b和c的值 		int temp = c;		c = b;		b = a;		a = temp;	}	else if(c==0 && b==0) c=1;//b、c缺省时,c实际上应为1 }// 初始化值表 void initNumList(char* str){	int listTop = 0,stackTop = 0;	char numStack[maxSize] = {'/0'};	// 初始化 	for(int i=0;i<6;i++)numList[i] = 0;	for(int i=0;i<2;i++)symbol[i] = 1;	// 扫描字符串并提取数字 	for(int i=0;str[i]!='/0';i++){		if(str[i]=='-'){			// 标记符号位 			symbol[listTop/3] = -1;		} else if (isDigit(str[i])){			numStack[stackTop++] = str[i];		} else {			if(stackTop!=0){				int num = buildNum(numStack,stackTop);				numList[listTop++] = num;				stackTop = 0;			}			if(str[i]==',') listTop = 3;// 从a2开始计数 		}	}	// 清空栈 	if(stackTop!=0){		int num = buildNum(numStack,stackTop);		numList[listTop++] = num;		stackTop = 0;	}	// 检查缺省情况 	for(int i=0;i<6;i+=3){		checkNum(numList[i],numList[i+1],numList[i+2]);	}}// 获取值表第 index个值 int getNum(int index){	return numList[index-1];}// 输出控制 a[b/c]void outputCtl(int b,int c){	if(b==0){		cout<<0<<endl;		return;		}	bool negative = b<0?true:false;		b = abs(b);	int g = gcd(b,c); // 取假分子和分母的最大公因数 	b = b/g;	 c = c/g; // 约分 	int a = b/c; b = b%c; // 化简为 a[b/c] 		if(negative)cout<<"-";	if(a==0)cout<<"["<<b<<"/"<<c<<"]"<<endl;	else if(b==0) cout<<a<<endl;	else cout<<a<<"["<<b<<"/"<<c<<"]"<<endl;}int main(){	char str[maxSize] = {'/0'};	cin >> str;	initNumList(str);		int a1=getNum(1),b1=getNum(2),c1=getNum(3);// a1[b1/c1]	int a2=getNum(4),b2=getNum(5),c2=getNum(6);// a2[b2/c2]		int c = lcm(c1,c2);	int b = (a1*c1+b1)*(c/c1)*symbol[0] - (a2*c2+b2)*(c/c2)*symbol[1];	outputCtl(b,c);		return 0;}


第七城市th7cn

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台