求回型存储的二维数组中任意位置的(java long范围内)元素值的数学算法分析及java实现

文章探讨了一种不依赖物理存储,通过数学算法直接计算回型排列的二维数组中任意坐标对应的数值的方法。针对传统存储访问方式可能导致的大内存消耗问题,提出了一种高效计算思路,包括确定圈数、计算起始数和圈内位置,并给出了Java代码实现。同时,作者提出了可能存在的优化空间,期待与读者交流学习。
摘要由CSDN通过智能技术生成

最近看到一个我觉得非常有意思的题目,关于“回型”存储的题目
网上有一些实现方法
这和大家分享一下我的思路和实现方法:

小弟学识浅薄,有不妥的地方,还请各位大神指教!!!!

1. 问题描述

一组连续的自然数,“回型”的存放入一个n*n的二维数组中,求二维数组中任意坐标的存储的值
例如:存放入一个4*4的二维数组中:
回型存储

传统解决方法:

先将这串连续的自然数按照规定,存入二维数组,然后再使用传统的访问二维数组的方法访问(nums[ ][ ])坐标对应的位置存储的值
缺点:在只求元素值不需要进行数组存储的情景中,当二维数组的大小非常大时(例如:存入1000 0000*1000 0000的二维数组中),可能会导致内存的溢出,即使内存足够用,这种方法也变得非常的低下,极大的浪费内存空间。

我的思路:

概述:由于这里不需要实现二维数组的物理存储,所以可以通过更为高效的直接“计算”来代替传统的存储后访问,解决了在存储超级大的二维数组时内存不够用的问题(前提是不需要存储的情况)

计算思路:

1.根据目标坐标,计算在存储的二维数组中的所在“圈数”(例如:上述的4*4的案例中,13,14,15,16为第二圈)

注意:为了好判断,这里将二维数组按中心点划分为了四个区,如图:
数组划分逻辑图

2.1根据计算得出的圈数,计算该圈的起始的第一个数*(例如:1是第一圈的起始数,13是第二圈的起始数)*

2.2根据计算得出的圈数,计算目标元素在该圈中的位置(例如:14在第二圈中的位置是2)

注意:这个起始数的计算,通过观察第二圈的尾数16,起始数13以及上一圈的尾数12,不难发现尾数和起始数及圈数的规律:本圈尾数=4*本圈长度-4+上圈尾数(16=4*2-4+12) 同时,下一圈起始数=本圈尾数+1(13=12+1)

3.根据目标圈的起始数及目标元素在圈中的位置,计算最终的元素值(例如:15=13+3-1)

代码实现:
回型类的实现:



/**
 * 
 * @author Lee.J.H  李健浩
 *
 */
public class HuiXing {
    

    private Long length;//回型存放的数组的规模  n*n
    /**
     * 该回型存放的数组的圈数  
     * 长度为基数的规模最内圈为n*n一个数,也算做一个内圈
     * 例如:5*5的回型  圈数为:5/2+1  第三圈为5*5=25一个数
     */
    private Long Cirs;

    public HuiXing(Long length){
        this.length=length;
        //计算圈数,向上取整
        this.Cirs=(long) Math.ceil(new Double(this.length)/2);
    }

    /**
     * 根据所在圈数,计算本圈的第一个数
     * 
     * @param cirNum  0表示最外圈  1...n表示内部第1...n圈
     * @return 如果目标圈数合法,返回目标圈的第一个数,否则抛出自定义异常
     * @throws OutOfCirNumberException 目标圈超过实际的圈数异常
     */
    private Long getFirstOfCir(long cirNum) throws OutOfCirNumberException{
        Long temp=0l;
        Long len=this.length;
        if(cirNum>this.Cirs){
            //目标圈数超过真实的圈数
            throw new OutOfCirNumberException(cirNum,this.Cirs);
        }else{
            //圈数合法,计算
            for(int i=
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值