java必做实验3

(1). 运行以下三个程序,对每一行语句加上注释,并对每一个程序的每一个输出结果给出分析。在报告中附上程序截图和详细的文字说明。

public class first_1 {
    public static void main(String []args){
        System.out.println("Hi, ABC, good".matches("ABC "));//matches判断所给字符串是否匹配给定(ABC )正则表达式,不匹配,返回false
        System.out.println("Hi, ABC, good".matches(".*ABC.*"));//.*ABC.*与所给字符串匹配,返回true
        System.out.println("A,B;C".replaceAll(",;","#"));//replaceAll方法想将”,;“替换成”#“,原字符串没有”,;“,则没有变化
        System.out.println("A,B;C".replaceAll("[,;]","#"));//正则表达式[,;]通过replaceAll方法将字符中所有”,“,”;“替换成”#“
        String []tokens="A,B;C".split("[,;]");//正则表达式[,;]通过split方法将字符中所有”,“,”;“作为分割符将原字符串分割
        for(int i=0;i<tokens.length;i++)//i<tokens的长度前继续循环
            System.out.println(tokens[i]+" ");//输出split后的tokens的单个字符,每个字符占一行
    }
}
public class first_2 {
    public static void main(String []args){//main方法
        String s="Hi, Good Morning";//定义一个字符串s并对其赋值为”Hi, Good Morning“
        System.out.println(m(s));//输出以s为参数的m方法的返回值,m的定义在下面
    }
    public static int m(String s){//以字符串s为形参,int为返回类型的共有静态方法m的定义
        int count = 0;//定义一个int型变量count,并初始化为0
        for(int i=0;i<s.length();i++){//i初始化为0,i<s的长度时执行循环
            if(Character.isUpperCase(s.charAt(i)))//如果以i下标的s字符为大写英文字母,执行下面语句
                count++;//count的值加一
        }
        return count;//将count做为返回值
    }
}
public class first_3 {
    public static void main(String []args){//main方法
        String s="java";//定义String类型的变量s并初始化为“java”
        StringBuilder builder=new StringBuilder(s);//以s为参数定义StringBuilder类型的变量builder
        change(s,builder);//将s,builder作为实参执行change方法
        System.out.println(s);//输出change方法后的s
        System.out.println(builder);//输出change方法后的builder
    }
    private static void change(String s,StringBuilder builder){//以是s,builder为形参void为返回类型的私有静态方法change的定义
        s=s+" and HTML";//企图在s后面加上“and HTML”
        //但是在方法change里面的s不是main里面的s(值传递),所以在退出方法change后s末尾并未被加上“HTML”
        builder.append(" and HTML");//用StringBuilder中的append方法在builder字符串后面加上“and HTML”
    }
}

2). 抽象类和接口的实验。

(2.1) 定义一个抽象类Human:包含一个成员变量String name;构造方法Human(String name),用于初始化姓名name;一个抽象方法double sayHi()。在报告中附上程序截图和详细的文字说明。

package second;

public abstract  class Human {//抽象类Human
    String name;//成员变量name
    Human(String name){//以name为参数的构造方法
        this.name=name;//因为重名所以用this所指出的成员变量name被形参name赋值
    }
    public abstract double sayHi();//一个抽象方法double sayHi()
}

 (单个抽象类无法执行,执行结果放1.3)

(2.2) 定义三个继承抽象类Human的类,分别命名为Chinese、Japanese和English,在这三个类中重写sayHi()方法,分别输出一句中文、日文和英文的问候;在报告中附上程序截图、运行结果和详细的文字说明。

三个类的定义都是类似的:

Chinese类:

package second;
public class Chinese extends Human{
        Chinese(String name){//构造方法的实现
            super(name);//调用父类构造 tips必须是构造方法中都第一条语句
        }
        public double sayHi(){//抽象成员方法的实现
            System.out.println("Hi, I'm"+name);//输出name为了测试是否继承了成员变量
            return 0;
        }
}

English类:

package second;
public class English extends Human{
    English(String name){//构造方法的实现
        super(name);//调用父类构造 tips必须是构造方法中都第一条语句
    }
    public double sayHi(){//抽象成员方法的实现
        System.out.println("Hi, I'm"+name);//输出name为了测试是否继承了成员变量
        return 0;
    }
}

Japanese类:

package second;
public class Japanese extends Human{
    Japanese(String name){//构造方法的实现
        super(name);//调用父类构造 tips必须是构造方法中都第一条语句
    }
    public double sayHi(){//抽象成员方法的实现
        System.out.println("Hi, I'm"+name);//输出name为了测试是否继承了成员变量
        return 0;
    }
}

(未定义main方法,执行结果放2.3)

(2.3) 定义一个测试类HumanTest:创建一个包含3个Human对象的数组,3个Human对象来自Chinese、Japanese和English类,循环调用该数组中的元素的sayHi()方法。在报告中附上程序截图、运行结果和详细的文字说明。

因为要用Human对象调用3者,可知这是上转型变量的数组

代码如下:

package second;
public class Human_test {
    public static void main(String []args){
        System.out.println("抽象类实现上转型对象:");
        Human []human=new Human[3];//创建human数组
        human[0]= new Chinese("Chinese");
        human[1]=new English("English");
        human[2]=new Japanese("Japanese");//human数组变量分别是3者的上转型
        for(int i=0;i<3;i++) human[i].sayHi();
    }
}

名字输出正确,打招呼方法与想对应子类对应,代码执行成功。 

(2.4) 通过一个接口(命名为Human)和三个实现类(命名为Chinese、Japanese和English)来达到如上类似的效果。在报告中附上程序截图、运行结果和详细的文字说明。

接口:

package second_new;
public interface Human {
    double sayHello();
}

三个类:

package second_new;
public class Chinese implements Human{
    String name;//接口中只能有final数据类型,所以name放在这里
    Chinese(String name){//构造方法的实现
        this.name=name;
    }
    public double sayHello(){//抽象成员方法的实现
        System.out.println("Hello, I'm "+name);//输出name为了测试是否实现了抽象的接口方法
        return 0;
    }
}

package second_new;
public class English implements Human{
    String name;//接口中只能有final数据类型,所以name放在这里
    English(String name){//构造方法的实现
        this.name=name;
    }
    public double sayHello(){//抽象成员方法的实现
        System.out.println("Hello, I'm "+name);//输出name为了测试是否实现了抽象的接口方法
        return 0;
    }
}


package second_new;
public class Japanese implements Human{
    String name;//接口中只能有final数据类型,所以name放在这里
    Japanese(String name){//构造方法的实现
        this.name=name;
    }
    public double sayHello(){//抽象成员方法的实现
        System.out.println("Hello, I'm "+name);//输出name为了测试是否实现了抽象的接口方法
        return 0;
    }
}

测试类:

package second_new;
public class interface_test {
    public static void main(String []args){
        System.out.println("接口实现上转型对象:");
        Human[] human=new Human[3];//创建human数组
        human[0]= new Chinese("Chinese");
        human[1]=new English("English");
        human[2]=new Japanese("Japanese");
        for(int i=0;i<3;i++) human[i].sayHello();
    }
}

运行成功!

(3). 编写Java应用程序,计算菜单“北京烤鸭:199.1元;西芹炒肉:11.8元;酸菜鱼:59.1元;铁板牛柳:32.1元”的总价格。在报告中附上程序截图、完整的运行结果截图和简要文字说明。

由题可知,这道题主要对题目的这个字符串进行处理,将菜名和菜的价格从字符串中提出,我想到的是用Scanner提供的分隔符切割提取的方法

源代码如下(只有一个主方法)

其中的正则表达式[;元:]是因为菜名和价格之间都是隔着这些字符

package third;
import java.util.*;
import java.util.Scanner;
public class menu {
    public static void main(String []args){
        String s1=("北京烤鸭:199.1元;西芹炒肉:12.9元;酸菜鱼:59元;铁板牛柳:32.1元");
        Scanner menu =new Scanner(s1);
        menu.useDelimiter("[:元;]");//自定义正则表达式作为分隔标记
        double []price=new double[4];//保存菜价
        String []name=new String[4];//保存菜名
        int i=0,j=0;//i,j后面分别作为price和name的数组下标
        double sum=0;//sum作为总价最后输出
        while(menu.hasNext()){
            try{//读入double数据
                double num= menu.nextDouble();//这里用num记录下nextDouble的值
                price[i++]= num;
                sum+=num;//若用两次nextDouble就会出错
            }//被分隔分开的不是double数,由正则表达式可知保存的是菜名
            catch(InputMismatchException exp) {
                name[j++]= menu.next();
            }//while中catch利用异常处理方法获得菜名
        }
        for(int ii=0;ii<name.length;ii++){//i已经被定义过了,不能重定义,就用ii啦
            System.out.println(name[ii]+"的价格是:"+price[ii]+"元");
        }
        System.out.println("总价是:"+sum);//输出总价
    }
}

菜名和价格都输出准确,最后的总价也计算正确,代码执行成功

(4). 编写Java应用程序,每次从键盘读入一个包含有大写英文字母、小写英文字母和数字混杂的字符串(例如Aa123bEFGaaa49023),要求按顺序输出大写英文字母(例如AEFG)、小写英文字母(abaaa)和数字(12349023)。要求循环连续测试10次,在报告中附上程序截图、完整的运行结果截图和简要文字说明。

由题我想到了正则表达式及字符串的替换与分解的用法

源代码:

package fourth;
import java.util.*;
import java.util.regex.*;
public class four {
    public static void main(String []args){
        for(int i=0;i<10;i++){
            System.out.print("Please input your string:");
            Scanner input=new Scanner(System.in);
            String s=input.nextLine();//s保留输入的字符串,设为输入一整行
            Pattern p;
            Matcher m;
            p=Pattern.compile("[A-Z]+");//正则化表达式,取A到Z字符
            m=p.matcher(s);
            System.out.print("The following is majuscule:");
            while(m.find()){
                String str=m.group();
                System.out.print(str);
            }
            System.out.println();
            p=Pattern.compile("[a-z]+");正则化表达式,取a到z字符
            m=p.matcher(s);
            System.out.print("The following is minuscule:");
            while(m.find()){
                String str=m.group();
                System.out.print(str);
            }
            System.out.println();
            p=Pattern.compile("[\\d+]");正则化表达式,取阿拉伯数字
            m=p.matcher(s);
            System.out.print("The following is number:");
            while(m.find()){
                String str=m.group();
                System.out.print(str);
            }
            System.out.println();
        }
    }
}

运行结果(题目给的自己瞎搞了几组数据,好像没什么大问题了)。

(5)编写Java应用程序,统计分析网页About-Shenzhen University (SZU) 中关于深圳大学的介绍的英文文章(包括题目About)中每个英文单词出现的次数(不区分大小写,不要写爬虫,可以把整篇文章的内容当作一个字符串读入),并输出出现次数最多的50个英文单词(按出现次数排序,每行输出10个英文单词,共5行)。在报告中附上程序截图、完整的运行结果截图和简要文字说明。

文本预处理,把换行符全去了,将整篇文章作为一行输入(太菜了,只能这样了QAQ)

代码:

package fifth;
import java.util.*;
import static java.lang.Character.*;
public class web {
    public static void main(String []args){
        Scanner input= new Scanner(System.in);
        StringBuilder article=new StringBuilder();//article存放输入的文章
        article.append(input.nextLine());
        for(int i=0;i<article.length();i++)
            if(isUpperCase(article.charAt(i)))
                article.setCharAt(i,toLowerCase(article.charAt(i)));//将article里面的所有大写字母转为小写
        String[] words=article.toString().split("[^a-z']");//将^和a~z之外的所有字符作为分隔符
        HashMap<String,Integer> map=new HashMap<>();//统计单词数的图
        for(String word:words) {//若拆分出来的字符不为空串,则统计出现的次数
            if (word.equals("")) continue;
            if (map.containsKey(word))
                map.replace(word, map.get(word) + 1);//若已经存在该单词的键,则对应的值+1
            else map.put(word, 1);//若不存在该单词的键,则将其对应的值设为1
        }
            List<Map.Entry<String,Integer>> list=new ArrayList<>(map.entrySet());//将哈希表中的键值对转化成List
            list.sort((o1,o2)->o2.getValue().compareTo(o1.getValue()));//降序排序
            for(int i=0;i<5;i++){//输出出现次数最多的前50个单词
                for(int j=0;j<10;j++)
                    System.out.printf("%s:%d  ",list.get(i*10+j).getKey(),list.get(i*10+j).getValue());//每个单词占20个字符,左对齐
                System.out.println();
            }
    }
}

(6). 张三、李四等人是A社团成员,李四、王五等人是B社团成员,编写一个Java应用程序(要求使用集合类),输出参加A社团的人、参加B社团的人、以及同时参加两个社团的人。在报告中附上程序截图、完整的运行结果截图和详细的文字说明。(10分)

这道题中李四即是A社团的成员又是B社团的成员,他是A社团和B社团的交集,在学的集合类中,HashSet是一个可以求交、并集的类,所以这道题我用了HashSet求交集

源代码如下:

package fifth;
import java.util.*;
import java.util.HashMap;
public class six {
    public static void main(String args[]){
        HashSet<String> A=new HashSet<String>();//A社团初始化
        A.add("张三");
        A.add("李四");
        System.out.print("A的社团成员有:");
        Object []a=A.toArray();
        for(int i=0;i<A.size();i++)//输出A社团成员
            System.out.print(a[i]+" ");
        HashSet<String> B=new HashSet<String>();//B社团成员初始化
        B.add("李四");
        B.add("王五");
        System.out.print("\nB社团成员有:");
        Object []b=B.toArray();
        for(int i=0;i<B.size();i++)
            System.out.print(b[i]+" ");
        B.retainAll(A);//求A社团和B社团的交集,求到的赋值给B
        System.out.print("\n同时参加两个社团的人有:");
        Object []c=B.toArray();
        for(int i=0;i<B.size();i++)//输出同时参加两个社团的人
            System.out.print(c[i]+" ");
        System.out.println();
    }
}

(7). 有10个国家,其属性有name、GDP2020和COVID19,分别表示国家名称、国际货币基金组织公布的2020年的国内生产总值(单位:百万美元)和网易新闻2021年10月7日公布的新冠肺炎累计确诊人数。10个国家的信息如下:

package seven;
import java.util.*;
class country {//利用country存放每个国家的信息
    String name;//国家名字
    Integer GDP2020,COVID19;//2020年GDP、2019年确诊人数
    public country(String name,int GDP2020,int COVID19){//有参构造初始化
        this.name=name;
        this.GDP2020=GDP2020;
        this.COVID19=COVID19;
    }
    public String toString(){//格式化
        return String.format("%-10s%s",name,"GDP2020:"+GDP2020+"COVID19"+COVID19);
    }
}

public class seven {
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        TreeMap<country,Integer>map=new TreeMap<>(new Comparator<country>() {
            public int compare(country c1,country c2){//重写compare
                return c1.COVID19.compareTo(c2.COVID19);//升序排序
            }
        });
        for(int i=0;i<10;i++){
            String name=input.next();
            int GDP2020=input.nextInt();
            int COVID19=input.nextInt();
            map.put(new country(name,GDP2020,COVID19),COVID19);
        }
        for(country c:map.keySet())
            System.out.println(c);
    }
}

其他(例如感想、建议等等)。

这次实验是做的时间最长的一次了,主要的困难在第六题,一开始我是想这正常输入的,但是使用while(input.hasNextLine())时始终无法跳出循环,询问助教后也没有很好的解决方法,于是在助教的认同下先对文本进行处理后进行输入(删除换行符)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值