Go Java算法之累加数示例详解

Go Java算法之累加数示例详解

什么是累加数

累加数是指一个字符串序列,划分成多个数字序列,每个数字序列的数字之和等于后面的数字序列的第一个数字。

例如:112358 是一个累加数,因为 1+1=2, 1+2=3, 2+3=5, 3+5=8,后面的数字序列分别为 1, 2, 3, 5。

算法思路

为了判断一个字符串是否为累加数,我们需要枚举前两个数字,然后依次判断后面的数字序列是否合法即可。

假设第一个数字为 i,第二个数字为 j,那么第三个数字就是 i+j,接下来用 i+j 对原字符串进行截取,判断剩余的字符串是否为 i+j,以此类推。

注意,数字序列不能以 0 开头,所以 i 和 j 可能是一位数、两位数、三位数中的任意两个数字。

示例说明

下面给出两个示例,来详细解释累加数的判断过程。

示例一

输入的字符串为 "11235813"。

我们首先枚举前两个数字:i=1, j=1。

然后计算出第三个数字,即 i+j=2,将字符串从当前位置截取出来,得到 "235813",判断该字符串是否为 2,发现不是,因此这个枚举的结果不合法。

接下来我们枚举下一组:i=1, j=2。

计算出第三个数字 i+j=3,截取字符串得到 "35813",判断该字符串是否为 3,不是。

接下来继续枚举:i=2, j=3。

计算出第三个数字 i+j=5,截取字符串得到 "5813",判断该字符串是否为 5,不是。

接下来继续枚举:i=3, j=5。

计算出第三个数字 i+j=8,截取字符串得到 "13",判断该字符串是否为 8,不是。

接下来继续枚举:i=5, j=8。

计算出第三个数字 i+j=13,截取字符串得到 "",判断该字符串是否为 13,是。

因此,该字符串是一个累加数。

示例二

输入的字符串为 "199100199"。

我们首先枚举前两个数字:i=1, j=9。

然后计算出第三个数字,即 i+j=10,由于下一位是 9,因此第一部分为 "19"。

依次计算出第四个数字:i+j=19,截取字符串得到 "9100199",发现它不等于 19,因此这个枚举的结果不合法。

接下来继续枚举:i=9, j=1。

计算出第三个数字 i+j=10,由于第二部分以 0 开头,不合法。

接下来继续枚举:i=1, j=9。

计算出第三个数字 i+j=10,第一部分为 "19",第二部分为 "9"。

依次计算出第四个数字:i+j=19,截取字符串得到 "100199",不等于 19。

接下来继续枚举:i=9, j=1。

计算出第三个数字 i+j=10,第一部分为 "199",第二部分为 "1"。

依次计算出第四个数字:i+j=11,截取字符串得到 "00199",不等于 11。

接下来继续枚举:i=1, j=9。

计算出第三个数字 i+j=10,第一部分为 "1",第二部分为 "99100199"。

依次计算出第四个数字:i+j=9,截取字符串得到 "9100199",不等于 9。

接下来继续枚举:i=9, j=9。

由于第一个数字不能为 0,因此这个枚举的结果不合法。

因此,该字符串不是一个累加数。

代码实现

下面给出代码实现的主要部分,具体实现细节请参考代码注释。

func isAdditiveNumber(num string) bool {
    n := len(num)
    for i := 1; i <= n/2; i++ { // 枚举第一个数字的长度
        for j := 1; j <= (n-i)/2; j++ { // 枚举第二个数字的长度
            if check(num[:i], num[i:i+j], num[i+j:]) { // 如果找到了一个累加数直接返回 true
                return true
            }
            // 如果第二个数字以 0 开头,则不能继续往下枚举
            if num[i:i+j][0] == '0' {
                break
            }
        }
        // 如果第一个数字以 0 开头,则不能继续往下枚举
        if num[0] == '0' {
            break
        }
    }
    return false
}

// 判断是否为累加数
func check(s1, s2, s3 string) bool {
    for len(s3) > 0 { // 按照累加数的定义依次判断后面的数字序列
        if !strings.HasPrefix(s3, add(s1, s2)) {
            return false
        }
        s1, s2, s3 = s2, add(s1, s2), s3[len(add(s1, s2)):]
    }
    return true
}

// 计算两个字符串数字的和
func add(s1, s2 string) string {
    i, j, carry, sum := len(s1)-1, len(s2)-1, 0, []byte{}
    for i >= 0 || j >= 0 {
        n1, n2 := 0, 0
        if i >= 0 {
            n1 = int(s1[i] - '0')
            i--
        }
        if j >= 0 {
            n2 = int(s2[j] - '0')
            j--
        }
        tmp := n1 + n2 + carry
        sum = append(sum, byte(tmp%10)+'0')
        carry = tmp / 10
    }
    if carry > 0 {
        sum = append(sum, byte(carry)+'0')
    }
    // 由于我们计算结果时是从低位开始的,因此要将结果翻转一下
    for i, n := 0, len(sum); i < n/2; i++ {
        sum[i], sum[n-i-1] = sum[n-i-1], sum[i]
    }
    return string(sum)
}

总结

累加数问题实际上可以转化为一个回溯问题,但是优化后的暴力枚举已经足够应对该问题。在实现时需要注意细节,例如数字序列不能以 0 开头、要注意截取字符串的范围等等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go Java算法之累加数示例详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 基于jsp实现新闻管理系统 附完整源码

    基于JSP实现新闻管理系统攻略 介绍 本攻略将会介绍如何使用JSP(Java Server Pages)实现一个简单的新闻管理系统,并提供完整的源码。 使用JSP是因为它可以将Java代码和HTML标记混合在同一个页面中,同时也可以使用标准的Java类库和框架。 开始 首先,搭建一个Java Web开发环境,如Tomcat。确保你已经会使用Eclipse或者…

    Java 2023年6月15日
    00
  • MyBatis批量插入数据的三种方法实例

    MyBatis批量插入数据的三种方法实例 在MyBatis中,批量插入数据的操作可以显著提高数据库的性能。本文将介绍MyBatis中常用的三种批量插入数据的方法。 方法一:使用foreach标签 使用foreach标签可以很方便地实现批量插入数据,具体实现步骤如下: 在mapper文件中编写批量插入数据的SQL语句,其中使用foreach标签循环插入数据。 …

    Java 2023年5月20日
    00
  • SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

    下面是SpringBoot快速集成jxls-poi的完整攻略。 1. jxls-poi简介 jxls-poi是一个基于POI实现Excel导出的工具,可以使用自定义模板导出Excel,并且支持本地文件导出和在线文件导出。 2. 集成jxls-poi到SpringBoot项目 2.1 导入依赖 在SpringBoot项目的pom.xml中添加以下依赖: &lt…

    Java 2023年6月15日
    00
  • Java 设计模式中的策略模式详情

    Java 设计模式中的策略模式 策略模式基础概念 策略模式是一种行为型设计模式,它能让你定义一些算法并将其封装到具有公共接口的独立类中。由于所有策略类都实现了相同的接口,因此它们可以自由地相互替换。 策略模式的结构 策略模式的核心在于定义一个策略接口(Istrategy),所有的算法都实现这个接口;然后定义一个上下文类(Context),这个上下文类有一个策…

    Java 2023年5月19日
    00
  • Windows Vista系统常用术语列表

    我们来详细讲解一下“Windows Vista系统常用术语列表”的完整攻略。 1. 什么是“Windows Vista系统常用术语列表”? “Windows Vista系统常用术语列表”是指在使用Windows Vista操作系统时,可能会遇到的一些常用术语,例如“任务栏”、“控制面板”、“系统还原”等等。 2. “Windows Vista系统常用术语列表…

    Java 2023年5月30日
    00
  • JS中showModalDialog 的使用解析

    JS中showModalDialog 的使用解析 简介 showModalDialog() 是 JavaScript 中的一个方法,用于打开模态对话框。模态对话框是一种对用户操作有限制的对话框,只有在对话框关闭之后,才能进行其他操作。 语法 showModalDialog (url, [argument1, argument2, …], [options…

    Java 2023年6月15日
    00
  • Maven打包jar生成javadoc文件和source文件代码实例

    接下来将为您详细讲解”Maven打包jar生成javadoc文件和source文件代码实例”的完整攻略。 1. 前置条件 在进行生成javadoc文件和source文件代码之前,需要确保本机已经安装了JDK和Maven。 2. 创建Maven项目 在本地创建一个Maven项目并在其中添加需要进行打包的代码。 <project xmlns="h…

    Java 2023年5月19日
    00
  • 多个jsp页面共享一个js对象的超级方法

    要实现多个JSP页面共享一个JS对象的超级方法,可以使用以下步骤: 在JSP页面中引入公共的JS文件。 <script src="common.js"></script> 定义公共的JS对象,可以将它定义为全局变量。 var commonObj = { name: "Tom", age: 18,…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部