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

Java 2D数组的用户输入与90度顺时针旋转教程

风强姑娘_3439

风强姑娘_3439

发布时间:2025-10-01 14:39:11

|

404人浏览过

|

来源于php中文网

原创

Java 2D数组的用户输入与90度顺时针旋转教程

本教程详细讲解了如何在Java中实现二维数组(矩阵)的用户输入、初始化以及90度顺时针旋转。文章首先介绍了如何正确地声明、读取并显示用户定义的矩阵,解决了输入显示可能遇到的常见问题。随后,深入阐述了矩阵90度顺时针旋转的核心原理,即通过转置和行反转两步操作实现,并提供了适用于任意MN非方阵的健壮解决方案及完整的Java代码示例,最后总结了相关注意事项与最佳实践。

1. Java 2D 数组的创建与用户输入

在java中创建和操作二维数组是常见的任务。本节将指导您如何通过用户输入动态定义矩阵的维度并填充其元素,同时纠正原始代码中可能导致显示异常的问题。

1.1 声明与初始化

首先,我们需要获取用户输入的行数(m)和列数(n),然后根据这些维度声明一个二维整型数组。

import java.util.Scanner;

public class MatrixOperations {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("请输入矩阵的行数 (m): ");
        int m = sc.nextInt();
        System.out.print("请输入矩阵的列数 (n): ");
        int n = sc.nextInt();

        // 声明并初始化二维矩阵
        int[][] array = new int[m][n];

        // ... 后续操作
    }
}

1.2 读取矩阵元素

使用嵌套循环遍历矩阵的每一个位置,并通过 Scanner 读取用户输入的整数,将其存入对应的数组单元。

        System.out.println("请按行输入矩阵的 " + m * n + " 个元素:");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("请输入 array[" + i + "][" + j + "]: ");
                array[i][j] = sc.nextInt();
            }
        }

注意事项: 原始代码中可能存在输入后显示元素数量不符的问题,这通常是由于后续操作(如旋转)被错误地放置在显示循环内部,或者对循环逻辑的误解。确保在所有元素输入完毕后再进行显示或旋转操作,并且显示循环应完整遍历整个矩阵。

1.3 显示原始矩阵

在进行任何转换之前,通常需要显示原始矩阵,以便验证输入是否正确。

        System.out.println("\n原始矩阵:");
        displayMatrix(array); // 调用一个辅助方法显示矩阵
    // 辅助方法:显示矩阵
    public static void displayMatrix(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                System.out.print(matrix[i][j] + "\t"); // 使用制表符对齐
            }
            System.out.println(); // 每行结束后换行
        }
    }

2. 矩阵90度顺时针旋转的实现

矩阵的90度顺时针旋转是一个常见的算法问题。对于非方阵(m*n),直接在原矩阵上进行旋转会比较复杂且容易出错。一种更通用且易于理解的方法是使用一个辅助矩阵来完成。

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

deep-java-review
deep-java-review

Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...

下载

2.1 旋转原理:转置与行反转

将一个矩阵顺时针旋转90度,可以分解为两个步骤:

  1. 转置 (Transpose): 将矩阵的行和列互换。即 matrix[i][j] 变为 matrix[j][i]。
  2. 行反转 (Reverse Rows): 对转置后的矩阵的每一行进行反转。

例如,一个2x3的矩阵:

1 2 3
4 5 6
  1. 转置后(变为3x2):
    1 4
    2 5
    3 6
  2. 行反转后(最终结果):
    4 1
    5 2
    6 3

2.2 使用辅助矩阵实现旋转

由于转置操作会改变矩阵的维度(m x n 变为 n x m),因此使用一个辅助矩阵来存储中间结果是处理非方阵的有效策略。

    /**
     * 将给定矩阵顺时针旋转90度。
     * 该方法会创建一个新的矩阵来存储旋转结果,适用于任何M*N矩阵。
     *
     * @param matrix 待旋转的原始矩阵
     * @return 旋转90度后的新矩阵
     */
    public static int[][] rotateMatrixClockwise(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return new int[0][0]; // 处理空矩阵或无效矩阵
        }

        int originalRows = matrix.length;
        int originalCols = matrix[0].length;

        // 旋转后的矩阵行数等于原矩阵列数,列数等于原矩阵行数
        int[][] rotatedMatrix = new int[originalCols][originalRows];

        // 第一步:转置矩阵并存储到辅助矩阵中
        // matrix[i][j] 的新位置是 rotatedMatrix[j][i]
        for (int i = 0; i < originalRows; i++) {
            for (int j = 0; j < originalCols; j++) {
                rotatedMatrix[j][i] = matrix[i][j];
            }
        }

        // 第二步:反转辅助矩阵的每一行
        // 对于 rotatedMatrix[j][i],其最终位置是 rotatedMatrix[j][originalRows - 1 - i]
        // 实际上,我们是在转置后的矩阵上进行行反转。
        // 等价于:对于原矩阵的每个元素 matrix[row][col],
        // 旋转后它会移动到新矩阵的 (col, originalRows - 1 - row) 位置。
        // 我们可以直接计算这个最终位置,避免显式的两步操作,直接填充 rotatedMatrix。
        // 但为了理解,我们先进行转置,再进行行反转。

        // 重新考虑:直接一步到位计算最终位置
        // 原 matrix[row][col] 旋转后在新矩阵的位置是 [col][originalRows - 1 - row]
        int[][] finalRotatedMatrix = new int[originalCols][originalRows];
        for (int r = 0; r < originalRows; r++) {
            for (int c = 0; c < originalCols; c++) {
                finalRotatedMatrix[c][originalRows - 1 - r] = matrix[r][c];
            }
        }
        return finalRotatedMatrix;
    }

解释:

  • originalRows 和 originalCols 分别是原始矩阵的行数和列数。
  • rotatedMatrix 是新的矩阵,其维度为 originalCols x originalRows。
  • 对于原始矩阵中的 matrix[r][c] 元素,它在旋转90度后会移动到新矩阵的 [c][originalRows - 1 - r] 位置。这个公式直接结合了转置和行反转的逻辑,一步到位地计算了最终位置。

3. 完整示例代码

将上述创建、输入、显示和旋转逻辑整合到一个完整的Java程序中。

import java.util.Scanner;

public class MatrixOperations {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 1. 获取矩阵维度
        System.out.print("请输入矩阵的行数 (m): ");
        int m = sc.nextInt();
        System.out.print("请输入矩阵的列数 (n): ");
        int n = sc.nextInt();

        // 输入验证,确保维度有效
        if (m <= 0 || n <= 0) {
            System.out.println("行数和列数必须是正整数。");
            sc.close();
            return;
        }

        // 2. 声明并初始化二维矩阵
        int[][] array = new int[m][n];

        // 3. 读取矩阵元素
        System.out.println("请按行输入矩阵的 " + (m * n) + " 个元素:");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("请输入 array[" + i + "][" + j + "]: ");
                array[i][j] = sc.nextInt();
            }
        }

        // 4. 显示原始矩阵
        System.out.println("\n--- 原始矩阵 ---");
        displayMatrix(array);

        // 5. 旋转矩阵
        int[][] rotatedArray = rotateMatrixClockwise(array);

        // 6. 显示旋转后的矩阵
        System.out.println("\n--- 矩阵顺时针旋转90度后 ---");
        displayMatrix(rotatedArray);

        // 关闭Scanner,释放资源
        sc.close();
    }

    /**
     * 辅助方法:显示矩阵内容
     * @param matrix 待显示的矩阵
     */
    public static void displayMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            System.out.println("矩阵为空或无效。");
            return;
        }
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                System.out.print(matrix[i][j] + "\t"); // 使用制表符对齐
            }
            System.out.println(); // 每行结束后换行
        }
    }

    /**
     * 将给定矩阵顺时针旋转90度。
     * 该方法会创建一个新的矩阵来存储旋转结果,适用于任何M*N矩阵。
     *
     * @param matrix 待旋转的原始矩阵
     * @return 旋转90度后的新矩阵
     */
    public static int[][] rotateMatrixClockwise(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return new int[0][0]; // 处理空矩阵或无效矩阵
        }

        int originalRows = matrix.length;
        int originalCols = matrix[0].length;

        // 旋转后的矩阵行数等于原矩阵列数,列数等于原矩阵行数
        int[][] finalRotatedMatrix = new int[originalCols][originalRows];

        // 计算每个元素在旋转后在新矩阵中的最终位置
        // 原 matrix[r][c] 旋转后在新矩阵的位置是 [c][originalRows - 1 - r]
        for (int r = 0; r < originalRows; r++) {
            for (int c = 0; c < originalCols; c++) {
                finalRotatedMatrix[c][originalRows - 1 - r] = matrix[r][c];
            }
        }
        return finalRotatedMatrix;
    }
}

4. 总结与最佳实践

  • 通用性: 上述 rotateMatrixClockwise 方法适用于任何 M x N 的矩阵,无论是方阵还是非方阵。它通过创建一个新的辅助矩阵来存储旋转结果,避免了在原矩阵上进行复杂且容易出错的就地(in-place)旋转操作。
  • 空间复杂度: 使用辅助矩阵的方法,其空间复杂度为 O(M * N),即与原始矩阵的大小相同。对于内存敏感的应用,可能需要考虑就地旋转算法(通常只适用于方阵)。
  • 输入验证: 在实际应用中,对用户输入进行验证至关重要。例如,确保矩阵的行数和列数是正整数,并处理可能的 InputMismatchException。
  • 资源管理: 及时关闭 Scanner 对象(通过 sc.close())以释放系统资源,防止资源泄露。
  • 代码清晰度: 将不同的功能(如显示、旋转)封装到单独的方法中,可以提高代码的可读性和模块化。
  • 原始问题分析: 原始代码中将 rotate(array); 和相关打印语句放在显示原始矩阵的内层循环中是错误的。旋转操作应该在矩阵完全输入并显示后,作为一次性操作执行。rotate 方法内部硬编码 M=4 也是一个主要问题,导致无法处理动态维度的矩阵。本教程的解决方案修正了这些问题。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

豆包大模型

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

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

WorkBuddy

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

讯飞智作

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

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

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

相关专题

更多
页面置换算法
页面置换算法

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

4996

2023.08.14

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

0

2026.09.30

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

0

2026.09.30

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

0

2026.09.30

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

0

2026.09.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

200

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

120

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

100

2026.09.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
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