风扇模拟
题目描述
请定义一个名为Fan的类模拟风扇,其属性包括打开状态、速度、风扇半径、风扇颜色。要求为每个属性提供访问器和修改器(getter和setter),定义print方法输出风扇对象的相关属性值。风扇有四种种固定的速度,分别是静止(quiet,0)慢速(slow,1-3)、中速(middle,4-7)、快速(quick,8-9);定义测试类,输入速度、半径、颜色、打开状态等数据,按格式输出相关信息。
相关属性值约束:
(1)打开状态:ON或者OFF,表示打开、关闭;
(2)速度(整数):速度小于0时赋值0,速度不可以大于9(大于9时赋值9);
(3)风扇半径在[5,10]内合法,大于10的赋值10,小于5的赋值5;
(4)风扇颜色只有黑色(black)、灰色(gray)、白色(white)三种,其他输入均默认为黑色(black);
(5)打开状态为OFF时,速度无效(即无论输入什么,都应赋值0);打开状态为ON时,速度也可以是0;
(6)私有属性、公有方法
注意:本题重点考查程序是否符合面向对象编程规范,包括变量命名、属性定义、getter和setter方法、成员方法定义、方法调用、代码对齐方式,等等。本题会在实验报告中重点检查。
提示:
(1)测试类(主类)结构参考“实验一设计型实验(1)分数计算”;
(2)不需要定义对象数组,按以下方式处理n组数据问题:
Fan fan=new Fan();
for(i=0;i<n;i++)
{
fan.setStatus(reader.next());
fan.setSpeed(reader.nextInt());
……
fan.print();
}
(3)变量、方法定义见名知意,getter和setter方法由eclipse自动生成后,再进行修改。
输入
风扇的打开状态、速度、风扇半径、风扇颜色等相关属性值,需要验证输入数据的合法性(已知数据类型正确,只需验证数值是否合法);每次输入n组数据。
输出
n组风扇的各属性信息
样例输入 Copy
4 ON 1 8 black OFF 3 11 red ON 10 5 gray OFF 0 3 white
样例输出 Copy
Status:ON;Speed:slow;FanRadius:8;FanColor:black Status:OFF;Speed:quiet;FanRadius:10;FanColor:black Status:ON;Speed:quick;FanRadius:5;FanColor:gray Status:OFF;Speed:quiet;FanRadius:5;FanColor:white
代码
import java.util.Scanner;
public class Main {
static Scanner reader=new Scanner(System.in);
public static void main(String[] args) {
int i,n;
n=reader.nextInt();
Fan fan;
for(i=0;i<n;i++) {
fan=new Fan();
fan.setStatus(reader.next());
fan.setSpeed(reader.nextInt());
fan.setRadius(reader.nextInt());
fan.setColor(reader.next());
fan.print();
}
}
}
class Fan{
private String Status;
private String Speed;
private int FanRadius;
private String FanColor;
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public String getSpeed() {
return Speed;
}
public void setSpeed(int speed) {
if(Status.equals("OFF")) {
Speed = "quiet";
return;
}
if(speed <= 0) {
Speed = "quiet";
return;
}
if(speed > 9) {
Speed = "quick";
return;
}
if(speed <= 3) {
Speed = "slow";
}else if(speed <= 7) {
Speed = "middle";
}else {
Speed = "quick";
}
}
public int getRadius() {
return FanRadius;
}
public void setRadius(int fanRadius) {
if(fanRadius < 5) {
FanRadius = 5;
return;
}
if(fanRadius > 10) {
FanRadius = 10;
return;
}
FanRadius = fanRadius;
}
public String getColor() {
return FanColor;
}
public void setColor(String fanColor) {
if(fanColor.equals("black") || fanColor.equals("gray") || fanColor.equals("white")) {
FanColor = fanColor;
}else {
FanColor = "black";
}
}
public void print() {
System.out.println("Status:" + Status + ";Speed:" + Speed + ";FanRadius:" + FanRadius + ";FanColor:" + FanColor);
}
}
提取身份证信息
题目描述
身份证号码中各数位的意义为:
1-2位:省、自治区、直辖市代码;
3-4位:地级市、盟、自治州代码;
5-6位:县、县级市、区代码;
7-14位:出生年月日,比如19670401代表1967年4月1日;
15-17位:为顺序号,其中17位男为单数,女为双数;
18位:为校验码,0-9和X。作为尾号的校验码,是由号码编制单位按统一的公式计算出来的,如果某人的尾号是0-9,都不会出现X,但如果尾号是10,那么就得用X来代替,因为如果用10做尾号,那么此人的身份证就变成了19位。X是罗马数字的10,用X来代替10 。有的地方也出现使用小写从x。
身份证校验码的计算方法
1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
2、将这17位数字和系数相乘的结果相加。
3、用加出来和除以11,看余数是多少?
4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。其中,小写x也认为正确。
5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字X。
请你编写程序,验证所输入身份证号的合法性,如果合法,则输出其年龄(周岁,根据出生日期判断年龄)。
输入
当前日期,n及个模拟身份证号,n组
输出
合法性(true,false),年龄(整数)
样例输入 Copy
2022 6 14 3 330903198509060219 340101200010113224 330329200504255448
样例输出 Copy
true:36 false:-1 true:17
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int y, m, d, n, i;
y = reader.nextInt();
m = reader.nextInt();
d = reader.nextInt();
n = reader.nextInt();
IdentityCard card;
for (i = 0; i < n; i++) {
card = new IdentityCard();
card.setID(reader.next());
if (card.check() == true)
System.out.println("true:" + card.getAge(y, m, d));
else
System.out.println("false:-1");
}
}
}
class IdentityCard {
private String ID;
private int year;
private int month;
private int day;
// getter, setter 方法
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public boolean check() {
if (!ID.matches("[1-9][0-9]{5}(19|20)[0-9]{9}[0-9Xx]")) {
return false;
}
year = Integer.parseInt(ID.substring(6, 10));
month = Integer.parseInt(ID.substring(10, 12));
day = Integer.parseInt(ID.substring(12, 14));
if (!dateLegal()) {
return false;
}
char[] ch = ID.toCharArray();
// 计算加权总和sum
int[] weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (ch[i] - '0') * weight[i];
}
int yu = sum % 11;
char[] validCode = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
if(ch[17]=='x'&&yu==2){
return true;
}
if (ch[17] != validCode[yu]) {
return false;
}
return true;
}
boolean dateLegal() {
if (month < 1 || month > 12) {
return false;
}
int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
daysInMonth[2] = 29;
}
return day >= 1 && day <= daysInMonth[month];
}
public int getAge(int y, int m, int d) {
int age = y - year;
if (m < month || (m == month && d < day)) {
age--;
}
return age;
}
}
共饮同井水(升级版)
题目描述
某村庄有一口公共水井,为了保护该水井及饮用水的质量,当地规定当该水井内的水量不高于100时,禁止取水6小时整(假设1:0:0开始禁止取水,则7:0:0可解禁),在此期间,公共水井水量自动恢复到最大容量1000;如果预计村民当次取水后水量低于100,则拒绝该村民本次取水。
其实每个村民自家也有口水井,自家的水井容量各不相同,范围在(100,200]内。村民优先去公共水井取水,若发现公共水井禁止取水或因容量不够拒绝取水时,再从自家水井取水。
自家水井容量不高于100时,禁止取水1小时整,在此期间,水井水量自动恢复到初始水量;如果预计村民当次取水后水量低于100,则允许该村民本次从自家水井取水至水井容量到100。
请模拟n次村民的用水情况:先设置公共水井水量及每位村民自家水井容量,再模拟村民取水的情形。村民每次取水时需输入年、月、日、时、分、秒和取水量,若成功从公共水井取水则输出“public:m”形式,m表示公共水井剩余水量;若成功从自家水井取水则输出“private:n”形式,n表示自家水井剩余水量;若没有取到水,则输出“wait”。
输入
公共水井初始水量(100<publicWell<=1000);m及m位村民自家水井水量(100<privateWell<=200,也是初始水量,村名编号从1开始,按1递增);n及n次村民的取水需求,每次取水格式:村民编号 年 月 日 时 分 秒 实际取水量(>0)。(不用检查输入数据格式的规范性,后一次取水时间晚于前一次取水时间,年份大于1970,时间为24小时制)
输出
每次取水的情况,显示方式(村民编号:水井类型,成功取水量,本次取水后水井的剩余水量)
样例输入 Copy
1000 3 150 200 110 4 1 2022 3 1 18 25 30 800 2 2022 3 1 20 25 20 150 1 2022 3 1 23 25 19 100 3 2022 3 2 6 25 25 150
样例输出 Copy
1:public,800,200 2:private,100,100 1:public,100,100 3:public,150,850
提示
(1)定义一个类DateTime,处理日期、时间的间隔,或者利用Calender类处理日期的间隔;
(2)将公共水井取水分成两类:取水成功、取水失败;将私人水井分成三种情况:取全部水、取部分水、取水失败;
(3)将小时转换成秒进行比较。
代码
import java.time.LocalDateTime;
import java.util.Scanner;
/*
* 共有两个类:一个主类Main主要是定义Well对象,输入Well对象的属性
* 并进行对Well的usePub(使用公共水井)和usePri(使用自家水井)的调用
*
* 第二个是Well类,包括属性:一些类变量主要是对公共井的属性描述;一些实例变量主要是对自家井的属性描述
* 两个方法usePub(使用公共水井)和usePri(使用自家水井)
*
*/
public class Main {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
Well.setPubWater(input.nextInt());
int n = input.nextInt(); //输入公共井初始水量
Well[] people = new Well[n];
for (int i = 0; i < people.length; i++) {
people[i] = new Well();
people[i].setPriWater(input.nextInt()); //定义和输入村民自家水井对象和初始水量
}
int m = input.nextInt();
for (int i = 0; i < m; i++) {
int j = input.nextInt(); //输入几号村民要取水
LocalDateTime time = LocalDateTime.of(input.nextInt(), input.nextInt(), input.nextInt(), input.nextInt(),
input.nextInt(), input.nextInt()); //输入村民取水时间
int wantUse = input.nextInt(); //输入取水量
if (!people[j - 1].usePub(j, time, wantUse)) {
people[j - 1].usePri(j, time, wantUse); //对两个方法的调用,如果公共井取到水了,就不用取自家井取水
}
}
}
}
class Well {
private static int pubWater; //公共井的水量
private static int pubMark = 1000; //公共井最大容量
private static String pubCondition = "open"; //公共井的开关状态
private static LocalDateTime pubTime; //公共井被禁用后的开启时间
private int priWater; //自家井的水量
private int priMark; //自家井最大容量
private String priCondition = "open"; //自家井的开关状态
private LocalDateTime priTime; //自家井被禁用后的开启时间
public static int getPubWater() {
return pubWater;
}
public static void setPubWater(int pubWater) {
Well.pubWater = pubWater;
}
public int getPriWater() {
return priWater; //这里是对一些属性的get和set方法
}
public void setPriWater(int priWater) {
priMark = priWater; //这里在输入自家井初始水量时,顺带把自家井最大容量给赋值
this.priWater = priWater;
}
/*
* 这里是使用自家水井的方法定义,当水井打开时或者水井关闭但取水时间已经过了或等于禁水时间,可以取水返回true
* 否则不能取水,返回false
* 方法参数为:村民编号,取水时间,想要取水的多少
*
* 返回值为是(true)否(false)取到水
*/
public boolean usePub(int j, LocalDateTime time, int wantUse) {
boolean mark;
if (pubCondition.equals("open") || pubCondition.equals("close") && (time.isAfter(pubTime)||time.isEqual(pubTime))) {
pubCondition = "open"; //如果可以取水则水井状态改为open
if (pubWater - wantUse >= 100) {
pubWater -= wantUse; //满足取水条件,取全部水
System.out.println(j + ":public," + wantUse + "," + pubWater);
mark = true;
} else {
mark = false;
}
} else {
mark = false;
} //不满足取水条件返回false
if (pubWater == 100) { //如果发现水井容量是100,则关闭水井,且设置最晚水井打开条件
pubTime = time.plusHours(6); //最晚水井打开条件为:本次取水时间加6个小时
pubWater = pubMark; //水井恢复最大容量1000
pubCondition = "close";
}
return mark;
}
/*
* 这里是使用自家井的方法,当水井打开时或者水井关闭但取水时间已经过了或等于禁水时间,可以取水
* 否则不能取水
* 方法参数为:村民编号,取水时间,想要取水的多少
* 无返回值
*/
public void usePri(int j, LocalDateTime time, int wantUse) {
if (priCondition.equals("open") || priCondition.equals("close") && (time.isAfter(priTime)||time.isEqual(priTime))) {
priCondition = "open";
if (priWater > 100) {
if (priWater - wantUse >= 100) {
priWater -= wantUse; //满足取全部水条件,取全部水
System.out.println(j + ":private," + wantUse + "," + priWater);
} else {
int mark = priWater - 100;
priWater = 100; //可以取水但水量不够,只能取部分水
System.out.println(j + ":private," + mark + "," + priWater);
}
}
} else {
System.out.println(j + ":wait"); //水井正处于禁水时间
}
if (priWater == 100) {
priTime = time.plusHours(1);
priWater = priMark;
priCondition = "close"; //如果发现水井容量是100,则关闭水井,且设置最晚水井打开条件
//最晚水井打开条件为:本次取水时间加6个小时
//水井恢复最大容量priMark
}
}
}