首页 > 代码库 > 动手动脑(数组)

动手动脑(数组)

1.阅读并运行示例PassArray.java,观察并分析程序输出的结果,小结,然后与下页幻灯片所讲的内容进行对照。

源代码:

// PassArray.java

// Passing arrays and individual array elements to methods

 

public class PassArray {   

    public static void main(String[] args) {

        int a[] = { 1, 2, 3, 4, 5 };

        String output = "The values of the original array are:\n";

 

        for (int i = 0; i < a.length; i++)

            output += "   " + a[i];

 

        output += "\n\nEffects of passing array " + "element call-by-value:\n"

                + "a[3] before modifyElement: " + a[3];

 

        modifyElement(a[3]);

 

        output += "\na[3] after modifyElement: " + a[3];

 

        output += "\n Effects of passing entire array by reference";

 

        modifyArray(a); // array a passed call-by-reference

 

        output += "\n\nThe values of the modified array are:\n";

 

        for (int i = 0; i < a.length; i++)

            output += "   " + a[i];

        

        System.out.println(output);

    }

 

    public static void modifyArray(int b[]) {

        for (int j = 0; j < b.length; j++)

            b[j] *= 2;

    }

 

    public static void modifyElement(int e) {

        e *= 2;

    }

}

结果:

技术分享

分析:

    引用传递:如果方法中有代码更改了数组元素的值,则直接修改了原始的数组元素,因为它将其地址传过去,原来地址所存储的数据已经改变。

按值传递:方法体中修改的仅是原始数组元素的一个拷贝,只是将数据的值传递过去进行运算,原来的数据值不变。

 

2.以下代码的输出结果是什么?为什么会有这个结果?

源代码:

public class ArrayInRam {

    public static void main(String[] args) {

        // 定义并初始化数组,使用静态初始化

        int[] a = { 5, 7, 20 };

        System.out.println("a数组中的元素:");

        // 循环输出a数组的元素

        for (int i = 0; i < a.length; i++) {

            System.out.print(a[i] + ",");

        }

        // 定义并初始化数组b,使用动态初始化

        int[] b = new int[4];

        // 输出b数组的长度

        System.out.println("\nb数组的初始长度为:" + b.length);

        // 因为aint[]类型,b也是int[]类型,所以可以将a的值赋给b

        // 也就是让b引用指向a引用指向的数组

        b = a;

        System.out.println("b=a,赋值之后,b数组的元素为:");

        // 循环输出b数组的元素

        for (int i = 0; i < b.length; i++) {

            System.out.print(b[i] + ",");

        }

        // 再次输出b数组的长度

        System.out.println("\n赋值之后,b数组的长度为:" + b.length);

    }

}

结果:

技术分享

分析:

b = a 赋值不是将a的值赋值给b,而是将对象整体赋值给b,将a的地址传递给b,b指向a的内存空间,所以b的长度与a相等。

 

3.阅读程序WhatDoesThisDo.java, 解释程序所完成的功能。

源程序:

public class WhatDoesThisDo {

    static int result;

    static String output;

 

    public static void main(String[] args) {

        int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        result = whatIsThis(a, a.length);

        output = "Result is: " + result;

        System.out.println(output);

    }

 

    public static int whatIsThis(int b[], int size) {

        if (size == 1)

            return b[0];

        else

            return b[size - 1] + whatIsThis(b, size - 1);

    }

}

结果:

 技术分享

分析:

递归实现数组内各个数的和。

 

4.阅读程序WhatDoesThisDo2.java, 解释程序所完成的功能。

源程序:

public class WhatDoesThisDo2 {

    public static void main(String[] args) {

        int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10  };

        StringBuilder sbBuilder=new StringBuilder();

        someFunction(a, 0, sbBuilder);

        System.out.println(sbBuilder);

}

 

    public static void someFunction(int b[], int x, StringBuilder out){

        if (x < b.length) {

            someFunction(b, x + 1, out);

            out.append(b[x] + "  ");

        }

    }

}

结果:

技术分享               

分析:

递归实现数组内数据逆序输出。

 

5.Arrays类中的静态方法

  运行TestArrays.java,了解Arrays中的一些重要方法的用法。

源程序:

import java.util.*;

 

public class TestArrays

{

    public static void main(String[] args) {

        //定义一个a数组

        int[] a = new int[]{3, 4 , 5, 6};

        //定义一个a2数组

        int[] a2 = new int[]{3, 4 , 5, 6};

        //a数组和a2数组的长度相等,每个元素依次相等,将输出true

        System.out.println("a数组和a2数组是否相等:" + Arrays.equals(a , a2));

        //通过复制a数组,生成一个新的b数组       

        int[] b = Arrays.copyOf(a, 6);

        System.out.println("a数组和b数组是否相等:" + Arrays.equals(a , b));

        //输出b数组的元素,将输出[3, 4, 5, 6, 0, 0]

        System.out.println("b数组的元素为:" + Arrays.toString(b));

        //b数组的第3个元素(包括)到第5个元素(不包括)赋为1

        Arrays.fill(b , 2, 4 , 1);

        //输出b数组的元素,将输出[3, 4, 1, 1, 0, 0]

        System.out.println("b数组的元素为:" + Arrays.toString(b));

        //b数组进行排序

        Arrays.sort(b);

        //输出b数组的元素,将输出[0, 0, 1, 1, 3, 4]

        System.out.println("b数组的元素为:" + Arrays.toString(b));    

    }

}

结果:

技术分享

分析:

    Arrays.equals(a , a2):判断两数组数据值是否相等。

    Arrays.copyOf(T[] original, int newLength):通过复制原数组,生成一个新的数组,长度为newLength。

    Arrays.toString(b):将数组转化为字符串输出。

    Arrays.fill(b , 2, 4 , 1):将数组b中3到5的元素用1来填充。

    Arrays.sort(b):将数组b进行排序。

 

6.阅读QiPan.java示例程序了解如何利用二维数组和循环语句绘制五子棋盘。

源程序:

import java.io.*;

 

public class QiPan

{

    //定义一个二维数组来充当棋盘

    private String[][] board;

    //定义棋盘的大小

    private static int BOARD_SIZE = 15;

    public void initBoard()

    {

        //初始化棋盘数组

        board = new String[BOARD_SIZE][BOARD_SIZE];

        //把每个元素赋为"╋",用于在控制台画出棋盘

        for (int i = 0 ; i < BOARD_SIZE ; i++)

        {

            for ( int j = 0 ; j < BOARD_SIZE ; j++)

            {

                board[i][j] = "╋";

            }

        }

    }

    //在控制台输出棋盘的方法

    public void printBoard()

    {

        //打印每个数组元素

        for (int i = 0 ; i < BOARD_SIZE ; i++)

        {

            for ( int j = 0 ; j < BOARD_SIZE ; j++)

            {

                //打印数组元素后不换行

                System.out.print(board[i][j]);

            }

            //每打印完一行数组元素后输出一个换行符

            System.out.print("\n");

        }

    }

    public static void main(String[] args)throws Exception

    {

        QiPan gb = new QiPan();

        gb.initBoard();

        gb.printBoard();

        //这是用于获取键盘输入的方法

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String inputStr = null;

        System.out.println("请输入您下棋的座标,应以x,y的格式:");

        br.readLine();  //每当在键盘上输入一行内容按回车,刚输入的内容将被 

                      br读取到。

        while ((inputStr = br.readLine()) != null)

        {

            //将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串

            String[] posStrArr = inputStr.split(",");

            //2个字符串转换成用户下棋的座标

            int xPos = Integer.parseInt(posStrArr[0]);

            int yPos = Integer.parseInt(posStrArr[1]);

            //把对应的数组元素赋为"●"

            gb.board[xPos - 1][yPos - 1] = "●";                

            /*

             电脑随机生成2个整数,作为电脑下棋的座标,赋给board数组。

             还涉及

                1.座标的有效性,只能是数字,不能超出棋盘范围

                2.如果下的棋的点,不能重复下棋。

                3.每次下棋后,需要扫描谁赢了

             */

            gb.printBoard();

            System.out.println("请输入您下棋的座标,应以x,y的格式:");

        }

    }

}

结果:

技术分享

分析:

利用二维数组绘制棋盘并规定棋盘大小即二维数组的行和列;利用双层循环语句为二维数组赋值;输出数组时要利用双层循环语句,但要注意换行问题。

 

7.请编写一个程序将一个整数转换为汉字读法字符串。比如“1123”转换为“一千一百二十三”。

源程序:

public class Num1Rmb

{

    private String[] hanArr = {"" , "" , "" , "" , "" ,

        "" , "" , "" , "" , ""};

    private String[] unitArr = {"" , "" , "","","十万","百万"};

 

    /*

      把一个四位的数字字符串变成汉字字符串

      @param numStr 需要被转换的四位的数字字符串

      @return 四位的数字字符串被转换成的汉字字符串。

     */

    private String toHanStr(String numStr)

    {

        String result = "";

        int numLen = numStr.length();

        //依次遍历数字字符串的每一位数字

        for (int i = 0 ; i < numLen ; i++ )

        {

            //char型数字转换成的int型数字,因为它们的ASCII码值恰好

             相差48

            //因此把char型数字减去48得到int型数字,例如‘4‘被转换成4

            int num = numStr.charAt(i) - 48;

            //如果不是最后一位数字,而且数字不是零,则需要添加单位(千、

             百、十)

            if ( i != numLen - 1 && num != 0)

            {

                result += hanArr[num] + unitArr[numLen - 2 - i];

            }

            //否则不要添加单位

            else

            {

                

                //上一个数是否为,不为时就添加

                if(result.length()>0 && hanArr[num].equals("") && result.charAt(result.length()-1)==‘‘)

                    continue;

                result += hanArr[num];

            }

        }

        //只有个位数,直接返回

        if(result.length()==1)

            return result;      

        int index=result.length()-1;

        while(result.charAt(index)==‘‘){

            index--;

        }

        if(index!=result.length()-1)

            return result.substring(0,index+1);

        else {

            return result;

        }

    }

 

      public static void main(String[] args) {       

            Num2Rmb nr = new Num2Rmb();

            Scanner in=new Scanner(System.in);

            System.out.println("请输入整数:");

            String num= in.next();

            System.out.println("汉字读法为:"+nr.toHanStr(num));

          }

}

结果:

技术分享

分析:

利用数组将数字大写形式以及个十百千等表示出来,注意遇到0以及个位数的判断。

 

8.更进一步,能否将数字表示的金额改为“汉字表达? 比如将“¥123.52”转换为“壹佰贰拾叁元伍角贰分”。

源程序:

public class Num1Rmb

{

    private String[] hanArr = {"" , "" , "" , "" , "" , "" , "" , "" , "" , ""};

    private String[] unitArr = {"","","","" ,"" , "","","十万","百万"};

    

    private String toHanStr(String numStr){    

        String result = "";

        int point = numStr.indexOf(".");

        String integer = numStr.substring(0,point);//取该字符串整数部分

        String decimal = numStr.substring(point+1);//取该字符串小数部分

        String newNum = integer + decimal;//合成一个新的字符串

        int numLen = newNum.length();

        //依次遍历数字字符串的每一位数字

        for (int i = 0 ; i < numLen ; i++ )

        {

            //char型数字转换成的int型数字,因为它们的ASCII码值恰好

             相差48

            //因此把char型数字减去48得到int型数字,例如‘4‘被转换成4

            int num = newNum.charAt(i) - 48;

            //如果不是最后一位数字,而且数字不是零,则需要添加单位(千、

             百、十)

            if ( num != 0)

            {

                result += hanArr[num] + unitArr[numLen -1 - i];

            }

            //否则不要添加单位

            else

            {

                

                //上一个数是否为,不为时就添加

                if(result.length()>0 && hanArr[num].equals("") && result.charAt(result.length()-1)==‘‘)

                    continue;

                result += hanArr[num];

            }

        }

        //只有个位数,直接返回

        if(result.length()==1)

            return result;     

        int index=result.length()-1;

        while(result.charAt(index)==‘‘){

            index--;

        }

        if(index!=result.length()-1)

            return result.substring(0,index+1);

        else {

            return result;

        }

    }

    public static void main(String[] args) {        

        Num1Rmb nr = new Num1Rmb();

        System.out.println("(只支持两位小数,整数部分只支持百万)");

        //测试把一个四位的数字字符串变成汉字字符串

        System.out.println(nr.toHanStr("1.00"));

        System.out.println(nr.toHanStr("10.01"));

        System.out.println(nr.toHanStr("123.52"));

        System.out.println(nr.toHanStr("1000.56"));       

    }

}

结果:

技术分享

分析:

只需在上一个程序上稍作修改,将小数点去掉合成一个新的字符串,并在数组中添加“角”“分”“元”即可。

 

9.前面几讲介绍过JDK所提供的BigInteger能完成大数计算,如果不用它,直接使用数组表达大数,你能实现相同的功能吗?

  要求:(1)用你的大数类实现加和减两个功能;

           2)阅读BigInteger类源码,弄清楚它是使用什么算法实现加减乘除四种运算的;

           3)通过互联网查找大数运算的相关资料,给你的大数类添加乘、除、求阶乘等其它功能。

源程序:

package Test;

import java.util.Scanner;

 

public class Test{

        public static int[]add(int []a,int []b){

            int digit=0;  //位数

            int[]c=new int[a.length];

            for(int i=a.length-1;i>=0;i--)

            {

                c[i]=a[i]+b[i]+digit;

                if(c[i]<10)

                    digit=0;

                else

                {

                    c[i]=c[i]-10;

                    digit=1;

                }

            }

            return c;

    }

        public static int []sub(int []a,int[]b,int w) {

            int digit=0;

            int[]c=new int[a.length];

            for(int i=a.length-1;i>=0;i--)

            {

                if(w<=0)

                {

                    c[i]=b[i]-a[i]-digit;

                    if(c[i]>=0)

                    {   digit=0; }

                    else

                    {

                        c[i]=c[i]+10;

                        digit=1;

                    }

                }

                    else

                    {

                        c[i]=a[i]-b[i]-digit;

                        if(c[i]>=0)

                        {digit=0;}

                        else

                        {

                            c[i]=c[i]+10;

                            digit=1;

                        }

                 }

             }

                return c;

            }

            public static void main(String[]args){

                int a[]=new int[50];

                int b[]=new int[50];

                int m=0;

                int n=0;

                int s=0;

                int t=0;int w=0;

                Scanner in=new Scanner(System.in);

                System.out.println("请输入第一个大数:");

                String aa=in.next();

                System.out.println("请输入第二个大数:");

                String bb=in.next();

                m=a.length-aa.length();

                n=b.length-bb.length();

                if(aa.length()>bb.length())

                {  w=1;  }

                else if (aa.length()<bb.length())

                {  w=-1;  }

                else

                    {w = aa.compareTo(bb);}

                for (int i = 0; i < aa.length(); i++)

                {   a[m++] = aa.charAt(i) - 48;  }

                for (int j = 0; j < bb.length(); j++)

                {  b[n++] = bb.charAt(j) - 48;  }

                    int[] c = Test1.add(a, b);

                    for (int k = 0; k < c.length; k++)

                    {

                        if (c[k] > 0)

                        {

                        s = k;

                        break;

                        }

                    }

                    System.out.print("大数相加的结果为:");

                    for (int i = s; i < c.length; i++)

          {  System.out.print(c[i]); }

                    System.out.println();

                    int[] d = Test1.sub(a, b, w);

                    for (int k = 0; k < d.length; k++)

                    {

                        if (d[k] > 0)

                        {

                        t = k;

                        break;

                        }

                    }

                    System.out.print("大数相减的结果为:");

                    if (w < 0)

                    System.out.print("-");

                    for (int i = t; i < d.length; i++)

                    {  System.out.print(d[i]); }

                    System.out.println();

                    System.out.println();

                    System.out.println();

                    System.out.println(); 

                    }

}

结果:

技术分享

分析:

    利用数组实现大数的表示;大数的加减即将数的每个位分开计算,相加大于10或不够减分情况讨论即可。

 

10.随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中。

设计思路:

    先定义一个长度为10的数组,利用random生成随机数,利用for循环将生成的随机数赋给数组,再利用面板进行输出数组中的数和产生的随机数之和。

程序流程图:

 技术分享                                              

源程序:

package Shuzu;

 

import javax.swing.JOptionPane;

 

public class Shuzu {

    public static void main(String[]args){

        int []b=new int[10];

        int sum=0;

        String output = "101000以内的随机数为 ";

        for(int i=0;i<b.length;i++)

        {

            int temp=(int)(Math.random()*100);

            b[i]=temp;

            output+=" "+b[i]+"\n";

            sum+=b[i];

        }

        output+="随机数之和为:"+sum;

         JOptionPane.showMessageDialog( null,output,"结果",

                 JOptionPane.INFORMATION_MESSAGE );

    }

}

结果:

 技术分享

分析:

    如何把生成的随机数赋给数组? 利用for循环,将生成的随机数即可赋给数组,其次就是遍历输出时,要实现输出数组,String一个output进行输出,注意输出时output+=" "+b[i]+"\n";才能得到输出。

动手动脑(数组)