Go和Java算法详析之分数到小数

 更新时间:2022年08月11日 11:18:04   作者:黄丫丫  
这篇文章主要给大家介绍了关于Go和Java算法详析之分数到小数的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

分数到小数

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。

如果小数部分为循环小数,则将循环的部分括在括号内。

如果存在多个答案,只需返回 任意一个 。

对于所有给定的输入,保证 答案字符串的长度小于 104 。

  • 示例 1:

输入:numerator = 1, denominator = 2

输出:"0.5"

  • 示例 2:

输入:numerator = 2, denominator = 1

输出:"2"

  • 示例 3:

输入:numerator = 4, denominator = 333

输出:"0.(012)"  

提示:

-231 <= numerator, denominator <= 231 - 1

denominator != 0

方法一:模拟竖式计算(Java)

这是一道模拟竖式计算(除法)的题目。

首先可以明确,两个数相除要么是「有限位小数」,要么是「无限循环小数」,而不可能是「无限不循环小数」。

将分数转成整数或小数,做法是计算分子和分母相除的结果。可能的结果有三种:整数、有限小数、无限循环小数。

如果分子可以被分母整除,则结果是整数,将分子除以分母的商以字符串的形式返回即可。

如果分子不能被分母整除,则结果是有限小数或无限循环小数,需要通过模拟长除法的方式计算结果。为了方便处理,首先根据分子和分母的正负决定结果的正负(注意此时分子和分母都不为 00),然后将分子和分母都转成正数,再计算长除法。

一个显然的条件是,如果本身两数能够整除,直接返回即可;

如果两个数有一个为“负数”,则最终答案为“负数”,因此可以起始先判断两数相乘是否小于 00,如果是,先往答案头部追加一个负号 -;

两者范围为 int,但计算结果可以会超过 int 范围,考虑 numerator = -2^{31}和 denominator = -1的情况,其结果为 2^{31},超出 int 的范围 [-2^{31}, 2^{31} - 1]。因此起始需要先使用 long 对两个入参类型转换一下。

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        // 转 long 计算,防止溢出
        long a = numerator, b = denominator;
        // 如果本身能够整除,直接返回计算结果
        if (a % b == 0) return String.valueOf(a / b);
        StringBuilder sb = new StringBuilder();
        // 如果其一为负数,先追加负号
        if (a * b < 0) sb.append('-');
        a = Math.abs(a); b = Math.abs(b);
        // 计算小数点前的部分,并将余数赋值给 a
        sb.append(String.valueOf(a / b) + ".");
        a %= b;
        Map<Long, Integer> map = new HashMap<>();
        while (a != 0) {
            // 记录当前余数所在答案的位置,并继续模拟除法运算
            map.put(a, sb.length());
            a *= 10;
            sb.append(a / b);
            a %= b;
            // 如果当前余数之前出现过,则将 [出现位置 到 当前位置] 的部分抠出来(循环小数部分)
            if (map.containsKey(a)) {
                int u = map.get(a);
                return String.format("%s(%s)", sb.substring(0, u), sb.substring(u));
            }
        }
        return sb.toString();
    }
}

时间复杂度:O(M)

空间复杂度:O(M)

方法一:模拟竖式计算(Go)

具体的方法详情已经在上文中表述,详情请看上文。

func fractionToDecimal(numerator, denominator int) string {
    if numerator%denominator == 0 {
        return strconv.Itoa(numerator / denominator)
    }

    s := []byte{}
    if numerator < 0 != (denominator < 0) {
        s = append(s, '-')
    }

    // 整数部分
    numerator = abs(numerator)
    denominator = abs(denominator)
    integerPart := numerator / denominator
    s = append(s, strconv.Itoa(integerPart)...)
    s = append(s, '.')

    // 小数部分
    indexMap := map[int]int{}
    remainder := numerator % denominator
    for remainder != 0 && indexMap[remainder] == 0 {
        indexMap[remainder] = len(s)
        remainder *= 10
        s = append(s, '0'+byte(remainder/denominator))
        remainder %= denominator
    }
    if remainder > 0 { // 有循环节
        insertIndex := indexMap[remainder]
        s = append(s[:insertIndex], append([]byte{'('}, s[insertIndex:]...)...)
        s = append(s, ')')
    }

    return string(s)
}

func abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}

时间复杂度:O(M)

空间复杂度:O(M)

总结

到此这篇关于Go和Java算法详析之分数到小数的文章就介绍到这了,更多相关Go Java分数到小数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用golang如何优雅的关机或重启操作示例

    使用golang如何优雅的关机或重启操作示例

    这篇文章主要为大家介绍了使用golang如何优雅的关机或重启操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • GoLang RabbitMQ TTL与死信队列以及延迟队列详细讲解

    GoLang RabbitMQ TTL与死信队列以及延迟队列详细讲解

    这篇文章主要介绍了GoLang RabbitMQ TTL与死信队列以及延迟队列,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • Go语言如何实现TCP通信详解

    Go语言如何实现TCP通信详解

    go里面实现tcp没有像之前写的C++那些那么麻烦,在C++里面要先创建套接字,然后绑定ip地址,go里面直接就一个函数建立套接字,然后在进行通信就可以了,下面这篇文章主要给大家介绍了关于Go语言如何实现TCP通信的相关资料,需要的朋友可以参考下
    2023-01-01
  • Golang常见错误之值拷贝和for循环中的单一变量详解

    Golang常见错误之值拷贝和for循环中的单一变量详解

    这篇文章主要给大家介绍了关于Golang常见错误之值拷贝和for循环中单一变量的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • Go设计模式之代理模式图文详解

    Go设计模式之代理模式图文详解

    这篇文章将通过图文讲解给大家详细的介绍一下Go代理模式,代理模式是一种结构型设计模式,代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理,感兴趣的同学跟着小编一起来看看吧
    2023-07-07
  • 详解在Go语言单元测试中如何解决Redis存储依赖问题

    详解在Go语言单元测试中如何解决Redis存储依赖问题

    在编写单元测试时,除了 MySQL 这个外部存储依赖,Redis 应该是另一个最为常见的外部存储依赖了,本文就来讲解下如何解决 Redis 外部依赖,文章通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • golang gorm 操作mysql及gorm基本用法

    golang gorm 操作mysql及gorm基本用法

    golang 官方的那个操作mysql的有点麻烦所以就使用了gorm,下面就gorm的使用做下简单介绍,感兴趣的朋友跟随小编一起看看吧
    2018-11-11
  • 详解Go语言如何进行Http调用

    详解Go语言如何进行Http调用

    无论是微服务还是单体架构等,服务间都有相互通信的时候,而最直接的通信方法就是 HTTP 调用,本文将会介绍在 Go 语言里,如何进行 HTTP 调用,需要的可以参考一下
    2022-12-12
  • golang中protobuf的使用详解

    golang中protobuf的使用详解

    protobuf是Google公司提出的一种轻便高效的结构化数据存储格式,常用于结构化数据的序列化,具有语言无关、平台无关、可扩展性特性,常用于通讯协议、服务端数据交换场景,下面我们就来看看golang中protobuf的具体使用吧
    2023-10-10
  • 详解golang consul-grpc 服务注册与发现

    详解golang consul-grpc 服务注册与发现

    这篇文章主要介绍了详解golang consul-grpc 服务注册与发现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06

最新评论