讲师中心 微信公众号
AI工具推荐 视频效率加速

Java递归实现:判断相邻数组元素和是否为10的倍数

千强同学_1883

千强同学_1883

发布时间:2025-09-24 23:10:02

|

503人浏览过

|

来源于php中文网

原创

Java递归实现:判断相邻数组元素和是否为10的倍数

本教程探讨如何使用递归方法判断一个整数数组中是否存在相邻的两个元素,它们的和是10的倍数。文章将分析常见的递归错误,特别是忽略递归调用返回值的陷阱,并提供一个正确且高效的递归解决方案,强调基本情况、递归步骤以及运算符优先级的重要性。

引言:递归检测相邻元素和的挑战

在程序设计中,我们有时需要检查数组中是否存在特定模式。一个常见的场景是判断是否存在相邻的两个元素,它们的和是某个特定值的倍数。本教程将聚焦于如何使用递归方法来解决这个问题:给定一个整数数组 arr,判断是否存在索引 i,使得 arr[i] + arr[i-1] 的和是10的倍数。我们将通过一个具体的java示例来深入理解递归的正确应用。

常见错误分析与原理

在使用递归解决这类布尔型判断问题时,开发者常犯的一个错误是未能正确处理递归调用的返回值。让我们分析一个典型的错误尝试:

public static boolean divideByTen(int arr[], int num) {
    int i = num - 1; // i 代表当前要检查的元素索引(从右向左)

    if (i > 0) { // 确保有前一个元素可以组成一对
        // 错误点1:丢弃递归调用的返回值
        divideByTen(arr, num - 1); // 递归调用,但其结果被忽略了

        // 错误点2:运算符优先级问题
        if (arr[i] + arr[i - 1] % 10 == 0) // 实际是 arr[i] + (arr[i-1] % 10)
            return true;
    }
    return false; // 如果不满足条件或到达基本情况,总是返回 false
}

错误点1:丢弃递归调用的返回值

代码中的 divideByTen(arr, num - 1); 语句执行了一个递归调用,但并没有对其返回值进行任何处理。这意味着即使在递归深层找到了满足条件的相邻对并返回了 true,这个 true 也被立即丢弃了。父级调用会继续执行其后续代码(例如 if (arr[i] + arr[i - 1] % 10 == 0)),而不会利用到子级调用的成功信息。

正确做法: 当递归调用的结果对当前层的判断至关重要时,必须捕获并处理该返回值。对于布尔型判断,通常是 if (recursiveCall(...)) return true; 或者直接 return recursiveCall(...);。

立即学习“Java免费学习笔记(深入)”;

错误点2:运算符优先级问题

JavaStoryDevelop
JavaStoryDevelop

你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在

下载

表达式 arr[i] + arr[i - 1] % 10 == 0 的本意是检查 (arr[i] + arr[i - 1]) 的和是否能被10整除。然而,在Java中,取模运算符 % 的优先级高于加法运算符 +。因此,该表达式实际上等同于 arr[i] + (arr[i - 1] % 10) == 0。这显然不是我们想要的结果。

正确做法: 使用括号明确指定运算顺序,确保先进行加法运算,再进行取模运算:(arr[i] + arr[i - 1]) % 10 == 0。

构建正确的递归解决方案

一个正确的递归函数应该包含以下两个核心部分:

  1. 基本情况 (Base Case): 递归的终止条件。当满足这个条件时,函数不再进行递归调用,而是直接返回一个确定的结果。这可以防止无限递归导致栈溢出。
  2. 递归步骤 (Recursive Step): 函数进行自身调用的部分。它将问题分解为更小的子问题,并利用子问题的结果来解决当前问题。

下面是基于上述原则构建的正确递归函数:

public class ArrayRecursion {

    /**
     * 递归判断数组中是否存在相邻元素和为10的倍数。
     * 从数组末尾(通过 index 参数指定)向前检查相邻对。
     *
     * @param arr   待检查的整数数组。
     * @param index 当前检查的数组索引。初始调用时,应传入 arr.length - 1。
     *              这个索引 arr[index] 将与 arr[index-1] 组成一对进行检查。
     * @return 如果存在相邻元素和为10的倍数,则返回 true;否则返回 false。
     */
    public static boolean checkAdjacentSumDivisibleByTen(int[] arr, int index) {
        // 基本情况1:如果索引小于1,说明没有足够的元素形成相邻对(至少需要两个元素),
        // 或者已经检查完所有可能的对,但未找到符合条件的。
        // 例如,对于空数组或只有一个元素的数组,index 初始值会是 -1 或 0,
        // 在这种情况下直接返回 false。
        if (index < 1) {
            return false;
        }

        // 递归步骤:
        // 1. 检查当前索引 arr[index] 及其前一个索引 arr[index - 1] 的元素和是否为10的倍数。
        //    注意:使用括号确保先求和再取模,避免运算符优先级问题。
        if ((arr[index] + arr[index - 1]) % 10 == 0) {
            return true; // 找到符合条件的对,立即返回 true,停止进一步递归。
        }

        // 2. 如果当前对不符合条件,则递归调用自身,检查数组中前一个位置的相邻对。
        //    关键:必须返回递归调用的结果,将子问题的结果传递回父级调用。
        return checkAdjacentSumDivisibleByTen(arr, index - 1);
    }

    // 主方法用于测试
    public static void main(String[] args) {
        int[] arr1 = {1, 9, 2, 8, 3, 7};   // (1+9)%10=0
        int[] arr2 = {5, 5, 10, 0, 2, 3}; // (5+5)%10=0, (10+0)%10=0
        int[] arr3 = {1, 2, 3, 4, 5};     // None
        int[] arr4 = {10, 20};            // (10+20)%10=0
        int[] arr5 = {};                  // Empty array
        int[] arr6 = {7};                 // Single element array

        System.out.println("arr1: " + checkAdjacentSumDivisibleByTen(arr1, arr1.length - 1)); // 预期: true
        System.out.println("arr2: " + checkAdjacentSumDivisibleByTen(arr2, arr2.length - 1)); // 预期: true
        System.out.println("arr3: " + checkAdjacentSumDivisibleByTen(arr3, arr3.length - 1)); // 预期: false
        System.out.println("arr4: " + checkAdjacentSumDivisibleByTen(arr4, arr4.length - 1)); // 预期: true
        // 对于空数组或单元素数组,arr.length - 1 会是 -1 或 0,
        // 此时 index < 1 的基本情况会立即返回 false。
        System.out.println("arr5 (空数组): " + checkAdjacentSumDivisibleByTen(arr5, arr5.length - 1)); // 预期: false
        System.out.println("arr6 (单元素数组): " + checkAdjacentSumDivisibleByTen(arr6, arr6.length - 1)); // 预期: false
    }
}

注意事项与总结

  1. 递归函数的返回值处理至关重要: 这是本教程的核心点。在布尔型判断的递归中,如果子问题能够确定最终结果(例如找到 true),其结果必须被返回并传递给上层调用。如果当前层不能确定,则继续递归,并将子问题的结果作为当前层的结果返回。
  2. 基本情况的完备性: 确保所有可能的终止条件都被覆盖。对于数组操作,需要考虑空数组、只有一个元素的数组,以及达到数组边界的情况。本例中 index < 1 很好地处理了这些边界条件。
  3. 运算符优先级: 在复合表达式中,始终注意运算符的优先级。当不确定时,使用括号 () 来明确指定运算顺序是一个好习惯。
  4. 递归与迭代的选择: 尽管递归在某些情况下能提供优雅的解决方案,但对于这类简单的数组遍历问题,迭代(使用 for 或 while 循环)通常更直观、更易于理解和调试,并且在性能上通常更优(避免了函数调用栈的开销,降低了栈溢出的风险)。选择递归主要是为了练习和理解递归的机制。

通过本教程,我们深入理解了如何使用递归来解决数组中相邻元素求和的问题,并强调了正确处理递归返回值和运算符优先级的重要性。掌握这些原则对于编写健壮和正确的递归算法至关重要。

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6144

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3064

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

1812

2025.10.17

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6067

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2568

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

6176

2023.08.14

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

20

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn