欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA Lab1

程序员文章站 2022-07-12 16:54:17
...
  • 2 实验环境配置
    2.1 安装JDK并进行环境变量的配置
    环境配置的路径:此电脑 —> 属性 —> 系统 —> 高级 —> 环境变量
    环境变量配置:添加JAVA_HOME环境变量,值为“JDK安装路径”。
    设置path:在path变量的最前面添加".;%JAVA_HOME%\bin;"
    在命令行下输入javac java等命令,如果窗口提示一些关于javac java命令的选择就代表jdk环境变量已经设置好。

    2.2 安装并使用Git
    2.2.1 在官网下载后安装
    2.2.2 设置账号和邮箱
    2.2.3 创建本地仓库
    $ git init
    2.2.4 本地仓库与GitHub的远程仓库连接
    使用HTTPS方式关联:
    git remote add origin [email protected]:”yourname”/example.git
    git push -u origin master
    2.2.5 上传文件至本地仓库,上传到远程仓库
    $ git add README.txt
    $ git commit -m “备注”
    $ git push -u origin master
    $ gir push origin master //简化命令

  • 3 实验过程
    3.1 Magic Squares
    本问题的任务主要分为两个部分:第一部分是设计一个isLegalMagicSquare()方法来判断n×n的矩阵是否为合法幻方。第二部分是理解一个n为奇数的幻方生成算法。
    3.1.1 isLegalMagicSquare()
    这个函数的功能是检验给出的矩阵是不是幻方,并且给出其不是幻方时的错误。
    首先是使用Java文本读入,读取矩阵,在读取时进行判断:

  1. 分隔符是否符合要求
    据题目可得,幻方的各个元素之间的分隔符必须为\t,所以将整个方阵的字符串中的\t \n换成空格,然后进行分割存入字符串数组。检查这个数组,如果产生了“ ”,则这个数组未合法使用分隔符。
  2. 检查输入是否均为正整数
    使用正则表达式来判断数组的各个元素是否为正整数。如果不是,则进行报错。
  3. 检查矩阵是否为方阵
    在之前的步骤当中记录下矩阵的最大列数,然后对行列数进行比较判断。
  4. 检查行、列、斜边相加的值是否相等
    先将字符串变为线性字符串数组。然后依据行和列之间的数学关系进行运算,计算行、列、斜边三条线上的和,如果不是幻方则报错。
    3.1.2 generateMagicSquare()
    通过实验报告中所给的源代码可以看出,这是幻方生成算法中的罗伯法。

具体步骤如下:

  1. 首先将最小的数放在第一行的*。
  2. 接下来将每一个数放在前一个数的右上方
  3. 如果这个数要放的方格已经超过了边缘,则把这个数放在另一个边缘。(e.g:超出第一行最右列,就放在最后一行的最左列)
  4. 如果方格被占用就填写到这个方格的下面一个方格。

P.S:此方法只适用于正奇数。当我们输入一个正偶数时,会发生数组越界的情况,导致无法正常生成幻方。

3.2 Turtle Graphics
先自主学习java的一个第三方画图方案Turtle,并且通过给出的现有的Turtle方法,根据代码注释部分要求的画图任务进行编写代码。
3.2.1 Problem 1: Clone and import
在网站上直接找到教师的仓库,并且下载相关文件到本地,进行参考。

3.2.2 Problem
3: Turtle graphics and drawSquare

在Turtle.java文件中定义了在画图当中所需要的接口:
public void forward(int units);
在当前方向画直线,units为长度,单位为内部规定单位
public void turn(double degrees);
按照顺时针方向进行转向
public void color(PenColor color);
改变画笔的颜色

编写drawSquare():画一个正方形,画笔初始方向向上。通过循环控制,画出正方形。

	public static void drawSquare(Turtle turtle, int sideLength) {
		try {
			turtle.color(PenColor.GREEN);// 将笔的颜色调为绿色(because I like)
			for (int i = 0; i < 4; i++) {// 通过循环画出正方形
				turtle.forward(sideLength);// 直走 长度
				turtle.turn(90);// 转90°
			}
		} catch (Exception e) {
			throw new RuntimeException("implement me!");
		}
	}

3.2.3 Problem 5: Drawing polygons
3.2.3.1 caculateRegularPolyAngle

函数功能:计算正多边形的内角和,输入的参数为正多边形的边数。计算依据的数学关系是,正多边形的外角和为360°,且均相等。
3.2.3.2 caculatePolygonSidesFromAngle
函数功能:得到内角就可以知道外角 ,然后来计算正多边形的边数。
3.2.3.3 drawRegularPolygon
函数功能:使用了上一个函数的功能,输入的参数为边数和边长,根据计算的内角,从而控制画笔turn的方向。
3.2.4 Problem 6: Calculating Bearings
3.2.4.1 calculateHeadingToPoint

函数功能:计算给定的两个向量之间的方向角。首先对给出的点进行处理,得到向量(当前点与目标点构成的向量),然后得出其与y轴之间的tan值,使用函数计算得出夹角,再和当前朝向的夹角计算出两个向量之间的夹角。
在计算夹角的过程之中,注意如果得到的夹角为负角时,需要将夹角改为正值。
3.2.4.2 caculateHeadings
函数功能:计算一系列边构成的向量之间的夹角,得出方向转动的大小。使用上一个函数,计算得出转动角度,使用List存储。
3.2.5 Problem 7: Convex Hulls
在实现这个功能时,使用的一个判断方向角度的方法。

	public static int orientation(Point p, Point q, Point r) {
		double val = (q.y() - p.y()) * (r.x() - q.x()) - (q.x() - p.x()) * (r.y() - q.y());

		if (val == 0)
			return 0; // collinear
		return (val > 0) ? 1 : 2; // clock or counterclock wise
	}

判断共线、逆时针或者顺时针的情况。
函数思想:在找到所有点中最左的点,然后逆时针开始访问各点,找到最边缘的点,存储起来。从最左边的点p开始一直找到起始点p,搜索条件为orientation(p,x,q)的方向对于所有点“x”都是逆时针的。跟踪q中最后访问的最逆时针的点,如果没有一个点比q更为逆时针,那么更新q。

3.3 Social Network
设计并实现Person和FriendshipGraph两个类。建立起一个图,通过输入搭建起有向的社交网络,并且输出。

3.3.1 设计/实现FriendshipGraph类
数据结构设计:
使用List persons= new ArrayList<>();来存储所有的人(节点)。
设计思路:

  1. public void addVertex(Person A)
    添加新的节点。在迭代遍历的时候,对重名进行判断。
  2. public void addEdge(Person A,Person B)
    添加A—>B的有向边。调用了Person中的getFriend()进行遍历,防止重复。
  3. public int getDistance(Person A,Person B)
    使用了queue的数据结构,利用BFS广度优先搜索求两个节点之间的最短路径。
    3.3.2 设计/实现Person类
    数据结构设计:
    List friendList = new ArrayList<>();用来存储当前节点的出边,即friend。
    public boolean visited;用来标记是否访问过该节点。
    设计思路:
  4. public void addFriend(Person X)
    向朋友列表里面添加新的朋友。即添加新的出边节点。
  5. public List getFriend()
    获取当前节点的friendList。
  6. public String getName()
    获取当前节点的name

3.3.3 设计/实现客户端代码main()
main函数即为实验要求的指令。
3.3.4 设计/实现测试用例
测试用例主要涵盖了所有正常和异常的情况。比如添加时重名,重边,单向边,计算路径得到正常数据和没有路径输出表示异常的情况。

3.4 Tweet Tweet
3.4.1 Problem 1: Extracting data from tweets

设计思路:

  1. public static Timespan getTimespan(List tweets)
    循环遍历tweet数组,记录tweet发表时间的最大和最小值,从而获得一个Timespan。
    使用Time中的before和after函数对时间的早晚进行比较。
  2. public static Set getMentionedUsers(List tweets)
    将所有的tweet内容放入一个字符串中,使用正则表达式对@和合法的username进行筛选,从而得到@后面的用户名。

3.4.2 Problem 2: Filtering lists of tweets
设计思路:

  1. public static List writtenBy(List tweets, String username)
    循环比较author和username在转换为小写的情况下是否相同。
  2. public static List inTimespan(List tweets, Timespan timespan)
    找到在时间范围内所发的推特信息。
  3. public static List containing(List tweets, List words)
    遍历作为参数的tweet信息,如果该tweet包含输入的words字符串的所有内容(在lowercase情况下),则将这条tweet返回。

3.4.3 Problem 3: Inferring a social network
设计思路:
1.

public static Map<String,Set<String>>guessFollowsGraph(List<Tweet> tweets)
Map<String, Set<String>> followMap = new HashMap<String, Set<String>>();
    	List<Tweet> social = new ArrayList<Tweet>();//all the tweets
    	for(Tweet tweet : social) {
    		Set<String> match = Extract.getMentionedUsers(Arrays.asList(tweet));//a tweet's @
    		followMap.put(tweet.getAuthor().toLowerCase(),match);
    		for(String author : match) {
    			if(!author.equals(tweet.getAuthor())){
    				followMap.get(tweet.getAuthor().toLowerCase()).add(author.toLowerCase());
    			}
    		}
    	}
    	return followMap;

将tweet的列表进行遍历,使用getMentionedUsers,将所有被@的人计入Map。
2.

public static List<String> influencers(Map<String, Set<String>> followsGraph)
    	 List<String> InfluenceList = new ArrayList<String>();
         Map<String, Integer> influencers = new HashMap<String, Integer>();
         int influenceCount;
         for (Set<String> follows : followsGraph.values()){
             for(String i: follows){
                 if(influencers.containsKey(i)){
                     influenceCount = influencers.get(i) + 1;
                     influencers.put(i.toLowerCase(), influenceCount);
                 }
                 else{
                     influencers.put(i.toLowerCase(), 1);
                 }
             }
         }
         
         //sort the influencers and put them in InfluenceList
         while(!influencers.isEmpty()){
             int topfollowers = Collections.max(influencers.values());
             for (String name : influencers.keySet()){
                 if(influencers.get(name).equals(topfollowers)){
                     InfluenceList.add(name);
                     influencers.remove(name);
                     break;
                 }
             }
         }
         return InfluenceList;

将tweet的列表进行遍历,使用getMentionedUsers,将所有@的人以及他们被@的次数放在Map中,再根据他们被@的次数来对其进行排序。
3.4.4 Problem 4: Get smarter
如果A是B的follower,B是C的follower,那么A也是C的follower。即将C也添加到Map中。

相关标签: Java

上一篇: lab2

下一篇: 缓存分布式锁探索