华为编程题:求最简分数

题目: 输入两行分数, 求相加的最简分数。(具体看最下面的输入测试)

介绍:这是一道校招编程题,我在这里主要展示了两种方式破题,并且对这两种方法作了对比。第一种是求因数法,第二种方法是辗转相除法求两个数的最大公约数。下面是作者我实际破题代码:


版本一:求数的乘因数法

    public static void T6() {
        Scanner sc = new Scanner(System.in);
        String numStr1 = sc.nextLine();
        String numStr2 = sc.nextLine();

        long[] arr1 = Arrays.stream(numStr1.split("/")).map(String::trim).mapToLong(Long::parseLong).toArray();
        long[] arr2 = Arrays.stream(numStr2.split("/")).map(String::trim).mapToLong(Long::parseLong).toArray();

        long a = arr1[0];
        long b = arr1[1];
        /* ----分隔符--- */
        long c = arr2[0];
        long d = arr2[1];

        /**
         *
         * a    c     ad+ bc
         * - +  -  =  -------
         * b    d       bd
         *
         */
        long m, n;
        if (b == d) {
            m = a + c;
            n = b;
        } else {
            m = a * d + b * c;
            n = b * d;
        }
        // 假设不会超过2^32次方, 如果要输入大值, 那么这里切换到64位去填充
        int len = 32;
        long[] arr = new long[len];
        factors(n, arr, 0);

        long next;
        for (int i = 0; i < len; i++) {
            next = arr[i];
            if (next > 0) {
                if (m % next == 0) {
                    m /= next;
                    n /= next;
                }
            } else
                break;
        }
        System.out.println(m + " / " + n);
    }
	// 求质数因子法
	public static void factors(long n, long[] arr, int m) {
        if (n < 2)
            return;
        else if (n % 2 == 0) {
            s(n, arr, m, 2);
        } else {
            for (long i = 3; i <= Math.sqrt(n); i += 2) {
                if (n % i == 0) {
                    s(n, arr, m, i);
                    return;
                }
            }
            arr[m] = n;
        }
    }

    private static void s(long n, long[] arr, int m, long i) {
        arr[m++] = i;
        n /= i;
        factors(n, arr, m);
    }

测试:

	// 输入测试:
	/*
	221/22
	22/2
	*/
	
	/*
	242/22
	22/11
	*/
	T6();

上面代码关键部分:

	public static void T6(long molecule, long denominator) {
        // 假设不会超过2^32次方, 如果要输入大值, 那么这里切换到64位去填充
        int len = 32;
        long[] arr = new long[len];
        factors(denominator, arr, 0);

        long next;
        for (int i = 0; i < len; i++) {
            next = arr[i];
            if (next > 0) {
                if (molecule % next == 0) {
                    molecule /= next;
                    denominator /= next;
                }
            } else
                break;
        }
        System.out.println(molecule + " / " + denominator);
    }

关键代码测试:

	T6(333, 9);
	T6(236575676767876L, 2048);
版本二:辗转相除法求共因数
	
 	/**
     * 辗转相除法求公除数
     * 
     * @param molecule		分子
     * @param denominator   分母
     */
    public static long euclideanAlgorithm(long molecule, long denominator) {
        long MOD = molecule % denominator;
        if (MOD == 0) {
            return denominator;
        } else {
            return euclideanAlgorithm(denominator, MOD);
        }
    }

	/**
     * 欧几里得算法: 辗转相除法求最大公约数
     * 方法2
     * 相比方法1, 非递归
     *	
     * @param molecule
     * @param denominator
     * @return
     */
    public static long euclideanAlgorithm1(long molecule, long denominator) {
        long MOD;
        do {
            MOD = molecule % denominator;
            molecule = denominator;
            denominator = MOD;
        } while (MOD > 0);

        return molecule;
    }

关键代码测试:

	long divisor = divisionAlgorithm(236575676767876L, 2048);

    System.out.println((x / divisor) + " / " + (y / divisor));





两种算法实战对比一:

在这里插入图片描述

对比二截图:

在这里插入图片描述
结果很明显,辗转相除法比求数的因子快的多。


如果你有什么问题,就请提出来吧,我看到了就会解答~ 同时我也谢谢大家大家的评论、点赞


作者留言:大家一起进步,冲啊!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值