首页 > 试题广场 >

Rational Arithmetic (20)

[编程题]Rational Arithmetic (20)
  • 热度指数:3469 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference,
product and quotient.

输入描述:
Each input file contains one test case, which gives in one line the two rational numbers in the format "a1/b1 a2/b2". 
The numerators and the denominators are all in the range of long int. If there is a negative sign, it must appear only in
front of the numerator. The denominators are guaranteed to be non-zero numbers.


输出描述:
For each test case, print in 4 lines the sum, difference, product and quotient of the two rational numbers, respectively. The format of each 
line is "number1 operator number2 = result". Notice that all the rational numbers must be in their simplest form "k a/b", where k is
the integer part, and a/b is the simplest fraction part. If the number is negative, it must be included in a pair of parentheses. If the
denominator in the division is zero, output "Inf" as the result. It is guaranteed that all the output integers are in the range of long int.
示例1

输入

5/3 0/6

输出

1 2/3 + 0 = 1 2/3<br/>1 2/3 - 0 = 1 2/3<br/>1 2/3 * 0 = 0<br/>1 2/3 / 0 = Inf
这种题目,思路越简单(想的越快)写的越多,思路越巧(不容易想)写的越少,所以还是要积累大神的写法,然后背下来;我的方法属于想得快、写的多的,思路仅供参考。
1. 构造函数:通分+处理分母为0+形成输出string
2. 加法:分为同号和异号两种情况,异号“左正右负”与“右正左负”只需递归切换顺序即可,故只考虑“左正右负”情况,该情况只需再分为“左绝对值大”与“右绝对值大”两种情况即可;主函数体不通分,上交构造函数通分
3. 减法:实际通过加一个负数实现,上交加法实现
4. 乘法:实际为四个元素相加,上交加法实现
5. 除法:实际为两个元素相乘,上交乘法实现
6. 重点:本法处理分母为0其实很简单,分母=0(其他部分随意)的分数不会干扰到任何一种运算;算法的最底层部分在于加法的异号处理和通分,其余算法都在这基础之上
#pragma warning (disable:4996)
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;

#define MAX 1000

long max_cmn_div(long nu, long de) /* 求最大公约数 */
{
    for (long i = de; i >= 1; --i) {
        if (nu % i == 0 && de % i == 0) {
            return i;
        }
    }
    return 1;
}

typedef struct frac_t {
    int sign;       /* 1 or -1 */
    long iport;
    long numer;
    long deno;
    char outform[MAX];
    
    frac_t(int si, long ip, long nu, long de) :sign(si), iport(ip), numer(nu), deno(de) {
        long cmn_div;
        if (de != 0) {
            iport = ip + nu / de;
            numer = nu % de;

            cmn_div = max_cmn_div(numer, deno);
            numer /= cmn_div;
            deno /= cmn_div;

            char tmp[MAX];
            (void)memset(outform, 0, sizeof(outform));
            (void)memset(tmp, 0, sizeof(tmp));
            if (si > 0) {
                if (iport > 0) {
                    (void)sprintf(outform, "%ld", iport);
                    if (numer > 0) {
                        (void)sprintf(tmp, " %ld/%ld", numer,deno);
                        (void)strcat(outform, tmp);
                    }
                }
                else if (numer > 0) {
                    (void)sprintf(tmp, "%ld/%ld", numer, deno);
                    (void)strcat(outform, tmp);
                }
                else {
                    (void)sprintf(outform, "0");
                }
            }
            else {
                if (iport > 0) {
                    (void)sprintf(outform, "(-%ld", iport);
                    if (numer > 0) {
                        (void)sprintf(tmp, " %ld/%ld", numer, deno);
                        (void)strcat(outform, tmp);
                    }
                    (void)strcat(outform, ")");
                }
                else if (numer > 0) {
                    (void)sprintf(tmp, "(-%ld/%ld)", numer, deno);
                    (void)strcat(outform, tmp);
                }
                else {
                    (void)sprintf(outform, "0");
                }
            }
        }
        else {
            (void)sprintf(outform, "Inf");
        }
    }

    bool abs_ls(const frac_t& fn)const { /* 比较绝对值 */
        if (iport < fn.iport) {
            return true;
        }
        else if (iport == fn.iport) {
            if ((double)numer / (double)deno < (double)fn.numer / (double)fn.deno) {
                return true;
            }
        }

        return false;
    }

    frac_t operator+ (const frac_t& fn)const {
        int si = sign, ip = iport, nu = numer, de = deno;

        if ((sign == 1 && fn.sign == 1) || (sign == -1 && fn.sign == -1)) {
            si = sign;
            ip = iport + fn.iport;
            if (deno == fn.deno) {
                nu = numer + fn.numer;
                de = deno;
            }
            else {
                nu = numer * fn.deno + fn.numer * deno;
                de = deno * fn.deno;
            }
        }
        else if (sign == 1 && fn.sign == -1) {
            if (abs_ls(fn)) {
                si = -1;
                ip = 0;
                nu = -(iport * deno + numer) * fn.deno + (fn.iport * fn.deno + fn.numer) * deno;
                de = deno * fn.deno;
            }
            else {
                si = 1;
                ip = 0;
                nu = (iport * deno + numer) * fn.deno - (fn.iport * fn.deno + fn.numer) * deno;
                de = deno * fn.deno;
            }
        }
        else {
            return fn + (*this);
        }

        return frac_t(si, ip, nu, de);
    }

    frac_t operator- (const frac_t& fn) const {
        return (*this) + frac_t(-fn.sign, fn.iport, fn.numer, fn.deno);
    }

    frac_t operator* (const frac_t& fn)const {
        int si = sign;
        if (sign == fn.sign) {
            si = 1;
        }
        else {
            si = -1;
        }

        return frac_t(si, iport * fn.iport, 0, 1)
            + frac_t(si, 0, iport * fn.numer, fn.deno)
            + frac_t(si, 0, fn.iport * numer, deno)
            + frac_t(si, 0, numer * fn.numer, deno * fn.deno);
    }

    frac_t operator/ (const frac_t& fn)const {
        int si = sign;
        if (sign == fn.sign) {
            si = 1;
        }
        else {
            si = -1;
        }

        return frac_t(si, 0, (iport * deno + numer) * fn.deno,
            (fn.iport * fn.deno + fn.numer) * deno);
    }
}frac_t;

int main(void)
{
    long n1, d1, n2, d2;
    int s1, s2;
    (void)scanf("%ld/%ld", &n1, &d1);
    (void)scanf("%ld/%ld", &n2, &d2);
    if (n1 < 0) {
        n1 = -n1;
        s1 = -1;
    }
    else {
        s1 = 1;
    }
    if (n2 < 0) {
        n2 = -n2;
        s2 = -1;
    }
    else {
        s2 = 1;
    }

    frac_t fn1(s1, 0, n1, d1);
    frac_t fn2(s2, 0, n2, d2);
    (void)printf("%s + %s = %s\n", fn1.outform, fn2.outform, (fn1 + fn2).outform);
    (void)printf("%s - %s = %s\n", fn1.outform, fn2.outform, (fn1 - fn2).outform);
    (void)printf("%s * %s = %s\n", fn1.outform, fn2.outform, (fn1 * fn2).outform);
    (void)printf("%s / %s = %s", fn1.outform, fn2.outform, (fn1 / fn2).outform);

    return 0;
}
	


编辑于 2021-05-04 20:12:58 回复(0)
原来每个人都100行左右呀
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            
            String l = sc.next();
            String r = sc.next();
            
            int lLine = findLine(l);
            int rLine = findLine(r);
            
            Fraction fl = new Fraction(getMolecular(l,lLine),getDenominator(l,lLine));
            Fraction fr = new Fraction(getMolecular(r,rLine),getDenominator(r,rLine));
            
            add(fl,fr);
            
            sub(fl,fr);
            
            mul(fl,fr);
            
            div(fl,fr);
        }
    }
    
    private static void div(Fraction l,Fraction r){
        if(r.up == 0){
            print(l,r,0,0,'/',true);
        }else{
            mul(l,r.down,r.up,'/');
        }
    }
    
    private static void mul(Fraction l,Fraction r){
        mul(l,r.up,r.down,'*');
    }
    
    private static void mul(Fraction l,long rUp,long rDown,char ch){
        long down = l.down * rDown;
        long up = l.up * rUp;
        if(down < 0){
            down *= -1;
            up *= -1;
        }
        if(ch == '/'){
            long temp = rUp;
            rUp = rDown;
            rDown = temp;
        }
        print(l,new Fraction(rUp,rDown),up,down,ch,false);
    }
    
    private static void sub(Fraction l,Fraction r){
        add(l,r,-1);
    }
    
    private static void add(Fraction l,Fraction r){
        add(l,r,1);
    }
    
    private static void add(Fraction l,Fraction r,int n){
        long down = l.down * r.down;
        long up = l.up * r.down + (r.up * l.down) * n;
        print(l,r,up,down,n == 1 ? '+' : '-',false);
    }
    
    private static void print(Fraction l,Fraction r,long up,long down,char ch,boolean isInf){
        System.out.println(doSimple(l.up,l.down)+" "+ch+" "+doSimple(r.up,r.down)+" = "+(isInf ? "Inf" : doSimple(up,down)));
    }
    
    private static String doSimple(long up,long down){
        if(up == 0){
            return "0";
        }
        if(up % down == 0){
            long temp = up / down;
            return temp > 0 ? temp + "" : "("+temp+')';
        }
        boolean isNeg = false;
        if(up < 0){
            up *= -1;
            isNeg = true;
        }
        long common = maxCommon(up,down);
        if(common != -1){
            up /= common;
            down /= common;
        }
        if(up > down){
            long temp = up / down;
            up %= down;
            if(isNeg){
                return "(-"+temp+" "+up+'/'+down+')';
            }
            return temp+" "+up+'/'+down;
        }
        if(isNeg){
            return "(-"+up+'/'+down+')';
        }
        return up + "/" + down;
    }
    
    private static long maxCommon(long up,long down){
        long common = -1;
        if(up > down){
            long temp = up;
            up = down;
            down = temp;
        }
        for(long i = up;i >1;i--){
            if(down % i == 0 && up % i == 0){
                common = i;
                break;
            }
        }
        return common;
    }
    
    private static class Fraction{
        private long up;
        private long down;
        public Fraction(long up,long down){
            this.up = up;
            this.down = down;
        }
    }
    
    private static int findLine(String str) {
        int i = 0;
        for(;i < str.length();i++){
            if(str.charAt(i) == '/'){
                break;
            }
        }
        return i;
    }
    private static long getMolecular(String str,int index){
        int molecular = 0;
        for(int i = index - 1;i >= 0;i--){
            char ch = str.charAt(i);
            if(ch >= '0' && ch <= '9'){
                molecular = molecular * 10 + (ch - '0');
            }else{
                if(ch == '-'){
                    molecular *= -1;
                }
                break;
            }
        }
        return molecular;
    }
    private static long getDenominator(String str,int index){
        int denominator = 0;
        for(int i = index + 1;i < str.length();i++){
            char ch = str.charAt(i);
            if(ch >= '0' && ch <= '9'){
                denominator = denominator * 10 + (ch - '0');
            }else{
                break;
            }
        }
        return denominator;
    }
}


发表于 2022-05-15 15:42:32 回复(0)
#include <iostream>
#include <algorithm>
//long long是两个关键字拼起来的,用起来很不方便,重命名一下
typedef long long ll;
//有理数类的声明
class RationalNumber
{
    bool m_infinate; //处理除数为零
    bool m_negative; //处理负数
    
    ll m_numerator; //分子,方便输出
    ll m_denominator; //分母
    ll m_integer; //整数部分
    ll m_numeratorAll; //记录无整数分数的分子,方便进行运算
    
    ll calcGCD(ll a, ll b); //求最大公约数的函数
public:
    //构造函数
    RationalNumber(ll numerator, ll denominator);
    //四则运算重载
    RationalNumber operator+(RationalNumber const& o) const;
    RationalNumber operator-(RationalNumber const& o) const;
    RationalNumber operator*(RationalNumber const& o) const;
    RationalNumber operator/(RationalNumber const& o) const;
    //输出流运算符重载
    friend std::ostream &operator<<(std::ostream &os, RationalNumber const& o);
};
//有理数类每个方法的实现
ll RationalNumber::calcGCD(ll a, ll b){
    if (b == 0){
        return a;
    }
    //辗转相除法
    return calcGCD(b, a % b);
}
RationalNumber::RationalNumber(ll numerator, ll denominator){
    m_negative = false;
    m_infinate = false;
    //处理分母为零的情况
    if (denominator == 0){
        m_infinate = true;
        return;
    }
    //这里这样写,是因为在通过计算结果进行构造过程中,有可能出现分子分母均为负的情况。
    if (numerator < 0){
        m_negative = !m_negative;
    }
    if (denominator < 0){
        m_negative = !m_negative;
    }
    //计算整数、分子、分母。其中分母要参与下面的运算,所以不能是负的,用abs取绝对值,分子要保留 原值
    m_integer = numerator / denominator;
    m_numerator = numerator - m_integer * denominator;
    m_denominator = abs(denominator);
    //约分,注意传给子函数的分子必须是正的,分母上面处理过了
    if (m_numerator){
        ll maxtmp = calcGCD(abs(m_numerator), m_denominator);
        if (maxtmp){
            m_numerator /= maxtmp; m_denominator /= maxtmp;
        }
    }
    //计算约分后假分数版的分子,因为后续运算是不需要整数部分的,所以必须用假分数的分子算。
    m_numeratorAll = m_numerator + m_integer * m_denominator;
}
//以下为分数的加减乘除,统统使用m_numeratorAll(假分数的分子)进行运算。
RationalNumber RationalNumber::operator+(RationalNumber const& o) const {
    ll numerator = (m_numeratorAll * o.m_denominator) + (o.m_numeratorAll * m_denominator);
    ll denominator = m_denominator * o.m_denominator;
    return RationalNumber(numerator, denominator);
}
RationalNumber RationalNumber::operator-(RationalNumber const& o) const {
    ll numerator = (m_numeratorAll * o.m_denominator) - (o.m_numeratorAll * m_denominator);
    ll denominator = m_denominator * o.m_denominator;
    return RationalNumber(numerator, denominator);
}
RationalNumber RationalNumber::operator*(RationalNumber const& o) const {
    ll numerator = m_numeratorAll * o.m_numeratorAll;
    ll denominator = m_denominator * o.m_denominator;
    return RationalNumber(numerator, denominator);
}
RationalNumber RationalNumber::operator/(RationalNumber const& o) const {
    ll numerator = m_numeratorAll * o.m_denominator;
    ll denominator = m_denominator * o.m_numeratorAll;
    return RationalNumber(numerator, denominator);
}
std::ostream &operator<<(std::ostream &os, RationalNumber const& o){
    //分母为0的情况就不用继续了
    if (o.m_infinate){
        os << "Inf"; return os;
    }
    //整数和分子为0那干脆就是0了
    if (o.m_numerator == 0 && o.m_integer == 0){
        os << "0"; return os;
    }
    //负数打印括号和负号
    if (o.m_negative){
        os << "(-";
    }
    //有整数就打整数
    if (o.m_integer){
        os << abs(o.m_integer);
        if (o.m_numerator) //整数小数都有就打个空格隔开
        { os << " "; }
    }
    //有分数就打分数,分母已经abs过了,这里可以不用
    if (o.m_numerator){
        os << abs(o.m_numerator) << '/' << o.m_denominator;
    }
    //负数的后半边括号
    if (o.m_negative){
        os << ")";
    }
    return os;
}
int main(){
    ll n1, d1, n2, d2;
    scanf("%lld/%lld %lld/%lld", &n1, &d1, &n2, &d2);
    RationalNumber rn1(n1, d1), rn2(n2, d2); //轻松+愉快的使用函数时间
    std::cout << rn1 << " + " << rn2 << " = " << rn1 + rn2 << '\n';
    std::cout << rn1 << " - " << rn2 << " = " << rn1 - rn2 << '\n';
    std::cout << rn1 << " * " << rn2 << " = " << rn1 * rn2 << '\n';
    std::cout << rn1 << " / " << rn2 << " = " << rn1 / rn2 << '\n';
    return 0;
}

发表于 2020-09-04 13:13:49 回复(0)
这个题我写复杂了。。。。。。。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
string convert(int fenzi,int fenmu) {
 string s;
 bool isSub = false;
 if (fenzi == 0) {
  s = "0";
 }
 else if (fenzi<0) {
  fenzi *= -1;//变为正数
  s.insert(s.size(), "(-");
  if (fenmu == 1) {
   s.insert(s.size(), to_string(fenzi));
  }
  else {
   if (fenzi / fenmu != 0) {//整数部分
    s.insert(s.size(), to_string(fenzi / fenmu));
    s.insert(s.size(), " ");
   }
   s.insert(s.size(), to_string(fenzi % fenmu));
   s.insert(s.size(), "/");
   s.insert(s.size(), to_string(fenmu));
  }
  s.insert(s.size(), ")");
 }
 else {
  if (fenmu == 1) {
   s.insert(s.size(), to_string(fenzi));
  }
  else {
   if (fenzi / fenmu != 0) {//整数部分
    s.insert(s.size(), to_string(fenzi / fenmu));
    s.insert(s.size(), " ");
   }
   s.insert(s.size(), to_string(fenzi % fenmu));
   s.insert(s.size(), "/");
   s.insert(s.size(), to_string(fenmu));
  }
 }
 return s;
}
void getfzfm(string s1,int& fenzi,int& fenmu) {
 int index = s1.find("/");//一定能找到
 string tmp1 = s1.substr(0, index);
 string tmp2 = s1.substr(index + 1);
 bool isSub1 = false;
 if (tmp1[0] == '-') {
  isSub1 = true;
  tmp1.erase(0, 1);
 }
 fenzi = stoi(tmp1, 0, 10);
 fenmu = stoi(tmp2, 0, 10);
 if (isSub1) {
  fenzi *= -1;
 }
}
void simplify(int& fenzi,int& fenmu) {
 int mmin = min(abs(fenzi), fenmu);//这里分子为正数,化简不用考虑
 for (int i = 2; i <= mmin; i++) {
  if (fenzi % i == 0 && fenmu % i == 0) {
   fenzi /= i;
   fenmu /= i;
   i--;//i不变
  }
 }
}
int main() {
 string s1, s2;
 cin >> s1 >> s2;
 int numerator1, numerator2, denominator1, denominator2;
 //第一个数
 getfzfm(s1,numerator1,denominator1);
 simplify(numerator1, denominator1);
 s1 =convert(numerator1, denominator1);
 //第二个数
 getfzfm(s2, numerator2, denominator2);
 simplify(numerator2, denominator2);
 s2 = convert(numerator2, denominator2);
 //加法
 int ansfenzi, ansfenmu;
 string answer;
 ansfenzi = numerator1 * denominator2 + numerator2 * denominator1;
 ansfenmu = denominator1 * denominator2;
 simplify(ansfenzi,ansfenmu);
 answer=convert(ansfenzi, ansfenmu);
 cout << s1 << " + " << s2<<" = "<<answer<<'\n';
 //减法
 ansfenzi = numerator1 * denominator2 - numerator2 * denominator1;
 ansfenmu = denominator1 * denominator2;
 simplify(ansfenzi, ansfenmu);
 answer = convert(ansfenzi, ansfenmu);
 cout << s1 << " - " << s2 << " = " << answer<<'\n';
 //乘法
 ansfenzi = numerator1 * numerator2;
 ansfenmu = denominator1 * denominator2;
 simplify(ansfenzi, ansfenmu);
 answer = convert(ansfenzi, ansfenmu);
 cout << s1 << " * " << s2 << " = " << answer<<'\n';
 //除法,1.注意0,2.注意分子分母符号,3.化简分式的时候要注意如果分子为负数,化简不了,要取个绝对值,前面化简也要这样取绝对值
 if (numerator2 == 0) {
  cout << s1 << " / " << s2 << " = " << "Inf" << '\n';
 }
 else {
  ansfenzi = numerator1 * denominator2;
  ansfenmu = denominator1 * numerator2;
  if (ansfenmu < 0) {//将符号移到分子上面去,以对应我写的convert函数
   ansfenzi *= -1;
   ansfenmu *= -1;
  }
  simplify(ansfenzi, ansfenmu);
  answer = convert(ansfenzi, ansfenmu);
  cout << s1 << " / " << s2 << " = " << answer << '\n';
 }
}


编辑于 2020-04-01 12:50:17 回复(1)
#include <iostream>
#include <sstream>
#include <cmath>
using namespace std;

long long gcd(long long a, long long b) {
    return b == 0 ? a : gcd(b, a%b);
}
class Fraction
{
public:
    Fraction(long long num, long long den) :a(num), b(den) {
        long long t;
        if (a == 0) t = b;
        else t = gcd(abs(a), b);
        a /= t; b /= t;
    };

    ~Fraction() {};

    const Fraction operator+(const Fraction& that) const {
        return Fraction(this->a*that.b + this->b*that.a,
            this->b*that.b);
    };
    const Fraction operator-(const Fraction& that) const {
        return Fraction(this->a*that.b - this->b*that.a,
            this->b*that.b);
    }
    const Fraction operator*(const Fraction& that) const {
        return Fraction(this->a*that.a, this->b*that.b);
    }
    const Fraction operator/(const Fraction& that) const {
        if (this->b*that.a < 0) return Fraction(-this->a*that.b, -this->b*that.a);
        else return Fraction(this->a*that.b, this->b*that.a);
    }
    friend ostream& operator<<(ostream& os, const Fraction& obj);
private:
    long long a, b;
};

ostream& operator<<(ostream& os, const Fraction& obj) {
    if (obj.b == 0) { os << "Inf";return os; }
    if (obj.a < 0) os << "(";
    if (obj.b == 1) os << obj.a;
    else if (abs(obj.a) > obj.b) {
        os << obj.a / obj.b << " " << abs(obj.a)%obj.b << "/" << obj.b;
    }
    else os << obj.a << "/" << obj.b;
    if (obj.a < 0) os << ")";
    return os;
}

int main()
{
    long long a, b, c, d;
    scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
    Fraction p(a, b), q(c, d);
    cout << p << " + " << q << " = " << p + q << endl;
    cout << p << " - " << q << " = " << p - q << endl;
    cout << p << " * " << q << " = " << p * q << endl;
    cout << p << " / " << q << " = " << p / q << endl;

    system("pause");
    return 0;
}

发表于 2018-07-29 18:29:18 回复(0)
#include<cstdio>
struct rational{
	long long up,down;
};
long long gcd(long long a,long long b){
	return b==0?a:gcd(b,a%b);
}
rational add(rational a,rational b){
	rational c;
	c.down=a.down*b.down;
	c.up=a.up*b.down+b.up*a.down;
	return c;
}
rational minus(rational a,rational b){
	rational c;
	c.down=a.down*b.down;
	c.up=a.up*b.down-b.up*a.down;
	return c;
}
rational multiply(rational a,rational b){
	rational c;
	c.down=a.down*b.down;
	c.up=a.up*b.up;
	return c;
}
rational divide(rational a,rational b){
	rational c;
	c.down=a.down*b.up;
	c.up=a.up*b.down;
	return c;
}
void show(rational a){
	bool flag=false;
	long long x,y,z=0;
	x=a.up,y=a.down;
	if(y<0)y=-y,x=-x;
	if(y==0){
		printf("Inf");
		return;
	}
	else if(x==0){
		printf("0");
		return;
	}
	else{
		if(x<0){
			flag=true;
			x=-x;
		}
		if(flag)printf("(-");
		long long temp=gcd(x,y);
		x/=temp,y/=temp;
		z=x/y,x=x%y;
		if(z>0)printf("%lld",z);
		if(z>0&&x!=0)printf(" ");//注意空格问题
		if(x!=0)printf("%lld/%lld",x,y);
		if(flag)printf(")");
		return;
	}
}
int main(){
	//freopen("A1088.txt","r",stdin);
	rational a,b;
	scanf("%lld/%lld %lld/%lld",&a.up,&a.down,&b.up,&b.down);
	show(a);printf(" + ");show(b);printf(" = ");show(add(a,b));printf("\n");
	show(a);printf(" - ");show(b);printf(" = ");show(minus(a,b));printf("\n");
	show(a);printf(" * ");show(b);printf(" = ");show(multiply(a,b));printf("\n");
	show(a);printf(" / ");show(b);printf(" = ");show(divide(a,b));printf("\n");
	return 0;
}
//input
-1/2 2/4
//output
(-1/2) + 1/2 = 0
(-1/2) - 1/2 = (-1)
(-1/2) * 1/2 = (-1/4)
(-1/2) / 1/2 = (-1)

发表于 2017-08-21 17:01:30 回复(0)
#include <iostream>
#include <math.h>
using namespace std;
struct fraction{                                            //分数
    long long up,down;
};
long long gcd(long long a,long long b){                     //求最大公约数
    if(b==0) return a;
    else return gcd(b,a%b);
}
fraction reduction(fraction result){                        //化简
    if(result.down<0){                                      //使分母非负
        result.up=-result.up;
        result.down=-result.down;
    }
    if(result.up==0) result.down=1;
    else{
        long long d=gcd(abs(result.up),abs(result.down));   //约分
        result.up/=d;result.down/=d;
    }
    return result;
}
fraction add(fraction a,fraction b){                        //分数加法运算
    fraction result;
    result.up=a.up*b.down+b.up*a.down;
    result.down=a.down*b.down;
    return result;
}
fraction minu(fraction a,fraction b){
    fraction result;
    result.up=a.up*b.down-b.up*a.down;
    result.down=a.down*b.down;
    return result;
}
fraction multi(fraction a,fraction b){
    fraction result;
    result.up=a.up*b.up;
    result.down=a.down*b.down;
    return result;
}
fraction divide(fraction a,fraction b){
    fraction result;
    result.up=a.up*b.down;
    result.down=a.down*b.up;
    return result;
}
void printresult(fraction a){                               //输出
    a=reduction(a);
    if(a.up<0) cout<<"(";
    if(a.down==1) cout<<a.up;  //整数                        
    else if(abs(a.up)>a.down)  //假分数化为带分数
        cout<<a.up/a.down<<" "<<abs(a.up)%a.down<<"/"<<a.down;
    else cout<<a.up<<"/"<<a.down; //真分数
    if(a.up<0) cout<<")";
}
int main(){
    fraction a,b;
    scanf("%lld/%lld %lld/%lld",&a.up,&a.down,&b.up,&b.down);
    printresult(a);cout<<" + ";printresult(b);cout<<" = ";printresult(add(a,b));cout<<'\n';
    printresult(a);cout<<" - ";printresult(b);cout<<" = ";printresult(minu(a,b));cout<<'\n';
    printresult(a);cout<<" * ";printresult(b);cout<<" = ";printresult(multi(a,b));cout<<'\n';
    printresult(a);cout<<" / ";printresult(b);cout<<" = ";
    if(b.up==0) cout<<"Inf"<<'\n';
    else{printresult(divide(a,b));cout<<'\n';}    
    return 0;
}

发表于 2018-02-18 19:50:56 回复(2)
import java.util.Scanner;

public class Main {
    static void pr(long a, long b) {
        long x = gcd(a, b);
        a /= x;
        b /= x;
        if (b < 0) {
            a *= -1;
            b *= -1;
        }
        if (a < 0) {
            if (-a % b == 0) {
                System.out.print("(" + a / b + ")");
            } else if (-a < b) {
                System.out.print("("+a + "/" + b+")");
            } else {
                System.out.print("(" + a / b + " " + (-a + (b * (a / b))) + "/" + b + ")");
            }
        } else {
            if (a % b == 0) {
                System.out.print(a / b);
            } else if (a < b) {
                System.out.print(a + "/" + b);
            } else {
                System.out.print(a / b + " " + (a - (b * (a / b))) + "/" + b );
            }
        }
    }
    static long  gcd(long a, long b) { //辗转相除法求最大公约数
        if (b == 0) {
            return a;
        }
        long r = a % b;
        return gcd(b, r);
    }
    static void add(long a, long b, long c, long d) {
        pr(a, b);
        System.out.print(" + ");
        pr(c, d);
        System.out.print(" = ");
        pr(a * d + b * c, b * d);
    }
    static void minus(long a, long b, long c, long d) {
        pr(a, b);
        System.out.print(" - ");
        pr(c, d);
        System.out.print(" = ");
        pr(a * d - b * c, b * d);
    }
    static void multiply(long a, long b, long c, long d) {
        pr(a, b);
        System.out.print(" * ");
        pr(c, d);
        System.out.print(" = ");
        pr(a * c, b * d);
    }
    static void division(long a, long b, long c, long d) {
        long m = a * d;
        long n = b * c;
        pr(a, b);
        System.out.print(" / ");
        pr(c, d);
        System.out.print(" = ");
        if (c == 0) {
            System.out.print("Inf");
        } else {
            if (n < 0) {
                m = m * -1; //把负号调整到分子上
                n = n * -1;
            }
            pr(m, n);
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.nextLine();
            String[] split = s.split(" ");
            String[] s1 = split[0].split("/");
            String[] s2 = split[1].split("/");
            long a = Long.parseLong(s1[0]);
            long b = Long.parseLong(s1[1]);
            long c = Long.parseLong(s2[0]);
            long d = Long.parseLong(s2[1]);
            add(a, b, c, d);
            System.out.println();
            minus(a, b, c, d);
            System.out.println();
            multiply(a, b, c, d);
            System.out.println();
            division(a, b, c, d);
        }
    }
}
编辑于 2023-03-18 23:00:59 回复(0)
#include <iostream>
using namespace std;

void parser(string& s, int& a, int& b) {
    bool symbol = true;
    int i = 0;
    if (s[i] == '-') {
        symbol = false;
        i++;
    }
    while (s[i] != '/') {
        a = a * 10 + s[i] - '0';
        i++;
    }
    while (s[++i] != '/') {
        b = b * 10 + s[i] - '0';
    }
    a *= symbol ? 1 : -1;
}

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
    return a * b / gcd(a, b);
}

void FormatPrint(int n, int d) {
    if (d == 0) {
        cout << "Inf";
        return;
    }
    if (n == 0) {
        cout << "0 ";
        return;
    }
    bool flag = false;
    if (n < 0) {
        cout << "(-";
        n = -n;
        flag = true;
    }
    int g = gcd(n % d, d);
    if (n / d) {
        cout << n / d;
        if (n % d / g) cout << " " << n % d / g << "/" << d / g;
    } else {
        if (n % d / g) cout << n % d / g << "/" << d / g;
    }

    if (flag) cout << ") ";
    else cout << " ";
}

void calc(int n1, int d1, int n2, int d2, char op) {
    int n, d;
    if (n1 && n2) {
        d = lcm(d1, d2);
        switch (op) {
            case '+':
                n = d / d1 * n1 + d / d2 * n2;
                break;
            case '-':
                n = d / d1 * n1 - d / d2 * n2;
                break;
            case '*':
                d = d1 * d2;
                n = n1 * n2;
                break;
            case '/':
                d = d1 * n2;
                n = d2 * n1;
                if (d < 0 && n > 0) {
                    d = -d;
                    n = -n;
                }
                break;
        }

    } else if (n1 || n2) {
        d = n1 ? d1 : d2;
        switch (op) {
            case '+':
                n = n1 + n2;
                break;
            case '-':
                n = n1 + n2;
                n *= n1 ? 1 : -1;
                break;
            case '*':
                n = 0;
                break;
            case '/':
                n = 0;
                if (n2 == 0) d = 0;
        }
    } else {
        n = 0;
    }
    FormatPrint(n1, d1);
    cout << op << " ";
    FormatPrint(n2, d2);
    cout << "= ";
    FormatPrint(n, d);
    cout << endl;
}

void compute(string& s1, string& s2) {
    int n1 = 0, d1 = 0, n2 = 0, d2 = 0;
    parser(s1, n1, d1);
    parser(s2, n2, d2);

    calc(n1, d1, n2, d2, '+');
    calc(n1, d1, n2, d2, '-');
    calc(n1, d1, n2, d2, '*');
    calc(n1, d1, n2, d2, '/');
}

int main() {
    string s1, s2;
    while (cin >> s1 >> s2) {
        s1 += '/';
        s2 += '/';
        compute(s1, s2);
    }
    return 0;
}

发表于 2023-08-29 13:04:02 回复(0)
大家好像都挺长的,主要是输出格式要求的一些字符分析清楚出现条件,然后顺序输出就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll aa, ab, ba, bb;

vector<ll> format(ll a, ll b)
{
    if (b == 0)
    {
        vector<ll> ans({0, 0, 0, 0});
        return ans;
    }
    ll gcd = __gcd(a, b);
    a /= gcd;
    b /= gcd;
    if (a == 0)
        b = 1;
    else if (a < 0)
    {
        a = -a;
        b = -b;
    }

    vector<ll> ans({abs(a / b), (a % abs(b)), b});
    return ans;
}

string output(vector<ll> f)
{
    string ans;
    if (f[2] == 0)
        return "Inf";
    if (f[0] || f[1] == 0)
    {
        ans += to_string(f[0]);
    }
    if (f[0] && f[1])
        ans += ' ';
    if (f[1])
    {
        ans += to_string(f[1]) + "/" + to_string(abs(f[2]));
    }
    if (f[2] < 0)
        return "(-" + ans + ")";
    return ans;
}

int main()
{
    // 打竞赛不敢同时用cstdio和iostream,但这里就可以摸一下鱼
    scanf("%lld/%lld %lld/%lld", &aa, &ab, &ba, &bb);
    string a = output(format(aa, ab)), b = output(format(ba, bb));
    cout << a << " + " << b << " = " << output(format(aa * bb + ab * ba, ab * bb)) << endl;
    cout << a << " - " << b << " = " << output(format(aa * bb - ab * ba, ab * bb)) << endl;
    cout << a << " * " << b << " = " << output(format(aa * ba, ab * bb)) << endl;
    cout << a << " / " << b << " = " << output(format(aa * bb, ab * ba)) << endl;
    return 0;
}


发表于 2022-11-21 20:31:06 回复(0)
public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String str1 = in.next();
            String str2 = in.next();
            long a1 = Long.parseLong(str1.split("/")[0]);
            long b1 = Long.parseLong(str1.split("/")[1]);
            long a2 = Long.parseLong(str2.split("/")[0]);
            long b2 = Long.parseLong(str2.split("/")[1]);
            System.out.println(sum(a1, b1, a2, b2));
            System.out.println(sub(a1, b1, a2, b2));
            System.out.println(mul(a1, b1, a2, b2));
            System.out.println(div(a1, b1, a2, b2));
        }
    }
    public static boolean isZero(long a) {
        if (a == 0) {
            return true;
        }
        return false;
    }
    public static boolean isPositive(long a) {
        if (a > 0) {
            return true;
        }
        return false;
    }
    public static String finalNum(long a, long b) {
        if (a == 0) {
            return "0";
        }
        long integer = a / b;
        StringBuilder sb = new StringBuilder();
        if (integer != 0) {
            if ((isPositive(a) && isPositive(b))) {
                sb.append(integer);
                long maxNum = maxNum(a, b);
                if (maxNum != b) {
                    sb.append(" ");
                    sb.append((a - b * integer) / maxNum);
                    sb.append("/");
                    sb.append(b / maxNum);
                }
            } else if ((!isPositive(a) && isPositive(b))) {
                sb.append("(");
                sb.append(integer);
                long maxNum = maxNum(-a, b);
                if (maxNum != b) {
                    sb.append(" ");
                    sb.append(-(a + b * (-integer)) / maxNum);
                    sb.append("/");
                    sb.append(b / maxNum);
                }
                sb.append(")");
            } else if ((isPositive(a) && !isPositive(b))) {
                sb.append("(");
                sb.append(integer);
                long maxNum = maxNum(a, -b);
                if (maxNum != -b) {
                    sb.append(" ");
                    sb.append((a - b * integer) / maxNum);
                    sb.append("/");
                    sb.append(-b / maxNum);
                }
                sb.append(")");
            } else if ((!isPositive(a) && !isPositive(b))) {
                sb.append(integer);
                long maxNum = maxNum(-a, -b);
                if (maxNum != -b) {
                    sb.append(" ");
                    sb.append((-a + b * integer) / maxNum);
                    sb.append("/");
                    sb.append(-b / maxNum);
                }
            }
        } else {
            if ((isPositive(a) && isPositive(b))) {
                long maxNum = maxNum(a, b);
                if (maxNum != b) {
                    sb.append(a / maxNum);
                    sb.append("/");
                    sb.append(b / maxNum);
                }
            } else if ((!isPositive(a) && isPositive(b))) {
                sb.append("(");
                long maxNum = maxNum(-a, b);
                if (maxNum != b) {
                    sb.append(a / maxNum);
                    sb.append("/");
                    sb.append(b / maxNum);
                }
                sb.append(")");
            } else if ((isPositive(a) && !isPositive(b))) {
                sb.append("(");
                long maxNum = maxNum(a, -b);
                if (maxNum != -b) {
                    sb.append(-(a ) / maxNum);
                    sb.append("/");
                    sb.append(-b / maxNum);
                }
                sb.append(")");
            } else if ((!isPositive(a) && !isPositive(b))) {
                long maxNum = maxNum(-a, -b);
                if (maxNum != -b) {
                    sb.append((-a ) / maxNum);
                    sb.append("/");
                    sb.append(-b / maxNum);
                }
            }
        }
        return sb.toString();
    }
    /**
     * 最大公约数
     *
     * @return
     */
    public static long maxNum(long a, long b) {
        while (b != 0) {
            long tmp = a;
            a = b;
            b = tmp % b;
        }
        return a;
    }
    public static String sum(long a1, long b1, long a2, long b2) {
        if (isZero(a2)) {
            return finalNum(a1, b1) + " + " + finalNum(a2, b2) + " = " + finalNum(a1, b1);
        } else {
            long newA1 = a1 * b2;
            long newB = b1 * b2;
            long newA2 = a2 * b1;
            return finalNum(a1, b1) + " + " + finalNum(a2, b2) + " = " + finalNum(newA1 + newA2, newB);
        }
    }
    public static String sub(long a1, long b1, long a2, long b2) {
        if (isZero(a2)) {
            return finalNum(a1, b1) + " - " + finalNum(a2, b2) + " = " + finalNum(a1, b1);
        } else {
            long newA1 = a1 * b2;
            long newB = b1 * b2;
            long newA2 = a2 * b1;
            return finalNum(a1, b1) + " - " + finalNum(a2, b2) + " = " + finalNum(newA1 - newA2, newB);
        }
    }
    public static String mul(long a1, long b1, long a2, long b2) {
        if (isZero(a2)) {
            return finalNum(a1, b1) + " * " + finalNum(a2, b2) + " = " + 0;
        } else {
            long newA = a1 * a2;
            long newB = b1 * b2;
            return finalNum(a1, b1) + " * " + finalNum(a2, b2) + " = " + finalNum(newA, newB);
        }
    }
    public static String div(long a1, long b1, long a2, long b2) {
        if (isZero(a2)) {
            return finalNum(a1, b1) + " / " + finalNum(a2, b2) + " = " + "Inf";
        } else {
            long newA = a1 * b2;
            long newB = b1 * a2;
            return finalNum(a1, b1) + " / " + finalNum(a2, b2) + " = " + finalNum(newA, newB);
        }
    }
发表于 2023-07-30 11:48:59 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str1 = in.next();
            String str2 = in.next();
            String[] s1 = str1.split("/");
            String[] s2 = str2.split("/");
            int num1 = Integer.parseInt(s1[0]) * Integer.parseInt(s2[1]);
            int demo1 = Integer.parseInt(s1[1]) * Integer.parseInt(s2[1]);
            int num2 = Integer.parseInt(s2[0]) * Integer.parseInt(s1[1]);
            int demo2 = Integer.parseInt(s2[1]) * Integer.parseInt(s1[1]);
            String befor = func(num1, demo1);
            String after = func(num2, demo2);
            System.out.println(befor + " + " + after + " = " + func(num1 + num2, demo1));
            System.out.println(befor + " - " + after + " = " + func(num1 - num2, demo1));
            System.out.println(befor + " * " + after + " = " + func(num1 * num2,
                               demo1 * demo2));
            System.out.println(befor + " / " + after + " = " + func(num1 * demo2,
                                demo1 * num2));
        }
    }
    public static String func(int num, int demo) {
        if (num == 0) {
            return "0";
        }
        if (demo == 0) {
            return "Inf";
        }

        int coe = maxCoe(num, demo);
        num /= coe;
        demo /= coe;
        String ret = fake(num, demo);
        return ret;
    }
    public static int maxCoe(int num, int demo) {
        int i = num % demo;
        while (i != 0) {
            num = demo;
            demo = i;
            i = num % demo;
        }
        return demo;
    }
    public static String fake(int num, int demo) {
        boolean flag = true;
        if (demo == 0) {
            return "Inf";
        }
        if (num < 0) {
            flag = !flag;
            num *= (-1);
        }
        if (demo < 0) {
            flag = !flag;
            demo *= (-1);
        }
        String frac = "";
        if (num < demo) {
            frac = num + "/" + demo;
        } else if (num == demo) {
            frac = "1";
        } else {
            int inte = num / demo;
            num = num - inte * demo;
            if (num != 0) {
                frac = inte + " " + num + "/" + demo;
            } else {
                frac = inte + "";
            }
        }
        if (flag) {
            return frac;
        } else {
            return "(-" + frac + ")";
        }
    }
}

面向测试用例编程
发表于 2023-05-06 15:21:06 回复(0)
/*
输入描述:
    每个输入文件包含一个测试用例,在一行中以“a1/b1 a2/b2”格式给出两个有理数。
分子和分母都在长整数的范围内。如果有负号,它只能出现在
分子前面。分母保证是非零数。

输出描述:
    对于每个测试用例,分别在4行中打印两个有理数的和、差、积和商。每个的格式
行是“number1 operator number2=result”。注意,所有有理数都必须是最简单的形式“k a/b”,
其中k是整数部分,a/b是最简单的分数部分。如果数字为负数,则必须包含在一对括号中。如果
除法中的分母为零,输出“Inf”作为结果。保证所有输出整数都在长整数的范围内。
*/

#include<iostream>
using namespace std;
typedef long long int64;  //分子 分母都在长整数范围内

class Rational
{
public:
    Rational(int64 n,int64 d)
    {
        negetive = false;  //初始化为false
        isZero = false;
        
        //在输入时(输入要求中有)分母永远不可能为0,但是经过运算之后分母可能会小于0
        if(0 == d){
            isZero = true;
            return;
        }
        
        //分子小于0,表示为负数
        if(n < 0){
            negetive = !negetive;
        }
        
        //在输入时,分母一定不会小于0,但经过计算之后分母也可能会小于0
        if(d < 0){
            negetive = !negetive;
        }
        
        //如果分数是假分数,必须要将其化简为真分数例如5 / 3 --> 1 2/3
        integer = n / d;
        numerator = n - integer*d;
        denominator = abs(d);  //输出的结果中分母不为0
        
        //如果不是最简的分数,还需要将其化简为最简的分数 10 / 15 --> 2 / 3
        //方法:只需要给分子和分母除分子和分母的最大公约数
        if(numerator < -1 || numerator > 1){
            int gcd = CalcGCD(abs(numerator),denominator);
            if(gcd){  //如果最大公约数存在
                numerator /= gcd;
                denominator /= gcd;
            }
        }
        
        //运算时分子 = 整数部分*分母+化简后的真分数的分子
        totalnumerator = integer*denominator + numerator; 
    }
    
    //+运算符重载
    Rational operator+(const Rational& r)const
    {
        int64 n = totalnumerator*r.denominator + r.totalnumerator*denominator;
        int64 d = denominator*r.denominator;
        return Rational(n,d);
    }
    
    Rational operator-(const Rational& r)const
    {
        int64 n = totalnumerator*r.denominator - r.totalnumerator*denominator;
        int64 d = denominator*r.denominator;
        return Rational(n,d);
    }
    
    Rational operator*(const Rational& r)const
    {
        int64 n = totalnumerator*r.totalnumerator;
        int64 d = denominator*r.denominator;
        return Rational(n,d);
    }
    
    Rational operator/(const Rational& r)const
    {
        int64 n = totalnumerator*r.denominator;
        int64 d = denominator*r.totalnumerator;
        return Rational(n,d);
    }
    
    //输出流重载,且必须为友元函数
    friend ostream& operator<<(ostream& _cout,const Rational& r)
    {
        if(r.isZero){
            _cout << "Inf";
            return _cout;
        }
        
        if(0 == r.integer && 0 == r.numerator){
            _cout << "0";
            return _cout;
        }
        
        //如果是负数,需要用()括起来
        if(r.negetive){
            _cout << "(-";
        }
        
        //输出有理数:整数+分数
        if(r.integer){
            _cout << abs(r.integer);
            //如果分数部分存在,整数与分数部分之间有一个空格
            if(r.numerator){
                _cout << " ";
            }
        }
        
        //分数可能存在也可能不存在
        if(r.numerator){
            _cout << abs(r.numerator) << "/" << r.denominator;
        }
        
        if(r.negetive){
            _cout << ")";
        }
        return _cout;
    }
private:
    int64 CalcGCD(int64 a,int64 b)
    {
        if(b == 0){
            return a;
        }
        return CalcGCD(b,a%b);
    }
    
    
private:
    int64 numerator;  //分子
    int64 denominator;  //分母
    int64 integer;  //整数部分 例如5/3 --> 1 2/3,其中1就是整数部分
    bool negetive;  //负数
    bool isZero;   //分母是否为0
    int64 totalnumerator;  //参与运算的分子,原分子+整数部分
};

int main()
{
    int64 n1,d1,n2,d2; //n1第一个有理数的分子,d1第一个有理数的分母;n2第二个有理数的分子,d2第二个有理数的分母
    while(scanf("%lld/%lld %lld/%lld",&n1,&d1,&n2,&d2)!=EOF)
    {
        Rational r1(n1,d1);  //描述有理数的类Rational
        Rational r2(n2,d2);
        cout << r1 << " + " << r2 << " = " << r1 + r2 << endl; //此处需要输出流重载,+运算符重载
        cout << r1 << " - " << r2 << " = " << r1 - r2 << endl;
        cout << r1 << " * " << r2 << " = " << r1 * r2 << endl;
        cout << r1 << " / " << r2 << " = " << r1 / r2 << endl;
    }
    return 0;
}

发表于 2023-02-18 17:19:00 回复(0)
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

struct Fraction {
	LL up,down;
} ans1,ans2,ans3,ans4,x,y;

LL gcd(LL a,LL b) {
	return b==0?a:gcd(b,a%b);
}

Fraction reduction(Fraction a) {
	if(a.down<0) {
		a.up=-a.up;
		a.down=-a.down;
	}
	if(a.up==0) {
		a.down=1;
	} else {
		LL d=gcd(abs(a.up),a.down);
		a.up/=d;
		a.down/=d;
	}
	return a;
}

Fraction Add(Fraction a,Fraction b) {
	Fraction c;
	c.up=a.up*b.down+b.up*a.down;
	c.down=a.down*b.down;
	return reduction(c);
}

Fraction Sub(Fraction a,Fraction b) {
	Fraction c;
	c.up=a.up*b.down-b.up*a.down;
	c.down=a.down*b.down;
	return reduction(c);
}

Fraction Mul(Fraction a,Fraction b) {
	Fraction c;
	c.up=a.up*b.up;
	c.down=a.down*b.down;
	return reduction(c);
}

Fraction Div(Fraction a,Fraction b) {
	Fraction c;
	c.up=a.up*b.down;
	c.down=a.down*b.up;
	return reduction(c);
}

void Printf(Fraction a) {
	a=reduction(a);
	if(a.up<0) cout<<'(';
	if(a.down==1) {
		cout<<a.up;
	} else if(abs(a.up)>a.down) {
		cout<<a.up/a.down<<" "<<abs(a.up)%a.down<<'/'<<a.down;
	} else {
		cout<<a.up<<'/'<<a.down;
	}
	if(a.up<0) cout<<')';
}

int main() {
	scanf("%lld/%lld %lld/%lld",&x.up,&x.down,&y.up,&y.down);
	ans1=Add(x,y);
	ans2=Sub(x,y);
	ans3=Mul(x,y);
	Printf(x);cout<<" + ";Printf(y);cout<<" = ";Printf(ans1);cout<<endl;
    Printf(x);cout<<" - ";Printf(y);cout<<" = ";Printf(ans2);cout<<endl;
	Printf(x);cout<<" * ";Printf(y);cout<<" = ";Printf(ans3);cout<<endl;
	Printf(x);cout<<" / ";Printf(y);cout<<" = ";if(y.up==0) printf("Inf");else Printf(Div(x,y));
	return 0;
}

发表于 2022-11-16 16:31:50 回复(0)


import java.util.Scanner;

class Rational {
    private long numerator;//分子
    private long denominator;//分母
    private boolean negative;//是否是负数
    private long integer;//整数部分
    private  long total;//全部的分数部分 不包括小数

    public static long getNumerator(String ret) {//获取分子
        return Long.parseLong(ret.substring(0, ret.indexOf('/')));
    }

    public static long getDenominator(String ret) {//获取分母
        return Long.parseLong(ret.substring(ret.indexOf('/') + 1, ret.length()));
    }

    public Rational(long numerator, long denominator) {
        if (denominator == 0) {//如果分母为0
            return;
        }
        if (denominator < 0 || numerator < 0)
            negative = true;
        this.numerator = numerator;
        this.denominator = denominator;

        //分数化型
        this.integer = this.numerator / this.denominator;
        this.numerator = this.numerator % this.denominator;

        //分数化简
        //最大公因数 分子可能是负数 分母是正数 那么最大公因数是负数
        long ret = getCommonFactor(numerator, denominator);
        this.numerator /= ret;
        this.denominator /= ret;
        this.total = this.denominator * integer + this.numerator;
    }

    public Rational Add(Rational rational) {
        long num = this.total * rational.denominator + rational.total * this.denominator;
        long den = this.denominator * rational.denominator;
        return new Rational(num, den);
    }
    public Rational sub(Rational rational) {
        long num = this.total * rational.denominator - rational.total * this.denominator;
        long den = this.denominator * rational.denominator;
        return new Rational(num, den);
    }

    public Rational mul(Rational rational) {
        long num = this.total * rational.total;
        long den = this.denominator * rational.denominator;
        return new Rational(num, den);
    }

    public Rational div(Rational rational) {
        long n = this.total * rational.denominator;
        long d = this.denominator * rational.total;
        return new Rational(n,d);
    }
    private long getCommonFactor(long numerator, long denominator) {//获取最大公因数
        while (denominator != 0) {
            long mod = numerator % denominator;
            numerator = denominator;
            denominator = mod;
        }
        return numerator;
    }

    @Override
    public String toString() {
        if (denominator == 0) {//分母为0
            return "Inf";
        }

        StringBuilder builder = new StringBuilder();
        if (this.negative) {
            builder.append('(');
        }

        numerator=Math.abs(numerator);
        denominator=Math.abs(denominator);
        if (this.integer != 0) {//如果有整数部分
            builder.append(integer);
            if (!(this.numerator == 0)) {//如果分子不为0 也就是有分数
                builder.append(" " + numerator);
                builder.append("/");
                builder.append(denominator);
            }
        }
        if(this.integer==0){//如果没有整数
            if (!(this.numerator == 0)) {//如果分子不为0 也就是有分数
                if(this.negative)
                    builder.append("-");
                builder.append(numerator);
                builder.append("/");
                builder.append(denominator);
            }else {
                builder.append("0");
            }
        }
        if (this.negative) {
            builder.append(')');
        }
        return builder.toString();
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String ret = scanner.next();
            String des = scanner.next();
            //构造两个分数
            Rational r1 = new Rational(Rational.getNumerator(ret), Rational.getDenominator(ret));
            Rational r2 = new Rational(Rational.getNumerator(des), Rational.getDenominator(des));
            System.out.println(r1 + " " + "+" + " " + r2 + " = " + r1.Add(r2));
            System.out.println(r1 + " " + "-" + " " + r2 + " = " + r1.sub(r2));
            System.out.println(r1 + " " + "*" + " " + r2 + " = " + r1.mul(r2));
            System.out.println(r1 + " " + "/" + " " + r2 + " = " + r1.div(r2));
        }
    }
}


编辑于 2022-09-19 22:00:36 回复(0)
import java.util.*;
class Rational{
    private long numerator;// 分子
    private long denominator;// 分母
    private long integer;// 整数部分
    private boolean negetive;// 负数帕努单
    private boolean isZero;// 分母为零
    private long totalNumerator;// 最终参与运算的分子
    public static long paraseNumerator(String s){
        // 提取 分数的 分子
        return Long.parseLong(s.substring(0,s.indexOf('/')));
    }
    public static long paraseDenominator(String s){
        // 提取 分数的 分子
        return Long.parseLong(s.substring(s.indexOf('/')+1));
    }
    Rational(long n,long d){
        if(0 == d){
            isZero = true;
            return;
        }
        if(n < 0){
            negetive = true;
        }
        if(d < 0){
            negetive = !negetive;
        }
        // 如果输入的是假分数,需要将其调整为真分数,比如 5/3 == 1 2/3
        integer = n/d;
        numerator = n - integer * d;
        denominator = Math.abs(d);
        
        // 如果分数不是最简的形式,需要将其你约分为最简的形式,比如 10/15 == 2/3
        // 在分子和分母的基础之上,分别处以分子和分母的最大公约数
        if(numerator > 1 || numerator < -1){
            long gcd = calcGCD(Math.abs(numerator),denominator);
            if(gcd > 0){
                numerator /= gcd;
                denominator /= gcd;
            }
        }
        totalNumerator = numerator + integer * denominator;
    }
    private long calcGCD(long a,long b){
        if(b == 0){
            return a;
        }
        return calcGCD(b,a%b);
    }
    public Rational add(Rational r){
        long n = totalNumerator * r.denominator + denominator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new Rational(n,d);
    }
    public Rational sub(Rational r){
        long n = totalNumerator * r.denominator - denominator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new Rational(n,d);
    }
    public Rational mul(Rational r){
        long n = totalNumerator * r.totalNumerator;
        long d = denominator * r.denominator;
        return new Rational(n,d);
    }
    public Rational div(Rational r){
        long n = totalNumerator * r.denominator;
        long d = denominator * r.totalNumerator;
        return new Rational(n,d);
    }
    public String toString(){
        StringBuffer s = new StringBuffer();
        
        if(isZero){
            s.append("Inf");
        }else if(integer == 0 && numerator == 0){
            s.append("0");
            return new String(s);
        }
        else{
            if(negetive){
                s.append("(-");
            }
            if(0 != integer){
                s.append(Math.abs(integer));
                if(numerator != 0){
                    s.append(" ");
                }
            }
            if(0 != numerator){
                s.append(Math.abs(numerator));
                s.append('/');
                s.append(denominator);
            }
        }
        if(negetive){
            s.append(')');
        }
        return new String(s);
    }
}
public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s = sc.next();// 第一个分数
            Rational r1 = new Rational(Rational.paraseNumerator(s),Rational.paraseDenominator(s));
            s = sc.next();// 第一个分数
            Rational r2 = new Rational(Rational.paraseNumerator(s),Rational.paraseDenominator(s));
            System.out.println(r1 + " + " + r2 + " = " + r1.add(r2));
            System.out.println(r1 + " - " + r2 + " = " + r1.sub(r2));
            System.out.println(r1 + " * " + r2 + " = " + r1.mul(r2));
            System.out.println(r1 + " / " + r2 + " = " + r1.div(r2));
        }
        sc.close();
    }
}

发表于 2022-08-06 23:20:05 回复(0)

发表于 2022-05-14 16:40:12 回复(0)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,c,d;

ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}

void funs(ll m,ll n)
{
    if(m*n==0)
    {
        printf("%s",n==0?"Inf":"0");
        return;
    }
    bool f=((m<0&&n>0)||(m>0&&n<0));
    m=abs(m);
    n=abs(n);
    //整数部分
    ll x=m/n;
    printf("%s",f?"(-":"");
    if(x!=0)
        printf("%lld",x);
    if(m%n==0)
    {
        if(f)
            cout<<")";
        return;
    }
    if(x!=0)
        cout<<" ";
    m=m-x*n;
    ll t=gcd(m,n);
    m=m/t;
    n=n/t;
    printf("%lld/%lld%s",m,n,f?")":"");
}

int main()
{
    int i,j;
    scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);
    funs(a,b);
    cout<<" + ";
    funs(c,d);
    cout<<" = ";
    funs(a*d+b*c,b*d);

    cout<<endl;
    funs(a,b);
    cout<<" - ";
    funs(c,d);
    cout<<" = ";
    funs(a*d-b*c,b*d);

    cout<<endl;
    funs(a,b);
    cout<<" * ";
    funs(c,d);
    cout<<" = ";
    funs(a*c,b*d);

    cout<<endl;
    funs(a,b);
    cout<<" / ";
    funs(c,d);
    cout<<" = ";
    funs(a*d,b*c);
    return 0;
}


发表于 2021-08-13 15:08:57 回复(0)

想的简单,写得多

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
class Solution {
public:
    //对外接口
    void Calculate(vector<string>& n) {
        //划分数据
        int index = 0, idx = 0;
        Split(n[0], index, idx);
        idx = 0;
        Split(n[1], index, idx);
        //为避免两有理数被多次计算字符串,此处进行计算
        Head(num[0], num[1], n1);
        Head(num[2], num[3], n2);
        // +
        int s = num[0] * num[3] + num[2] * num[1];
        int p = num[1] * num[3];
        Show(s, p, '+');
        // -
        s = num[0] * num[3] - num[2] * num[1];
        Show(s, p, '-');
        // *
        s = num[0] * num[2];
        p = num[1] * num[3];
        Show(s, p, '*');
        // /
        s = num[0] * num[3];
        p = num[1] * num[2];
        if (p < 0 && s>0)//若分母为负数,交换负号
            s *= -1, p *= -1;
        Show(s, p, '/');
    }
    Solution() :num(4) {}
private:
    //更相减损术
    int GDC(int m1, int m2) {
        m1 *= m1 < 0 ? -1 : 1;
        m2 *= m2 < 0 ? -1 : 1;
        while (m1 != m2) {
            if (m1 > m2)
                m1 -= m2;
            else if (m1 < m2)
                m2 -= m1;
            else
                return m1;
        }
        return m1;
    }
    //格式控制及输出
    void Show(const int& s, const int& p, const char& sys) {
        string head;
        //拼接第一个有理数
        head += n1;
        head += ' ';
        head += sys;
        head += ' ';
        //拼接第二个有理数
        head += n2;
        head += " = ";
        //拼接结果
        if (!p)
            head += "Inf";
        else if (!s)
            head += '0';
        else
            Head(s, p, head);
        cout << head << endl;
    }
    //输出字符串拼接
    void Head(const int& s, const int& p, string& head) {
        if (s == 0) {
            head += '0';
        }
        else if (abs(s) > p) {//存在整数部分
            bool flag = s < 0;//负数为真
            if (flag)
                head += "(-";
            head += to_string(abs(s / p));//整数部分
            if (s/p*p != s) {//存在小数部分
                head += ' ';
                 CalFraction(s,p,head);
            }
            if (flag)
                head += ")";
        }
        else if (s == p)
            head += '1';
        else {//不存在整数部分
            bool flag = s < 0;//负数为真
            if (flag)
            head += "(-";
            CalFraction(s,p,head);
            if (flag)
                head += ")";
        }
    }
    //计算分数部分
    void CalFraction(const int& s,const int& p,string& head){
        int fac = GDC(abs(s) % p, p);//最大公因数
        head += to_string((abs(s) - abs(s) / p * p) / fac);
        head += '/';
        head += to_string(p / fac);
    }
    //数字切割
    void Split(string& n,int& index,int& idx) {
        int sys = n[0] == '-' ? -1 : 1;//正负判断
        idx += sys == -1 ? 1 : 0;//确定因符号引起的偏移
        int pos = n.find('/', idx);//找出完整数字
        for (int j = idx; j < pos; ++j)
            num[index] = num[index] * 10 + (n[j] - '0');
        num[index++] *= sys;
        idx = pos + 1;
        pos = n.size();
        for (int j = idx; j < pos; ++j)
            num[index] = num[index] * 10 + (n[j] - '0');
        ++index;
    }
private:
    vector<int> num;//[a1,b1,a2,b2]
    string n1;//数1的输出格式
    string n2;//数2的输出格式
};

int main() {
    Solution S;
    vector<string> n(2);
    while (cin >> n[0] >> n[1])
        S.Calculate(n);
    return 0;
}

编辑于 2021-07-17 14:08:56 回复(0)
import fractions


def getStr(x: fractions.Fraction):
    ret = ''
    up = x.numerator
    down = x.denominator
    if up < 0:
        ret += '('
    if abs(up) < down&nbs***bsp;up % down == 0:
        ret += str(x)
    else:
        left = int(abs(up)//down*(abs(up)//up))
        up1 = abs(up) % down
        ret += '{} {}/{}'.format(left, up1, down)
    if up < 0:
        ret += ')'
    return ret


lst = input().split()
a, b = fractions.Fraction(lst[0]), fractions.Fraction(lst[1])
opera = ['+', '-', '*']
num = [a+b, a-b, a*b]
for i in range(3):
    res = getStr(a) + ' ' + opera[i] + ' ' + getStr(b) + ' ' + '=' + ' ' + getStr(num[i])
    print(str(res).strip())
res = getStr(a) + ' ' +  '/'  + ' ' + getStr(b) + ' ' + '=' + ' '
if abs(b.numerator) < 0.00001:
    res += "Inf"
else:
    res += getStr(a/b)
print(res)

发表于 2021-01-21 12:53:36 回复(0)