数组课后作业

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

按引用传递与按值传送数组类型方法参数的最大关键在于:

使用前者时,如果方法中有代码更改了数组元素的值,实际上是直接修改了原始的数组元素。

使用后者则没有这个问题,方法体中修改的仅是原始数组元素的一个拷贝。

 

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

package T6;

import java.io.*;

public class Qipan {

	private String[][] pan = new String[15][15];//定义棋盘及大小
	
	public void initpan()//初始化
	{
		for(int i = 0; i < 15; i++)
			for(int j = 0; j < 15; j++)
				pan[i][j] = "╋";
	}
	
	public void show()//棋盘输出
	{
		for(int i = 0; i < 15; i++)
		{
			for(int j = 0; j < 15; j++)
				System.out.print(pan[i][j]);
			System.out.println();
		}
	}
	
	public static void main(String[] args)throws Exception
	{
		Qipan qp = new Qipan();
		qp.initpan();
		qp.show();
		//这是用于获取键盘输入的方法
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String inputStr = null;
		System.out.println("请输入您下棋的座标,应以x,y的格式:");
		
		while ((inputStr = br.readLine()) != null)
		{
			//将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串
			String[] posStrArr = inputStr.split(",");
			//将2个字符串转换成用户下棋的座标
			int xPos = Integer.parseInt(posStrArr[0]);
			int yPos = Integer.parseInt(posStrArr[1]);
			//把对应的数组元素赋为"●"。
			qp.pan[xPos - 1][yPos - 1] = "●";				
			/*
			 电脑随机生成2个整数,作为电脑下棋的座标,赋给board数组。
			 还涉及
				1.座标的有效性,只能是数字,不能超出棋盘范围
				2.如果下的棋的点,不能重复下棋。
				3.每次下棋后,需要扫描谁赢了
			 */
			qp.show();
			System.out.println("请输入您下棋的座标,应以x,y的格式:");
		}
	}
}

  

程序中定义数组,初始化数组,只能实现自己下棋,不能实现人机对弈。

 

3.

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

源代码:

package T6;

//胡建峰,2016.11.02
//整数转化为汉字表达

import java.util.Scanner;

public class Hanzi 
{
	private String[] han = {"零" , "壹" , "贰" , "叁" , "肆" , "伍" , "陆" , "柒" , "捌" , "玖"};//数字汉字数组
	private String[] unit = {"十" , "百" , "千" , "万" , "十万" , "百万"};//单位汉字数组
	
	private String change(int n) {
		String result = "";//输出
		String num = String.valueOf(n);//n转化为string
		int length = num.length();//长度
		
		for(int i = 0; i < length; i ++)//添加汉字及单位,对0特殊
		{
			int x = num.charAt(i) - '0';
			if(x != 0)
			{
				if(i != length - 1)
					
				{			
					result += han[x];
					result += unit[length - i - 2];
				}
				else
					result += han[x];
			}
			else
			{
				if(length == 1)
					result += han[0];
				else if(result.charAt(result.length() - 1) != '零')
					result += han[0];
			}			
		}
		if(result.length() == 1)
			return result;
		else if(result.charAt(result.length() - 1) == '零')
			return result.substring(0, result.length() - 1);
		else
			return result;
	}
	
	public static void main(String[] args) {
		System.out.print("请输入一个整数(最多六位数):");//输入
		Scanner s = new Scanner(System.in);
		int num = s.nextInt();
		s.close();
		Hanzi hz = new Hanzi();
		
		System.out.println("转化为汉字表达为:" + hz.change(num));//输出
	}	

}

  运行结果:

多次测试可以实现六位数字的转化。

 

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

源码:

package T6;

//胡建峰,2016.11.06
//整数转化为汉字表达

import java.util.Scanner;

public class Hanzi2 {

	private String[] han = {"零" , "壹" , "贰" , "叁" , "肆" , "伍" , "陆" , "柒" , "捌" , "玖"};//数字汉字数组
	private String[] unit = {"十" , "百" , "千" , "万" , "十万" , "百万"};//单位汉字数组
	
	private String change(double n) {
		String result = "";//输出
		String num = String.valueOf(n);//n转化为string
		int length = num.indexOf(".");//长度
		int len = num.length();
		
		for(int i = 0; i < length; i ++)//添加汉字及单位,对0特殊
		{
			int x = num.charAt(i) - '0';
			if(x != 0)
			{
				if(i != length - 1)
					
				{			
					result += han[x];
					result += unit[length - i - 2];
				}
				else
					result += han[x];
			}
			else
			{
				if(length == 1)
					result += han[0];
				else if(result.charAt(result.length() - 1) != '零')
					result += han[0];
			}			
		}
		if(result.charAt(result.length() - 1) == '零')//为.前加元
			result = result.substring(0, result.length() - 1) + "元";
		else
			result += "元";
		
		//小数转化
		for(int j = length + 1; j < len; j++)
		{
			int y = num.charAt(j) - '0';
			if(j == length + 1)
			{
				if(y != 0)
					result += (han[y] + "角");
				else if(len - j == 2)
					result += "零";
			}
			else
			{
				if(y != 0)
					result += (han[y] + "分");
			}
		}
		
		return result;//结果输出
	}
	
	public static void main(String[] args) {
		System.out.print("请输入一个钱数(最多六位数):");//输入
		Scanner s = new Scanner(System.in);
		double num = s.nextDouble();
		s.close();
		Hanzi2 hz = new Hanzi2();
		
		System.out.println("转化为汉字表达为:" + hz.change(num));//输出
	}	

}

  结果截图:

对小数点前的转化后加个元,再对小数点后的判断。

 

4.

(1)

源代码:

package T6;

//胡建峰,2016.11.06
//大数运算

import java.util.Scanner;

public class Bigint {

	private int [] big = new int[20];
	
	public void init()
	{
		for(int i = 0; i < 20; i++)
			big[i] = 0;
	}
	
	public void input(String s)
	{
		for(int i = 0 ; i < s.length(); i++)
			big[s.length() - i - 1] = s.charAt(i) - '0';
	}

	public void show()
	{
		int al = 0;
		for(int i = 19;i >= 0 ; i--)
			if(big[i] != 0)
			{
				al = i;
				break;
			}
			
		for(int j = 0;j <= al; j++)
			System.out.print(big[al - j]);
	}
	
	public boolean bigger(Bigint a,Bigint b)
	{
		int al = 0,bl = 0;
		for(int i = 19;i >= 0 ; i--)
			if(a.big[i] != 0)
			{
				al = i;
				break;
			}
		
		for(int i = 19;i >= 0 ; i--)
			if(b.big[i] != 0)
			{
				bl = i;
				break;
			}
		if(al > bl)
			return true;
		else if(al < bl)
			return false;
		else
		{
			if(a.big[al] > b.big[al])
				return true;
			else if(a.big[al] < b.big[al])
				return false;
			else
			{
				while(a.big[al] == b.big[al])
				{
					if(al != 0)
					{
						if(a.big[al - 1] > b.big[al - 1])
							return true;
						else if(a.big[al - 1] < b.big[al - 1])
							return false;
						else
							al --;
					}
					else
						return true;
				}
			}
		}
		return false;
	}
	
	public void add(Bigint a,Bigint b)
	{
		Bigint result = new Bigint();
		result.init();
		
		if(a.bigger(a, b))
		{
			int l = 0,temp;
			for(int i = 19;i >= 0 ; i--)
				if(a.big[i] != 0)
				{
					l = i;
					break;
				}
			l++;
			for(int j = 0;j < l; j++)
			{
				temp = a.big[j] + b.big[j];
				if(temp > 9)
				{
					result.big[j] = (temp - 10);
					result.big[j + 1] += 1;
				}
				else
					result.big[j] = temp;
			}
		}
		else
		{
			int l = 0,temp;
			for(int i = 19;i >= 0 ; i--)
				if(b.big[i] != 0)
				{
					l = i;
					break;
				}
			l++;
			for(int j = 0;j < l; j++)
			{
				temp = a.big[j] + b.big[j];
				if(temp > 9)
				{
					result.big[j] = (temp - 10);
					result.big[j + 1] += 1;
				}
				else
					result.big[j] = temp;
			}
		}
		result.show();
		System.out.print("\n");
	}
	
	public void sub(Bigint a,Bigint b)
	{
		Bigint result = new Bigint();
		result.init();
		
		if(a.bigger(a, b))
		{
			int l = 0,temp;
			for(int i = 19;i >= 0 ; i--)
				if(a.big[i] != 0)
				{
					l = i;
					break;
				}
			
			for(int j = 0;j < l; j++)
			{
				temp = a.big[j] - b.big[j];
				if(temp < 0)
				{
					result.big[j] = (temp + 10);
					result.big[j + 1] -= 1;
				}
				else
					result.big[j] = temp;
			}
		}
		else
		{
			System.out.print("-");
			int l = 0,temp;
			for(int i = 19;i >= 0 ; i--)
				if(b.big[i] != 0)
				{
					l = i;
					break;
				}
			
			for(int j = 0;j < l; j++)
			{
				temp = a.big[j] - b.big[j];
				if(temp < 0)
				{
					result.big[j] = (temp + 10);
					result.big[j + 1] -= 1;
				}
				else
					result.big[j] = temp;
			}
		}
		result.show();
		System.out.print("\n");
	}
	
	public static void main(String[] args) {
		Bigint b1 = new Bigint();
		b1.init(); 
		Bigint b2 = new Bigint();
		b2.init();
		
		System.out.println("请输入两个正的大数:");
		Scanner s = new Scanner(System.in);
		String str1 = s.next();
		String str2 = s.next();
		s.close();
		b1.input(str1);
		b2.input(str2);
		
		System.out.print(str1 + "+" + str2 + "=");
		b1.add(b1, b2);
		System.out.print(str1 + "-" + str2 + "=");
		b1.sub(b1, b2);
	}

}

  结果截图:

小结:通过定义int数组来实现大数相加相减,初始化,输入后将数字反过来存,然后加法是比较大小,补0,然后每位相加,大于9的进1,最后再反过来输出。减法为小于0的,上一位减1。

 

(2)其实要实现大整数类也不难,简单一想,我们可以把一个很大很长的数分成多个短小的数,然后保存在一个数组中,大数之间的四则运算及其它运算都是通过数组完成.JDK就是这么实现的.JDK的BigInteger类里用一个int数组来保存数据。

   分析该构造函数源码之前,先想一个问题,构造一个大整数开始最主要的问题是如何把一个大数保存到mag数组中,通常我们自己实现的话很有可能是数组每块存一位数(假设大数为10进制),但这样的话想想也知道太浪费空间,因为一个int值可以保存远不止一位十进制数.   Java语言里每个int值大小范围是-2^31至2^31-1 即-2147483648~2147483647,因此一个int值最多可保存一个10位十进制的整数,但是为了防止超出范围(2222222222这样的数int已经无法存储),保险的方式就是每个int保存9位的十进制整数.JDK里的mag数组即是这样的保存方式.因此若一串数为:18927348347389543834934878.  划分之后就为:18927348  |  347389543  |  834934878. mag[0]保存18927348 ,mag[1]保存347389543 ,mag[2]保存834934878. 这样划分可以最大利用每一个int值,使得mag数组占用更小的空间.当然这只是第一步.  划分的问题还没有说完,上述构造函数能够支持不同进制的数,最终转换到mag数组里面的数都是十进制,那么不同进制的大数,每次选择划分的位数就不相同,若是2进制,每次就可以选择30位来存储到一个int数中(int值大小范围是-2^31至2^31-1),若是3进制3^19<2147483647<3^20,因此每次就可以选择19位来存储到一个int数中,对于不同进制每次选择的位数不同,因此需要有一个数组来保存不同进制应当选择的位数。

bitsPerDigit是用于计算radix进制m个有效数字  转换成2进制所需bit位[假设所需x位],我们来看一个计算式:radix^m - 1 = 2^x - 1, 解这个方程得 x = m * log2(radix) , 现在m是几位有效数字,常量就只有 log2(radix),这是一个小数,这不是我们喜欢的,所以我们希望用一个整数来表示,于是我们把他扩大1024倍然后取整,例如3进制 bitsPerDigit[3] = 1624(我用计算器算了一下 x = log2(3) * 1024 ~= 1623.xxx) ,我们队这个数取整,为什么取1624呢,其实只要不超过太多都可以的,你可以设置为1620,1600,1610...;”

(3)

乘法代码:

public static String multiply(String x, String y){
        if(isNullAndNotNumber(x,y)){
            return null;
        }
       
        if(x.equals("0") || y.equals("0")){
            return "0";
        }
       
        int[] a = toIntArray(x);
        int[] b = toIntArray(y);
       
        int[] temp1 = null;
        int[] temp2 = null;
       
        int enter = 0;
        int result = 0;
        int count = 1;
        for(int i=(b.length -1); i>=0; i--){
            temp1 = new int[a.length+(++count)];
            enter = 0;
            for(int j=a.length-1; j>=0; j--){
                result = a[j]*b[i]+enter;
                temp1[j+2] = result;
                enter = result/10;
            }
            temp1[1] = enter;
            temp1[0] = 0;
            temp2 = addIntArray(temp1, temp2);
        }
       
        StringBuffer sb = new StringBuffer(32);
        for(int j=0; j<temp2.length; j++){
            if(temp2[j] == 0 && sb.length() == 0){
                continue;
            } else {
                sb.append(temp2[j]);
            }
        }
       
        return sb.toString();
    }

  除法代码:

 public static List<String> divide(String x, String y) {
        if(isNullAndNotNumber(x,y)){
            return null;
        }
       
        List<String> returnList = new ArrayList<String>();
        if(y.equals("0") || x.equals("0")){
            returnList.add("0");
            returnList.add("0");
            return returnList;
        }
       
        String quotient = "";//quotient
        String remainder = "";//remainder
        if (isBig(x, y) == false) {
            remainder = y;
            quotient = "0";
           
            returnList.add(quotient);
            returnList.add(remainder);
            return returnList;
        }
        int i = y.length();
        remainder = x.substring(0, i);
       
        do {
            for (int j = 9; j >= 1; j--) {
                if ((isBig(remainder, multiply(y, Integer.valueOf(j).toString())) == false) && (isBig(remainder, multiply(y, Integer.valueOf(j - 1).toString())) == true)) {
                    if((j-1) > 0){
                        quotient += (j-1);
                    }
                    remainder = subtract(remainder, multiply(y, Integer.valueOf(j-1).toString()));
                    break;
                }
            }
            int len = remainder.length();
            for (int k = 0; (k < y.length() - len) && (i < x.length()); k++) {
                remainder += x.charAt(i);
                i++;
                if (isBig(remainder, y) == false) {
                    quotient += "0";
                }
            }
            if ((isBig(remainder, y) == false) && (i < x.length())) {
                remainder += x.charAt(i);
                i++;
            }
        } while (i < x.length());
        for (int j = 9; j >= 1; j--) {
            if ((isBig(remainder, multiply(y, Integer.valueOf(j).toString())) == false) && (isBig(remainder, multiply(y, Integer.valueOf(j - 1).toString())) == true)) {
                if((j-1) > 0){
                    quotient += (j-1);
                }
                remainder = subtract(remainder, multiply(y, Integer.valueOf(j-1).toString()));
                break;
            }
        }
       
        returnList.add(quotient);
        returnList.add(remainder);
        return returnList;
    }

  阶乘为一个乘法递归算法。

小结:在网上查到了算法,但是还没有添加至我的算法中,后我会修改。

 

课后作业:

1.设计思路:定义一个输出结果和一个数组,初始化数组的时候为数组赋随机值,同时求和,然后用窗口输出结果。最后美化一下输出。

2.程序流程图:

3.源程序代码:

package T6;

import java.util.Random;

//胡建峰,2016.11.2
//随机生成10个数,求和(数组)

import javax.swing.*;

public class RandomSum {

	public static void main(String[] args) {
		String output="数组元素为:\n";//定义输出
		int sum = 0;
		int a[] = new int[10];//数组
		
		for(int i = 0; i < 10; i++ )//生成1-100的随机数赋给数组,添加输出和计算和
		{
			a[i] = new Random().nextInt(99)+1;
			output += (a[i] + "\t");
			sum += a[i];
			if((i + 1) % 2 == 0)
				output += "\n";
		}
		
		output += ("数组和为:" + sum); //输出和
		JTextArea outputArea = new JTextArea( 8, 10 );//输出消息框
	    outputArea.setText( output );

	    JOptionPane.showMessageDialog( null, outputArea,
	         "result", JOptionPane.PLAIN_MESSAGE );

	      System.exit( 0 );

	}

}

  

4.结果截图:

5.总结:

在使用数组时必须在主函数中对其初始化,其他操作注意下就可以了。

posted @ 2016-11-06 19:06  丶枫  阅读(233)  评论(0编辑  收藏  举报