N个数循环奇数位数的数组解法

原题是这样的:有N个数组成的数组,要求去除奇数位置上的数字,分别打印出这些数字;剩下的数字从新排列,继续去除其中技术位置上的数字,并打印这些数字;以此类推,直到只剩下最后一个数字,要求在屏幕上打印这些数字,并且显示最后剩下的一个数字在原来数组中的位置。

其实这是很有规律的,用数学方法解很方便。想法是第一次去除的是:{1,3,5,7….}全部的奇数,第二次去除的是{1,3,5,7,9…}×2,第三次去除的是{1,3,5,7,9}×2^2以此类推,很容易根据数学规律写出程式出来。

不巧的是下午头脑发热,一直想着数组,想着利用数组的晒法去求素数。结果愣是写了一个小时没写出来,回来冷静了下,把解决的过程记录下来。

首先,简单的描述下我的思路,其实直接,就是去模拟这个过程。比如这群数中都没有0。那么做一个循环,每间隔一位非零的数字就打印一个,并且把这个数字从新赋值为0。

想法很简单,在java中实现起来去很难。我写了一段非常糟糕的代码,打了很多补丁,测试的时候还是会报错。

说明:为了论述问题的方便,把所有的数看成一个boolean型数组,当这个数被去除时,这个位置的数组值就为false。

一开始我是想每次循环执行两步。每次循环中:第一步找到找到数组中第一个true值,把它的值变成false,第二步,找到数组中的第二个true值,它的值不变。这样写了代码。很糟糕,打了很多补丁,测试的时候还是会报错。代码我就省去了,写下我回来后的思考。

其实这样想法是没有问题的,关键是对于数组的操作。数组是很危险的类型,稍微不慎就会取值越过数组长度范围,导致报错,且这样的错误很难被发现。为此发明了多种方法来安全的操作数组。作为初学者的我,一直操作数组都是在for()中,以前for的下标在每次循环中安静的安全的递增1,从不做其他操作。这次却不同,出错的大部分原因在这里。

为此我总结了一个安全操作数组下标的方法,虽然看起来没有for那样的好看,但是其安全性以及灵活性得到了很大的提高。

它的基本结构如下:

while (bl[i] == false) {                                         //while条件
            i++;                   //对下标进行操作
            if (i >=n) {          //防止i的值出数组的长度
                                     ...                                //下面的操作可以多样化,为下次循环初始化值
        }
}

使用for(){};在大括号中对下标的值进行改写是有风险的,使用类似上述结构的语句可以有效的避免这种风险。

用这种方法为基础,以下是N个数,循环除去奇数位置数字,求最后一位数字的实现代码(java):

int n =100;

        boolean[] bl = new boolean[n];

        for (int i = 0; i < n; i++) {
            bl[i] = true;
        }                                                   //初始化,将所有的boolean数组值写出true。

        int count = 0;
        int i = 0;
        int k = 1;
        while (count != n - 1) {

            while (bl[i] == false) {
                i++;
                if (i >=n) {                        //越界,在这里意味着一个新的循环开始,{}为下次循环做准备
                    i = i % n;
                    System.out.println();
                    k = 1;
                } // 从头开始,保证必定能找到
            }
            if (k % 2 == 1) {
                bl[i] = false; // 将找到的数杀掉
            //    System.out.print((i + 1) + " be killed\t");
                count++;
            }
            k++;
            i++;
            if (i / n == 1) {
                i = i % n;
            //    System.out.println();
                k = 1;
            }
        }
        //System.out.println();
        while (bl[i] == false) {
            i++;
            if (i >=n) {
                i = i % n;
            }
        }
        System.out.println("第" + (i + 1) + "个人,未被杀");
    }
小弟也是新手,希望各位前辈多多指教。
posted @ 2015-04-18 02:30  谷粉  阅读(520)  评论(0编辑  收藏  举报