题目描述
身份证号码中各数位的意义为:
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 IDCard {
public static void main(String[] args) {
Scanner reader=new Scanner(System.in);
int y,m,d,n,i;
y=;
m=;
d=;
n=;
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{
//定义成员变量,getter,setter方法
public boolean check() {
if(!ID.matches("[1-9][0-9]{5}(19|20)[0-9]{9}[0-9Xx]")) {//一个简易的正则表达式,判断身份证号前17位是否为数字,第一位不能是0,第7/8位是19或20,最后一位是数字或X、x,本语句可以直接使用。
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
yu=sum%11;
//根据余数对应关系,判断身份证号最后一位是否正确
}
boolean dateLegal(){ //判断出生日期是否合法
}
public int getAge(int y,int m,int d) {
//根据当前日期和生日,计算年龄
}
}
正确代码
package project4;
import java.util.Scanner;
public class IDCard {
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();//n组
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{
//定义成员变量,getter,setter方法
private String ID;
int year,month,day;
int sum=0;
int yu;
public boolean check() {
year=Integer.parseInt(ID.substring(6, 10)); //获取身份证号码中的出生年份
month=Integer.parseInt(ID.substring(10, 12)); //获取身份证号码中的出生月份
day=Integer.parseInt(ID.substring(12, 14)); //获取身份证号码中的出生日
if(!getID().matches("[1-9][0-9]{5}(19|20)[0-9]{9}[0-9Xx]")) {//一个简易的正则表达式,判断身份证号前17位是否为数字,第一位不能是0,第7/8位是19或20,最后一位是数字或X、x,本语句可以直接使用。
return false;
}
if(!dateLegal()) {//判断出生日期是否合法,主要是月、日的合法性
return false;
}
char ch[]=getID().toCharArray();//将字符串转换成字符数组//这是用来干什么的
sum=(ch[0]-'0')*7+(ch[1]-'0')*9+(ch[2]-'0')*10
+(ch[3]-'0')*5+(ch[4]-'0')*8
+(ch[5]-'0')*4+(ch[6]-'0')*2
+(ch[7]-'0')*1+(ch[8]-'0')*6
+(ch[9]-'0')*3+(ch[10]-'0')*7
+(ch[11]-'0')*9+(ch[12]-'0')*10
+(ch[13]-'0')*5+(ch[14]-'0')*8
+(ch[15]-'0')*4+(ch[16]-'0')*2;
char yan=getID().charAt(17);
yu=sum%11;//根据余数对应关系,判断身份证号最后一位是否正确
if(yu==0&&yan=='1' ||yu==1&&yan=='0'||yu==2&&(yan=='x'||yan=='X')||yu==3&&yan=='9'||
yu==4&&yan=='8' ||yu==5&&yan=='7'||yu==6&&yan=='6'||yu==7&&yan=='5'||
yu==8&&yan=='4' ||yu==9&&yan=='3'||yu==10&&yan=='2' ) return true;
else return false;
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
boolean dateLegal(){ //判断出生日期是否合法//是判断输入的(ID中的)year,month,day是否正确
if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)
&&(day>=1&&day<=31)) return true;
else if((month==4||month==6||month==9||month==11)&&(day>=1&&day<=30)) return true;
else if((month==2)&&(day>=0&&day<=29)&&!(year%400==0||(year%4==0&&year%100!=0))) return true;
else if((month==2)&&(day>=0&&day<=28)&&(year%400==0||(year%4==0&&year%100!=0))) return true;
else return false;
}
public int getAge(int y,int m,int d) {
//根据当前日期和生日,计算年龄
int age=y-year;
if(m<month) age--;
if(m==month&&d<day) age--;
return age;
}
}
错误和知识点
1.知识点
1)
.将字符串转化为浮点数/整数 int x =Integer.parseInt("9"); double c = Double.parseDouble("5"); int b = Integer.parseInt("444",16);//16是进制数,“9,5,444”是字符串
结果
9 5.0 1092
2).matches() 方法用于检测字符串是否匹配给定的正则表达式。str.matches(regex) ,返回true、false
3)str.toCharArray()将字符串转换成字符数组
'a'表示字符字面量,在内存中占1个字节,'a'+1表示'a'的ASCII码加1,结果为'b'
"a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果指向"a"结束符'\0'
6)substring():截取字符串中介于两个指定下标之间的字符。
用法:两个参数:
字符串.substring(参数1,参数2);(str.substring(2,9)//获取第3个到第八个字符,从0开始的)
参数1:字符串截取的起始下标,非负的整数
如果此参数是0,则是从字符串的第一个字符开始截取
参数2:截取结束位置的索引下标
注意:截取的结果,不包括结束位置的字符
所以也可以用.substring获取单个字符(str.substring(0,1) //获取第0个字符)
7)charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
str.charAt(0) //获取第0个字符
2.错误
1)我又把操作直接写到类里了
2)而且有的问题明明我可以做对,但是因为他很长所以我就不愿意去想,比如月份问题和生日计算,
还是不要凭感觉去写,更重要的的是有思路,我总是思路混乱
3)而且我打字超慢的,好烦
4)还有一个return的问题,不知道为当有两个lf-return就错误,但是再在外面加一个return就好了,或者是加一个if-return和else-return。
谁能够帮帮我啊!!!!!!!!!!!