黑马程序员——函数与数组:精打细算的年级组长的利器

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

去森林公园开篝火晚会

黑马高中高一年级准备去森林公园举办一次篝火晚会,年级组长经过实地长期深入考察,发现森林公园有一项鲜为人知的福利:买罐装可乐,喝完后可以直接在现场用3个易拉罐再换一罐可乐。为了给学校节省开支,同时又为了能够让每个学生都能喝上可乐,年级组长陷入了深深的沉思,最终他想起了JAVA...

Version1:先试试50个人买多少就够了?

/**
 * 
 * @author Woo
 *分析:这个问题的关键是找到循环终止的条件
 *在这里的终止条件是:每个人都正好得到了一罐可乐
 *即:最终得到的可乐罐数 = 这个班级的人数
 *所以首先要考虑两个变量:
 *最终得到的可乐罐数:colaSum
 *这个班级的人数:studentsSum
 *由于3个罐子可以再换一罐可乐,因为最终实际购买的可乐罐数并不等于最终得到的可乐罐数
 *因此还需要一个变量:enoughCan,它作为最终的函数返回值,返回给调用者
 *可以以一种全局性的思维来思考这个问题,设想问题的最终情况
 *此时实际购买的enoughCan正好全部喝完,还一个都没换,这时再一下子用enoughCan的罐子换了若干罐可乐
 *这若干罐可乐 + enoughCan 就等于 studentsSum
 *其实如果在if循环中增加一个计数器,就会发现,这个计数器的值就是“若干罐”的“若干”
 *而enoughCan其实就是while循环的计数器
 *即while循环的次数 + if循环的次数 = 最终的学生数
 */


public class Function {
	//主函数:负责调用
	public static void main(String[] args) {
		int students = 50;
		System.out.println(students + "人只要买: " + getCount(students) + "罐就够了!");
	}

/*	Methods的格式
 	修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,)
	{
			执行语句;
			return 返回值;
	}

 */
	public static int getCount(int studentsSum){
		
		int colaSum = 0;
		int enoughCan = 0;
		
		while(colaSum < studentsSum){//最终得到的可乐罐数 = 这个班级的人数,循环终止
			enoughCan++;//相当于累加器,记录循环执行的次数
			colaSum++;
			if(colaSum % 3 == 0){//3个易拉罐再换一罐可乐
				colaSum++;
			}
		}
		
		return enoughCan;
	}
}/*
 程序输出结果:
 50人只要买: 34罐就够了!
 
 */

Version2:能不能从键盘上输入一个值,就返回一个结果?

/**
 * 
 * @author Woo
 * 
 */

import java.util.Scanner;//导入包
public class Function {
	
	static Scanner sc = new Scanner(System.in);//键盘输入定义在主函数之前
	static int students;//属于类的变量
	
	//主函数:负责调用
	public static void main(String[] args) {
		while(true){//从键盘不断输入数据
			students = inputStudentsNumber();//把该方法的返回值放入students变量中
			System.out.println(students+ "人只要买: " + getCount(students) + "罐就够了!");
		}
	}


	public static int getCount(int studentsSum){
		
		int colaSum = 0;
		int enoughCan = 0;
		
		while(colaSum < studentsSum){//最终得到的可乐罐数 = 这个班级的人数,循环终止
			enoughCan++;//相当于累加器,记录循环执行的次数
			colaSum++;
			if(colaSum % 3 == 0){//3个易拉罐再换一罐可乐
				colaSum++;
			}
		}
		
		return enoughCan;
	}
	
	//输入学生人数的方法
	public static int inputStudentsNumber(){
		while(true){//如果没有while(true)这句语句,则输入99这个错误数据后,会输出学生人数输入有误,但接着又输出99人只要买: 67罐就够了!
			System.out.println("班级有多少人?");
			int students = sc.nextInt();
			if((students < 0) || students >= 60){
				System.out.println("学生人数输入有误");
			}else
			return students;
		}

	}
}

Version3:能不能利用数组一下子进行处理?

/**
 * 
 * @author Woo
 * 高一年级一共有3个班级:
 * 1班有50个人、2班45人、3班48人
 * 年级组长利用数组批量来处理这个问题,
 * 不用再用键盘一个个输入了
 */
public class ArrayCola {
	//主函数:负责调用
	public static void main(String[] args) {
		
		/*一维数组的初始化方式:
		 * 元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
		 * int[] arr = new int[3];
		 * 或int[] arr = {,,};
		 */
		
		int[] students = {50,45,48};//定义了一个1维数组
		
		for(int i = 0; i < students.length; i++){//遍历一维数组的基本方法,i的范围使用students.length比直接使用3好
			System.out.println(students[i] + "人只要买: " + getCount(students[i]) + "罐就够了!");
		}
		
	}


	//使用数组之后,该方法未作任何改变,相当于复用了
	public static int getCount(int studentsSum){
		
		int colaSum = 0;
		int enoughCan = 0;
		
		while(colaSum < studentsSum){//最终得到的可乐罐数 = 这个班级的人数,循环终止
			enoughCan++;//相当于累加器,记录循环执行的次数
			colaSum++;
			if(colaSum % 3 == 0){//3个易拉罐再换一罐可乐
				colaSum++;
			}
		}
		
		return enoughCan;
	}
}

/*
程序输出结果:

50人只要买: 34罐就够了!
45人只要买: 31罐就够了!
48人只要买: 33罐就够了!


 */

Version4:校长的新要求

/**
 * 
 * @author Woo
 * 全校一共三个年级
 * 高一1班:50人、高一2班:45人、高一3班:48人
 * 高二1班:54人、高二2班:49人、高二3班:52人
 * 高三1班:39人、高三2班:42人、高三3班:41人、高三4班:38人
 * 校长看年级组长活动策划得不错,想让全校都参加,需要安排车子
 * 想让他算一算以下几个问题:
 * 1.学校总共人数有多少?
 * 2.人数最多的班级是哪个班,有多少人?
 */


public class HeadmasterReq {
	public static void main(String[] args) {
		int arr[][] = {{50,45,48},{54,49,52},{39,42,41,38}};//初始化了一个二维数组,其中有三个一维数组
		
		//求和
		//int studentsSum = getSum(arr);这句话可以省略,直接在输出语句中使用getSum,传入数组名
		System.out.println("全校学生人数的总和是" + getSum(arr) + "人");
		
		//求最大值
		System.out.println("全校人数最多的班级是:" + "高" + getMax(arr)[0] + "(" + getMax(arr)[1] + ")班," + "总共有:" + getMax(arr)[2] + "人");
			
	}
	
	//方法1:获取2维数组的和
	public static int getSum(int arr[][]){
		
		int sum = 0;
		
		for(int i = 0; i < arr.length; i++){
			for(int j = 0; j < arr[i].length; j++){
				sum += arr[i][j];
			}
		}
		return sum;
	}
	
	//方法2:获取2维数组的最大值
	public static int[] getMax(int arr[][]){//传入一个二维数组,返回一个一维数组,相当于拥有了多个返回值,年级、班级、最大值
		
		int max = arr[0][0];
		int grade = 0;
		int classes = 0;
		
		for(int i = 0; i < arr.length; i++){ 
			for( int j = 0; j < arr[i].length; j++){
				if(arr[i][j] > max){//if条件中的语句当且仅当条件为真时才会执行,最终max,i,j的值就是该二维数组中最大值以及对应值
					max = arr[i][j];
					grade = i + 1;//因为数组的脚标是从0开始算1的
					classes = j + 1;//最终循环会把二维数组中所有的值都遍历到,最后的max值就是二维数组中的最大值,再得到与之对应的脚标
				}
			}
		}
		
		int[] getMaxReturn = {grade,classes,max};
		return getMaxReturn;
	}
}

/*

程序输出结果:

全校学生人数的总和是458人
全校人数最多的班级是:高2(1)班,总共有:54人

 */


勤俭持家的年级组长

奖金存多少时候才能买车?

/**
 * 年级组长每天有50元奖金补贴。
 * 他打算日积月累,用这笔钱买辆3万元的二手车。
 * 平日里,年级组长一分钱都不舍得花,全部存着。
 * 每到周日,他用奖金里的100元给自己买一个小礼物。
 * 他想知道自己需要多少天才能存够用这奖金买到二手车?
 * @author Woo
 *
 *分析:
 *有三种情况(想到分支语句):
 *1.工作日:存50元
 *2.周六:没有奖金
 *2.周日:花掉100元
 *循环结束的条件:
 *钱的总数达到30000元
 */
public class Bonus {
	public static void main(String[] args) {
		//定义两个变量,一个存当前拥有的钱,一个存日期
		int date = 0;
		//当date = 13时,moneySum += 10 语句执行,此时moneySum已经等于100,而循环结束时的date++还会执行一次
		//解决方法是:让date从0开始,并且将date++放在while循环首部
		int moneySum = 0;
		final int CAR_MONEY = 30000;
		
		while(moneySum < CAR_MONEY){
			
			date++;
			if((date % 6 == 0 )){//周六的情况
				moneySum = moneySum;
			}
			
			else if((date % 7 == 0 ))
			{
				moneySum -= 100;//周日的情况
			}
			
			else
			{
				moneySum += 50;//平时的情况
			}
			
		}
		System.out.println("年级组长想要用奖金买二手车需要:" + date + "天");
	}
	
}

/*
 * 年级组长想要用奖金买二手车需要:1259天
 */

要这么久?还不如搞搞副业卖兔子!

/**
 * 
 * @author Woo
 * 年级组长得知兔子的繁殖能力比较强
 * 一个月后一对兔子就能生下一对兔子,卖掉一只兔子尽赚15元
 * 需要几个月年级组长能买到他梦寐以求的二手车?
 * 
 * 斐波那契数列前10项为:1,1,2,3,5,8,13,21,34,55
 * 
 * 分析:
 * 0~1个月有1对兔子、1~2个月还是1对兔子、2~3个月2对兔子....
 * 循环终止的条件是尽赚的钱达到二手车的钱:3万元
 * 尽赚的钱 = 兔子对数总数 * 2 * 15
 * 兔子对数总数 = 斐波那契数列的第n项的值,n即为月数
 * 
 */
public class Fibonacci {
	public static void main(String[] args) {
		int enoughMoney = 0;
		final int CAR_MONEY = 30000;
		int month = 0;
		while(enoughMoney < CAR_MONEY){
			month++;
			enoughMoney = calFibo(month) * 2 * 15;
		}
		System.out.println("年级组长想要买到二手车需要" + month + "个月");
	}
	
	

	
	//方法calFibo(),运用递归表达式求斐波那契数列的第n项的值
	public static int calFibo(int n){
		if(n == 1 || n == 2){
			return 1;//实际问题:第1、2个月只有一对兔子
		}else{
			return calFibo(n-1) + calFibo(n-2);//第3项是第1项与第2项的和,依此类推
		}
	}
}

/*
 * 年级组长想要买到二手车需要17个月
 */





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值