分数混合加减和查找

综合前面的应用完成分数的混合加减和查找某个在表达式中出现的次数。具体如下:
1.定义Fraction类
class Fraction      //分数
{
private: 
    int num = 0;    //分子
    int den = 1;    //分母
public:    
    //构造函数
    Fraction() {}
    Fraction(int num, int den);
    //打印分数 
    void PrintFraction() const;
    //约分
    void Reduct();     
     //根据需要重载运算符的成员函数
};
【提示】
构造函数:Fraction(int num, int den)功能如下:
判断分子分母的合法性:如果分母为0,输出"分母为0错误“;如果分母为负数,则将负号转移到分子。如果不是最简要进行约分。
约分函数 void Reduct()简要算法如下:
(1) 处理分子为 0 的情况:如果分子为0,分母设置为1,返回
说明:分子为0时,不用约分。将分母统一设为1的原因是为了与“约分完后分母有可能为1”的情况统一,这两种情况便可以在输出时统一处理:当分母为1时,输出分子。
(2) 获得分数的符号,存入sign
(3) 计算|分子|和|分母|的最大公约数gys
(4) 约分:|分子|/gys,|分母|/gys
(5) 符号处理:|分子| * sign
2.定义FractionL类
class FractionL{
private:
    int number;
    Fraction *p;
public:
    FractionL(int n)
    {
        p=new Fraction[n];
        number=n;
    }    
    // 根据需要重载运算符的成员函数,比如[]运算符的重载
};
3.根据需要重载运算符的全局函数
4.实现main
main的总体思想:读入一个分数,初始化Fraction对象sum,循环读入下一个符号,根据符号进行不同操作,* 退出,+/-则读入下一个分数与sum进行+/-运算,具体下:

(1) 定义int变量n1,n2,i=0,分别用来存储读入分数的分子、分母,以及分数个数
(2) 定义char变量c1,c2,c1读走/,c2存储运算符
(3) 定义FractionL fl(10),用来存储所有的分数
(4) 读入分数:分子和分母存入n1和n2
(5) 定义Fraction 对象sum(n1,n2)
(6) 将刚读入的分数存入fl,fl[i++]=sum;
(7) 循环进行分数加减,直到遇到*,具体如下:
while(1)
{
   读入下一个符号c2
   如果c是* 则退出循环 
   否则
        读入下一个分数n1/n2,存入fl(fl[i]=Fraction(n1,n2)
        如果c2是+,则sum=sum+fl[i];
        如果c2是-,则sum=sum-fl[i];
    sum.约分
    i++        
}
(8) 输出表达式计算结果sum
(9) 读入要查找的分数n1/n2
(10) 调用fl的find函数查找分数n1/n2的个数
(11) 输出查找结果
语法要求:
要求使用运算符重载完成Fraction对象的混合加减。
表达式中分数的存储,要求使用函数题中的FractionL类对象来存储分数,并通过下标运算符[]完成对FractionL类对象的成员p的对应元素的赋值。例如:
FractionL fl(10);
fl[0]=Fraction(1,2);//则是把临时对象Fraction(1,2)赋值给了fl成员p[0];
为FractionL定义成员函数find完成查找某个分数出现的次数,即查找成员p指向数组中某个分数出现的次数。
输入格式:
第一行:输入一个包含n个分数加减混合运算的表达式(*结尾),输入的分数都是正的,且只有+和-运算,n值不超过10.
第二行:要查找的分数

输出格式:
表达式的计算结果
要查找分数在表达式中出现的次数

输入样例1:
1/2+1/3-1/2+1/4*
1/2
输出样例1:
在这里给出相应的输出。例如:

结果=7/12
有2个1/2
输入样例2:
1/2+1/2-1/2+1/2*
1/2
输出样例2:
在这里给出相应的输出。例如:

结果=1
有4个1/2

#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

class Fraction {
private:
    int num = 0;
    int den = 1;
public:
    Fraction() {}
    Fraction(int num, int den): num(num), den(den) { 
    if (den == 0) {
        cout << "分母为0错误" << endl;
        exit(1);                   //终止程序的执行,并返回状态码 1。
    } else if (den < 0) {        //如果分母为负数,则将负号转移到分子。
        num = -num;
        den = -den;
    }
    Reduct();            //约分保证最简
}
    
    // 打印分数
    void PrintFraction() const {
    if (den == 1) {
        cout << num;
    } else {
        cout << num << "/" << den;
    }
}
    // 约分
    void Reduct() {
    if (num == 0) {
        den = 1;
    }
    int sign = (num < 0) ? -1 : 1;     //前面已将负号转移到分子,则通过分子的符号获得分数的符号,存入sign
    int gys = gcd(num,den);            //定义gys为最大公约数
    num = abs(num) / gys * sign;       //符号处理
    den /= gys;
}
    
    //最大公约数函数
int gcd(int a,int b)            //求最大公约数(Greatest Common Divisor)
{                               //辗转相除法(欧几里得算法)
    if(b==0)                    //用较大数除以较小数得到余数,反复进行直到余数为零
        return a;
    else
        return gcd(b,a%b);        //如果0<a<b,a%b=a
}
    
    // 运算符重载
    Fraction operator+(const Fraction& other) const {
    Fraction result(num * other.den + other.num * den, den * other.den);
    result.Reduct();
    return result;
}
    Fraction operator-(const Fraction& other) const{
    Fraction result(num * other.den - other.num * den, den * other.den);
    result.Reduct();
    return result;
}
    bool operator==(const Fraction& other) const {
    return num * other.den == other.num * den;
}
};

// 分数列表类
class FractionL {
private:
    int number;        // 用于存储分数的数量
    Fraction *p;       // 指向动态分配的 Fraction 数组
public:
    FractionL(int n) {
        p = new Fraction[n];  // 动态分配一个大小为 n 的 Fraction 数组
        number = n;         // 将 number 设置为 n
    }
    Fraction& operator[](int index) const {  // 下标运算符重载:通过下标访问存储的分数
        if (index >= 0 && index < number) {
            return p[index];
        } else {
            cout << "下标越界." << endl;
            exit(1);
        }
    }
    int find(const Fraction& target) const {  // 查找函数:查找给定分数在存储的分数数组中出现的次数
        int count = 0;
        for (int i = 0; i < number; ++i) {
            if (p[i] == target) {
                count++;
            }
        }
        return count;
    }
};

int main() {
    int n1, n2, i = 0;
    char c1, c2;
    FractionL fl(10);       // 用来存储所有的分数
    cin >> n1 >> c1 >> n2;  // 读入第一个分数
    Fraction sum(n1, n2);   //实例化对象
    fl[i++] = sum;          //将对象存入动态数组中
    while (true) {          // 循环读入符号和分数,进行加减运算
        cin >> c2;
        if (c2 == '*') break;  //* 表示退出
        cin >> n1 >> c1 >> n2;
        fl[i] = Fraction(n1, n2);
        
        if (c2 == '+') {
            sum = sum + fl[i];
        } else if (c2 == '-') {
            sum = sum - fl[i];
        }
        
        sum.Reduct();
        i++;
    }

    cout << "结果=";       // 输出表达式计算结果
    sum.PrintFraction();
    cout << endl;
    
    cin >> n1 >> c1 >> n2;    // 读入要查找的分数
    Fraction target(n1, n2);
    
    int count = fl.find(target);    // 查找并输出分数出现次数
    cout << "有" << count << "个";
    target.PrintFraction();
    cout << endl;

    return 0;
}

  • 52
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值