有理数运算

2 篇文章 0 订阅

1034 有理数四则运算 (20 分) (Go语言版)

本题要求编写程序,计算 2 个有理数的和、差、积、商。

输入格式:

输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为 0。

输出格式:

分别在 4 行中按照 有理数1 运算符 有理数2 = 结果 的格式顺序输出 2 个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式 k a/b,其中 k 是整数部分,a/b 是最简分数部分;若为负数,则须加括号;若除法分母为 0,则输出 Inf。题目保证正确的输出中没有超过整型范围的整数。

输入样例 1:

2/3 -4/2

输出样例 1:

2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)

输入样例 2:

5/3 0/6

输出样例 2:

1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf

Go语言代码

package main

import (
	"fmt"
	"errors"
)

type num struct {
	numerator   int // 分子
	denominator int // 分母
}

type num2 struct {
	integer     int
	numerator   int // 分子
	denominator int
}

func (n num2) String() string {
	var s string
	if n.integer == 0 {
		if n.denominator != 1 {
			if n.numerator > 0 {
				s = fmt.Sprintf("%d/%d", n.numerator, n.denominator)
			} else if n.numerator < 0 {
				s = fmt.Sprintf("(%d/%d)", n.numerator, n.denominator)
			} else {
				s = "0"
			}
		} else {
			var t1, t2 string
			if n.numerator >= 0 {
				t1 = ""
				t2 = ""
			} else {
				t1 = "("
				t2 = ")"
			}
			s = fmt.Sprintf("%s%d%s", t1, n.numerator, t2)
		}
	} else {
		if n.integer > 0 {
			if n.numerator != 0 {
				s = fmt.Sprintf("%d %d/%d", n.integer, n.numerator, n.denominator)
			} else {
				s = fmt.Sprintf("%d", n.integer)
			}
		} else {
			if n.numerator != 0 {
				s = fmt.Sprintf("(%d %d/%d)", n.integer, n.numerator, n.denominator)
			} else {
				s = fmt.Sprintf("(%d)", n.integer)
			}
		}
	}
	return s
}

func gcd(N1 int, N2 int) int {
	if N2 == 0 {
		return N1
	} else {
		return gcd(N2, N1%N2)
	}
}

func simplify(n num) num2 {
	var new_num num2
	var flag = false
	if n.numerator < 0 {
		n.numerator = -1 * n.numerator
		flag = true
	}
	var tmp = gcd(n.numerator, n.denominator)
	new_num.denominator = n.denominator / tmp
	new_num.integer = (n.numerator / tmp) / new_num.denominator
	new_num.numerator = (n.numerator / tmp) % new_num.denominator
	if flag {
		if new_num.integer == 0 {
			new_num.numerator = -1 * new_num.numerator
		} else {
			new_num.integer = -1 * new_num.integer
		}
	}
	return new_num
}

func add(n1 num, n2 num) num {
	var tmp num
	tmp.numerator = n1.numerator + n2.numerator
	tmp.denominator = n1.denominator
	return tmp
}

func minus(n1 num, n2 num) num {
	var tmp num
	tmp.numerator = n1.numerator - n2.numerator
	tmp.denominator = n1.denominator
	return tmp
}

func times(n1 num, n2 num) num {
	var tmp num
	tmp.numerator = n1.numerator * n2.numerator
	tmp.denominator = n1.denominator * n2.denominator
	return tmp
}

func divide(n1 num, n2 num) (num, error) {
	var tmp num
	if n2.numerator == 0 {
		return tmp, errors.New("Inf")
	}
	flag := false
	if n2.numerator < 0 {
		n2.numerator = -1 * n2.numerator
		flag = true
	}
	tmp.numerator = n2.denominator
	tmp.denominator = n2.numerator
	if flag {
		tmp.numerator = -1 * tmp.numerator
	}
	return times(n1, tmp), nil
}

func main() {
	var n1 num
	var n2 num
	fmt.Scanf("%d/%d %d/%d", &n1.numerator, &n1.denominator, &n2.numerator, &n2.denominator)
	common_multiple := n1.denominator * n2.denominator / gcd(n1.denominator, n2.denominator)

	// 加减传参传通分后的数
	var tmp_n1 num
	var tmp_n2 num
	tmp_n1.numerator = n1.numerator * (common_multiple / n1.denominator)
	tmp_n1.denominator = common_multiple
	tmp_n2.numerator = n2.numerator * (common_multiple / n2.denominator)
	tmp_n2.denominator = common_multiple

	fmt.Printf("%s + %s = %s\n", simplify(n1), simplify(n2), simplify(add(tmp_n1, tmp_n2)))
	fmt.Printf("%s - %s = %s\n", simplify(n1), simplify(n2), simplify(minus(tmp_n1, tmp_n2)))
	fmt.Printf("%s * %s = %s\n", simplify(n1), simplify(n2), simplify(times(n1, n2)))
	value, err := divide(n1, n2)
	if err != nil {
		fmt.Printf("%s / %s = %s\n", simplify(n1), simplify(n2), err.Error())
	} else {
		fmt.Printf("%s / %s = %s\n", simplify(n1), simplify(n2), simplify(value))
	}
}

结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值