论JAVA----------------------前三次题目集总结
论JAVA----------------------前三次题目集总结
前三次题目集还是比较基础性的内容,但覆盖面广泛,给后面的面向对象程序设计打下了良好的基础,主要包括以下知识点:
- 简单的输入输出:(例如:输入:Scanner in = new Scanner(System.in);int year=in.nextInt();输出:System.out.println("Wrong Format");)
- 循环控制:
(1)if-else 语句:例如:
if (isLeapYear(year))
{ System.out.println(year + " is a leap year."); }
else { System.out.println(year + " is not a leap year."); }
(2)switch-case 语句:
switch(c)
{ case 'f': System.out.println("3");break;
default : System.out.println(c+" is an invalid input");}
(3)while语句:
While(循环继续的条件){
语句组;
用于控制循环的附件语句;
}
(4)do-while 语句:
do{
//循环体;
语句(组);
}while(循环继续的条件);
(5)for循环
for(初始操作;循环继续条件;每次迭代后的操作){
//循环体;
语句(组);
}
(6)嵌套循环
- 经典的凑钱问题
循环语句+条件设置+整零分配+判断==纸币凑钱
- 数组的相关操作(一维数组的创建、访问、初始化、遍历、复制等)
(1)创建:double[] myList = new double[10];(这条语句声明了一个由10个double型元素构成的数组,并将该数组的引用赋值给myList)
(2)访问:数组元素通过下标进行访问(同C语言一样)
(3)初始化:例如使用随机数初始化数组(生成0.0到100,。0之间的随机值)
for (int i = 0;i < myList.length; i++){
myList[i] = Math.random( )*100;
}
(4)遍历:显示数组:
for (int i = 0;i < myList.length; i++)
{
System.out.print(myList[i] + “ ”);}
(5)复制:✸使用java.lang.System类的arraycopy方法复制数组,而不是使用循环。
Arraycopy(sourceArray,srcpos,targetArray,tarPos,length);
其中,参数srcPos和tarPos分别表示在源数组sourceArray和目标数组targetArray中的起始位置。从sourceArray复制到targetArray中的元素个数由参数length指定。
- 排序(典型:冒泡排序)
如:for (int i = 0; i < N; i++) {
for (int j = 0; j < N - i - 1; j++) {
if (c[j] > c[j+1]) {
int temp = c[j];
c[j] = c[j+1];
c[j+1] = temp;
}
}
}
- 类与对象 为了避免对数据域的直接修改,应该使用
private修饰符将数据域声明为私有的,称为
“数据域封装”
class Account ------------>Account 类
{
private int id; --------------->对象--私有属性(封装)
private double balance;
private double annualInterestRate;
}
- 方法的定义及调用
定义方法的的语句:
修饰符 返回值类型 方法名(参数列表){
//方法体
}
我们来看一个方法的定义,该方法找到两个整数中较大的数。这个名为max的方法有两个int 型参数:num1和num2,方法返回较大的一个。

实例代码(日期类):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
int month = scanner.nextInt();
int day = scanner.nextInt();
Date date = new Date(year, month, day);
if (date.checkInputValidity()) {----------------->调用方法
date.getNextDate();-------------------------->
}
}
}
public boolean checkInputValidity(){------------------->定义方法
if (year < 1900 || year > 2000) {
System.out.println("Date Format is Wrong");
return false;
}
if (month < 1 || month > 12) {
System.out.println("Date Format is Wrong");
return false;
}
if (day < 1 || (isLeapYear(year) ? mon_maxnum[month - 1] < day : mon_minnum[month - 1] < day)) {
System.out.println("Date Format is Wrong");
return false;
}
return true;
}
public void getNextDate(){------------------------------>定义方法
String format = null;
boolean lastDay = isLeapYear(year) ? (mon_maxnum[month - 1] == day) : (mon_minnum[month - 1] == day);
if (lastDay) {
if (month == 12) {
format = String.format("Next day is:%d-%d-%d", year + 1, 1, 1);
} else {
format = String.format("Next day is:%d-%d-%d", year, month + 1, 1);
}
} else {
format = String.format("Next day is:%d-%d-%d", year, month, day + 1);
}
System.out.println(format);
}
}
- 日期类
①判断闰年: 返回“布尔值”更简便
public boolean isLeapYear(int year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;}
②判断输入数据是否合法:
public boolean checkInputValidity(){
if (year < 1900 || year > 2000) {
System.out.println("Date Format is Wrong");
return false;
}
if (month < 1 || month > 12) {
System.out.println("Date Format is Wrong");
return false;
}
三目运算,省去大量循环判断
if (day < 1 || (isLeapYear(year) ? mon_maxnum[month - 1] < day:mon_minnum[month - 1] < day)) {
System.out.println("Date Format is Wrong");
return false;
}
return true;
}
通过限定条件,采用循环语句判断输入数据是否合法。
③调用方法,使代码模块化,符合JAVA编程语言的结构要求。
如:if (date.checkInputValidity()) {
date.getNextDate(); }
9.无参/有参构造方法
public Account() {} ----------->无参构造
public Account(int id, double balance) { ------->有参构造
this.id = id;
this.balance = balance;
}
10.getter及setter方法
私有数据域不能被对象从定义该私有域的类外访问。但是经常会有客户端需要存取、修改数据域。为了访问私有数据域,可以提供一个获取(getter)方法返回数据域的值。为了更新数据域,可以设置一个(setter)方法给数据域设置新值。


如:
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
注:eclipse上生成getter及setter方法的快捷操作
下面对于具体的题目做下分析:
判断三角形的类型:

对于这道题目,从题目要求的输入输出格式和输入输出样例来看,是比较基础的题目。当输入数值符合题目规定数值范围后,判断三角形的类型,首先就要输入三条边,然后利用数学知识判断三条边是否满足三角形成立的关系:三角形任意两边之和大于第三边,任意两边之差小于第三边。当判断结果为三角形后,在比较三边关系得出是否是直角三角形,等腰三角形,等边三角形,等腰直角三角形等等。这是这道题整体的实现思路。那么,该如何用JAVA语言实现呢?
部分源码如下:

①使用循环语句if-else做判断:输入数据的合法性,构成三角形三边的合法性,构成每一类三角形的合法性等等。
②使用正确的JAVA编程语言。
③正确使用嵌套循环,保证循环的合理性,既不要盲目判断,造成程序的复杂化,也不能缺枝少叶。简言之,就是不说废话。
下面再下面再给出一道题:
求下一天:
题目分析:
首先,本题考查的主要内容就是:类、对象、方法。
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
由于年份分为闰年、平年,月份也是天数不一样,尤其是二月份更是随着年份的不同而不同,所以需要判断所输入年份是否为闰年,然后根据这一结果再去看输入月份是多少,然后根据月份的规律判断下一天是在本月还是下一个月,比如是12月还需要考虑它的下一天会不会跨年,都要采取相应的算法。如果总是采用if-else语句循环嵌套,逐一考虑,那很显然是非常复杂,特别容易出错,也特别容易把自己搞混的。那么,我们就可以采用将每个月的天数用数组存起来,将润年的判断返回布尔值,定义并调用方法,采用三目运算省去繁杂的条件判断,模块化代码,使代码精简。下面我展示一下我的源码:
import java.util.Scanner;
public class Main {
public static int[] normal = {31,28,31,30,31,30,31,31,30,31,30,31};
public static int[] leap = {31,29,31,30,31,30,31,31,30,31,30,31};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
int month = scanner.nextInt();
int day = scanner.nextInt();
if (checkInputValidity(year, month, day)) {
isLeapYear(year);
nextDate(year,month,day);
}
}
public static boolean isLeapYear(int year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
public static boolean checkInputValidity(int year,int month,int day) {
if (year < 1820 || year > 2020) {
System.out.println("Wrong Format");
return false;
}
if (month < 1 || month > 12) {
System.out.println("Wrong Format");
return false;
}
if (day < 1 || (isLeapYear(year) ? leap[month - 1] < day : normal[month - 1] < day)){
System.out.println("Wrong Format");
return false;
}
return true;
}
public static void nextDate(int year, int month, int day){
String format = null;
boolean lastDay = isLeapYear(year) ? (leap[month - 1] == day) : (normal[month - 1] == day);
if (lastDay) {
if (month == 12){
format = String.format("Next date is:%d-%d-%d", year + 1, 1, 1);
}else {
format = String.format("Next date is:%d-%d-%d", year, month + 1, 1);
}
}else {
format = String.format("Next date is:%d-%d-%d", year, month, day + 1); 类图如右所示
}
System.out.println(format);
}
}
下面来看一下运行结果:

可以看出,程序运行无误。
下面再来看另外一道与日期有关的题目:
求前N天:
这一道题可能刚开始想的话是觉得比较复杂的,但经过一段时间的逻辑规划,其实和上一道与日期有关的题目也是十分类似的。这一次我们不妨就用if-else语句整体实现函数的功能。
import java.util.Scanner;
public class Daybefore {
//主方法
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
int year=in.nextInt();
int month=in.nextInt();
int day=in.nextInt();
int n=in.nextInt();
f(year,month,day,n);
}
//判断year是否为闰年,返回boolean类型
public static boolean isLeapYear(int year)
{
boolean isLeapYear=false;
if((year%4==0&&year%100!=0)||year%400==0)//闰年
isLeapYear=true;
else
isLeapYear=false;
return isLeapYear;
}
public static void f(int year,int month ,int day ,int n)
{
//用数组 a[0]设为0
int[] months={0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year)==true)
months[2]=29;//如果是闰年 二月改为29
int newyear=0;
int newmonth=0;
int newday=0;
if(year<=2020&&year>=1820&&month<=12&&month>=1&&day>=1&&day<=months[month]&&n>=-10&&n<=10)
{
if(n==0)//当天
{
newyear=year;
newmonth=month;
newday=day;
}
if(n<0)//往后
{
n=-n;//改为正数方便计算
if(month==12)//12月
{
if(day+n>31)//是否跨年
{
newyear=year+1;
newmonth=1;
newday=day+n-31;
}
else
{
newyear=year;
newmonth=month;
newday=day+n;
}
}
else
{
if(day+n>months[month])
{
newyear=year;
newmonth=month+1;
newday=day+n-months[month];
}
else
{
newyear=year;
newmonth=month;
newday=day+n;
}
}
n=-n;//改回
}
if(n>0)//往前
{
if(month==1)//1月
{
if(day-n<1)//是否跨年
{
newyear=year-1;
newmonth=12;
newday=months[12]-(n-day);
}
else
{
newyear=year;
newmonth=month;
newday=day-n;
}
}
else
{
if(day-n<1)
{
newyear=year;
newmonth=month-1;
newday=months[month-1]-(n-day);
}
else
{
newyear=year;
newmonth=month;
newday=day-n;
}
}
}
System.out.println(n+" days"+" ago"+" is:"+newyear+"-"+newmonth+"-"+newday);
}
else
System.out.println("Wrong Format");
}
类图如下:

运行结果:

从这段代码我们就可以看出,用大量的嵌套循环(如if-else语句)的确也是可以保证程序的合法性,实现函数的功能,但编写起来可是特别复杂,我们尽量首选其他方法来实现程序功能,降低复杂度,提高程序运行效率;如果是在程序本身特别需要用嵌套循环,流程控制且自身能力足够,确保可以不重不漏,正确编写,我们再去使用简单的循环编写。
下面我们来看如何定义日期类:
题目:
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
Date类结构如下图所示:

下面先来看一下源码:
import java.util.Scanner;
public class Main { 主方法
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
int month = scanner.nextInt();
int day = scanner.nextInt();
Date date = new Date(year, month, day);
if (date.checkInputValidity()) {
date.getNextDate();
} 调用方法
}
}
类
class Date {
public static int[] mon_minnum = {31,28,31,30,31,30,31,31,30,31,30,31};
public static int[] mon_maxnum = {31,29,31,30,31,30,31,31,30,31,30,31};
private int year;
private int month; 对象的私有属性(数据域的封装)
private int day;
public Date() {
}
public Date(int year, int month, int day) {
this.year = year;
this.month = month; this关键字用于引用正在被构建的对象
this.day = day; 的数据域year,month,day
}
public int getYear() {
return year;
}
getter及setter方法
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public boolean isLeapYear(int year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
public boolean checkInputValidity(){
if (year < 1900 || year > 2000) {
System.out.println("Date Format is Wrong");
return false;
}
if (month < 1 || month > 12) {
System.out.println("Date Format is Wrong");
return false;
}
if (day < 1 || (isLeapYear(year) ? mon_maxnum[month - 1] < day : mon_minnum[month - 1] < day)) {
System.out.println("Date Format is Wrong");
return false;
}
return true;
}
public void getNextDate(){
String format = null;
boolean lastDay = isLeapYear(year) ? (mon_maxnum[month - 1] == day) : (mon_minnum[month - 1] == day);
if (lastDay) {
if (month == 12) {
format = String.format("Next day is:%d-%d-%d", year + 1, 1, 1);
} else {
format = String.format("Next day is:%d-%d-%d", year, month + 1, 1);
}
} else {
format = String.format("Next day is:%d-%d-%d", year, month, day + 1);
}
System.out.println(format);
}
}
这段代码定义了定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),实现了一个能创建日期的有参构造和无参构造方法,以及year,month,day的getter及setter方法,通过定义方法,调用方法实现函数的整体功能。
下面我们来看一道求一阶导函数的题目:

下面我们先来看一下实现一阶求导的源码:
import java.io.*;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine().replaceAll(" ","");
List<Express> expresses = new ArrayList<>();
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == 'x') {
Express express = new Express();
// 指数
if (i == line.length() - 1){
express.setExponent(1);
}else {
if (line.charAt(i + 1) != '^'){
express.setExponent(1);
}else {
String next = line.substring(i + 2);
String exponent = "";
for (int j = 0; j < next.length(); j++) {
if (j == 0 && (next.charAt(j) == '+' || next.charAt(j) == '-')){
exponent += next.charAt(j);
continue;
}else if (next.charAt(j) == '+' || next.charAt(j) == '-') {
break;
}else {
exponent += next.charAt(j);
}
}
express.setExponent(Long.parseLong(exponent));
}
}
// 常数
if (i == 0) {
express.setConstant(1);
} else {
if (line.charAt(i - 1) != '*'){
express.setConstant(1);
}else {
String pre = line.substring(0, i - 1);
int prePlusIndex = pre.lastIndexOf("+");
int preMinusIndex = pre.lastIndexOf("-");
if (prePlusIndex == -1 && preMinusIndex == -1) {
express.setConstant(Long.parseLong(pre));
}else if (prePlusIndex == pre.length() - 1 || preMinusIndex == pre.length() - 1) {
express.setConstant(1);
}else {
if (preMinusIndex > prePlusIndex) {
express.setConstant(Long.parseLong(pre.substring(preMinusIndex)));
}else {
express.setConstant(Long.parseLong(pre.substring(prePlusIndex)));
}
}
}
}
expresses.add(express);
}
}
String result = "";
for (int i = 0; i < expresses.size(); i++) {
if (expresses.get(i).getExponent() == 0 || expresses.get(i).getConstant() == 0){
result = "Wrong Format";
break;
}
String v = "";
if (expresses.get(i).getExponent() - 1 == 0) {
v = (expresses.get(i).getConstant() * expresses.get(i).getExponent()) + "";
}else {
v = (expresses.get(i).getConstant() * expresses.get(i).getExponent()) + "*x^" + (expresses.get(i).getExponent() - 1);
}
if (i == 0) {
result += v;
}else {
if (v.charAt(0) == '-') {
result += v;
}else {
result += "+" + v;
}
}
}
result = result.equals("") ? "0" : result;
System.out.println(result);
}
}
class Express{
private long constant;
private long exponent;
public long getConstant() {
return constant;
}
public void setConstant(long constant) {
this.constant = constant;
}
public long getExponent() {
return exponent;
}
public void setExponent(long exponent) {
this.exponent = exponent;
}
@Override
public String toString() {
return "Express{" +
"constant=" + constant +
", exponent=" + exponent +
'}';
}
}
本题求导主要集中在:当f(x)=ax^b+c时,f‘(x)=abx^(b-1)问题的求解中,
在求解过程中可考虑构建一个函数表达式的类(属性包括常数,指数),输入的表达经过前置的校验确认是正确的函数表达式后,去除函数间的所有空格,通过拆分'x'特征值确实常数和系数来构建函数表达式类的实例,构建完成后,解析实例得出导数表达式。
编程注意点:
1. 常数c的处理
2. 系数/指数符号+/-
3. 首为系数为负数
4. 指数为0
5. 系数为0
6. 大数的处理
需要的坑:
大数的处理
解决措施:
将int转为long

浙公网安备 33010602011771号