diff --git a/Main.java b/Main.java new file mode 100644 index 0000000..28d2ed2 --- /dev/null +++ b/Main.java @@ -0,0 +1,27 @@ +public class Main { + public static void main(String[] args) { + int[] voltages = {10, -5, 7, 105, 999, 89, 76, 74}; + int validCount = 0; // 有效数据个数 + double validSum = 0; // 有效数据总和 + + for (int voltage : voltages) { + if (voltage == 999) { + System.out.println("程序终止,传感器离线"); + break; // 遇到999,终止程序 + } else if (voltage < 0) { + System.out.println("警告:发现负数,数据已跳过"); + } else if (voltage >= 1 && voltage <= 100) { + validCount++; + validSum += voltage; + } + // 其他情况(如>100)不处理 + } + + if (validCount > 0) { + double average = validSum / validCount; + System.out.printf("有效数据个数:%d,平均值:%.2f\n", validCount, average); + } else { + System.out.println("没有收集到有效数据,打印初始状态"); + } + } +} diff --git a/QQ20260309-200157.png b/QQ20260309-200157.png new file mode 100644 index 0000000..e01bff2 Binary files /dev/null and b/QQ20260309-200157.png differ diff --git a/REMEAD2.md b/REMEAD2.md new file mode 100644 index 0000000..338c97f --- /dev/null +++ b/REMEAD2.md @@ -0,0 +1,53 @@ +import java.util.Scanner; + +/** +* 温度转换程序(与Python版本功能完全等效) +* 输入格式:温度值 + 空格 + 单位(C/F),例如 36.6 C 或 97 F +* 功能:实现摄氏温度↔华氏温度的相互转换 + */ + public class TemperatureConverter { + // 摄氏温度转换为华氏温度的核心方法 + public static double celsiusToFahrenheit(double celsius) { + return celsius * 9.0 / 5.0 + 32; + } + + // 华氏温度转换为摄氏温度的核心方法 + public static double fahrenheitToCelsius(double fahrenheit) { + return (fahrenheit - 32) * 5.0 / 9.0; + } + + // 程序主入口,处理输入和输出逻辑 + public static void main(String[] args) { + // 创建Scanner对象接收用户输入 + Scanner scanner = new Scanner(System.in); + + // 提示语与你的Python程序完全一致 + System.out.print("请输入要转换的温度与单位(例如 36.6 C 或 97 F):"); + + // 读取温度值和单位(兼容空格分隔的输入格式) + double temperature; + String unit; + try { + temperature = scanner.nextDouble(); // 读取温度数值 + unit = scanner.next().toUpperCase(); // 读取单位并统一转为大写(兼容小写输入) + } catch (Exception e) { + System.out.println("输入格式错误!请按示例格式输入(如:36.6 C)"); + scanner.close(); + return; + } + + // 根据单位执行转换并输出结果 + if (unit.equals("C")) { + double result = celsiusToFahrenheit(temperature); + System.out.printf("%.2f C = %.2f F%n", temperature, result); + } else if (unit.equals("F")) { + double result = fahrenheitToCelsius(temperature); + System.out.printf("%.2f F = %.2f C%n", temperature, result); + } else { + System.out.println("单位错误!仅支持 C(摄氏)或 F(华氏)"); + } + + // 关闭Scanner,释放资源 + scanner.close(); + } + } \ No newline at end of file diff --git a/TemperatureConverter.java b/TemperatureConverter.java new file mode 100644 index 0000000..d90b60d --- /dev/null +++ b/TemperatureConverter.java @@ -0,0 +1,53 @@ +import java.util.Scanner; + +/** + * 温度转换程序(与Python版本功能完全等效) + * 输入格式:温度值 + 空格 + 单位(C/F),例如 36.6 C 或 97 F + * 功能:实现摄氏温度↔华氏温度的相互转换 + */ +public class TemperatureConverter { + // 摄氏温度转换为华氏温度的核心方法 + public static double celsiusToFahrenheit(double celsius) { + return celsius * 9.0 / 5.0 + 32; + } + + // 华氏温度转换为摄氏温度的核心方法 + public static double fahrenheitToCelsius(double fahrenheit) { + return (fahrenheit - 32) * 5.0 / 9.0; + } + + // 程序主入口,处理输入和输出逻辑 + public static void main(String[] args) { + // 创建Scanner对象接收用户输入 + Scanner scanner = new Scanner(System.in); + + // 提示语与你的Python程序完全一致 + System.out.print("请输入要转换的温度与单位(例如 36.6 C 或 97 F):"); + + // 读取温度值和单位(兼容空格分隔的输入格式) + double temperature; + String unit; + try { + temperature = scanner.nextDouble(); // 读取温度数值 + unit = scanner.next().toUpperCase(); // 读取单位并统一转为大写(兼容小写输入) + } catch (Exception e) { + System.out.println("输入格式错误!请按示例格式输入(如:36.6 C)"); + scanner.close(); + return; + } + + // 根据单位执行转换并输出结果 + if (unit.equals("C")) { + double result = celsiusToFahrenheit(temperature); + System.out.printf("%.2f C = %.2f F%n", temperature, result); + } else if (unit.equals("F")) { + double result = fahrenheitToCelsius(temperature); + System.out.printf("%.2f F = %.2f C%n", temperature, result); + } else { + System.out.println("单位错误!仅支持 C(摄氏)或 F(华氏)"); + } + + // 关闭Scanner,释放资源 + scanner.close(); + } +} \ No newline at end of file diff --git a/W1 b/W1 new file mode 100644 index 0000000..e69de29 diff --git a/W3/Main.class b/W3/Main.class new file mode 100644 index 0000000..faa23ec Binary files /dev/null and b/W3/Main.class differ diff --git a/W3/Main.java b/W3/Main.java new file mode 100644 index 0000000..51537f5 --- /dev/null +++ b/W3/Main.java @@ -0,0 +1,169 @@ +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartUtils; +import org.jfree.chart.JFreeChart; +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.DefaultPieDataset; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +public class Main { + public static void main(String[] args) { + try { + // 1. 爬取电影数据 + MovieCrawler crawler = new MovieCrawler(); + List movies = crawler.crawlTopMovies(50); // 爬取50部电影 + + // 2. 数据清洗 + List cleanedMovies = cleanData(movies); + + // 3. 数据存储 + saveToCSV(cleanedMovies, "movies.csv"); + + // 4. 数据分析 + analyzeData(cleanedMovies); + + // 5. 结果展示 + displayResults(cleanedMovies); + generateCharts(cleanedMovies); + + System.out.println("爬取完成!共获取了 " + cleanedMovies.size() + " 部电影数据。"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static List cleanData(List movies) { + return movies.stream() + .map(movie -> { + // 去空格 + movie.setTitle(movie.getTitle().trim()); + movie.setGenre(movie.getGenre().trim()); + movie.setDirector(movie.getDirector().trim()); + movie.setActors(movie.getActors().trim()); + movie.setSynopsis(movie.getSynopsis().trim()); + return movie; + }) + .collect(Collectors.toList()); + } + + private static void saveToCSV(List movies, String fileName) throws IOException { + try (FileWriter writer = new FileWriter(fileName)) { + // 写入表头 + writer.write("Title,Year,Rating,Genre,Director,Actors,Synopsis\n"); + + // 写入数据 + for (Movie movie : movies) { + writer.write(String.format("%s,%d,%.1f,%s,%s,%s,%s\n", + escapeCSV(movie.getTitle()), + movie.getYear(), + movie.getRating(), + escapeCSV(movie.getGenre()), + escapeCSV(movie.getDirector()), + escapeCSV(movie.getActors()), + escapeCSV(movie.getSynopsis()))); + } + } + } + + private static String escapeCSV(String value) { + if (value == null) return ""; + if (value.contains(",") || value.contains("\n") || value.contains("\"")) { + value = value.replace("\"", "\"\""); + return "\"" + value + "\""; + } + return value; + } + + private static void analyzeData(List movies) { + System.out.println("\n=== 数据分析结果 ==="); + + // 1. 评分分布 + System.out.println("\n1. 评分分布:"); + Map ratingDistribution = movies.stream() + .collect(Collectors.groupingBy(Movie::getRating, Collectors.counting())); + ratingDistribution.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> System.out.printf("评分 %.1f: %d 部\n", entry.getKey(), entry.getValue())); + + // 2. 年份分布 + System.out.println("\n2. 年份分布:"); + Map yearDistribution = movies.stream() + .collect(Collectors.groupingBy(Movie::getYear, Collectors.counting())); + yearDistribution.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> System.out.printf("年份 %d: %d 部\n", entry.getKey(), entry.getValue())); + + // 3. 导演作品数排行 + System.out.println("\n3. 导演作品数排行:"); + Map directorCount = movies.stream() + .collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting())); + directorCount.entrySet().stream() + .sorted(Map.Entry.comparingByValue().reversed()) + .limit(10) + .forEach(entry -> System.out.printf("%s: %d 部\n", entry.getKey(), entry.getValue())); + + // 4. 平均评分 + double averageRating = movies.stream() + .mapToDouble(Movie::getRating) + .average() + .orElse(0); + System.out.printf("\n4. 平均评分:%.2f\n", averageRating); + } + + private static void displayResults(List movies) { + System.out.println("\n=== 电影数据列表 ==="); + System.out.printf("%-50s %-10s %-10s %-30s %-30s\n", "Title", "Year", "Rating", "Genre", "Director"); + System.out.println("-------------------------------------------------------------------------------------------------------------------------------"); + + for (Movie movie : movies) { + System.out.printf("%-50s %-10d %-10.1f %-30s %-30s\n", + truncate(movie.getTitle(), 50), + movie.getYear(), + movie.getRating(), + truncate(movie.getGenre(), 30), + truncate(movie.getDirector(), 30)); + } + } + + private static String truncate(String text, int maxLength) { + return text.length() > maxLength ? text.substring(0, maxLength - 3) + "..." : text; + } + + private static void generateCharts(List movies) throws IOException { + // 1. 评分分布饼图 + DefaultPieDataset ratingDataset = new DefaultPieDataset(); + Map ratingDistribution = movies.stream() + .collect(Collectors.groupingBy(Movie::getRating, Collectors.counting())); + ratingDistribution.forEach((rating, count) -> ratingDataset.setValue(String.valueOf(rating), count)); + + JFreeChart ratingChart = ChartFactory.createPieChart( + "电影评分分布", + ratingDataset, + true, + true, + false + ); + ChartUtils.saveChartAsPNG(new File("rating_distribution.png"), ratingChart, 800, 600); + + // 2. 年份与评分关系图 + DefaultCategoryDataset yearRatingDataset = new DefaultCategoryDataset(); + Map yearAverageRating = movies.stream() + .collect(Collectors.groupingBy(Movie::getYear, + Collectors.averagingDouble(Movie::getRating))); + yearAverageRating.forEach((year, avgRating) -> yearRatingDataset.addValue(avgRating, "评分", String.valueOf(year))); + + JFreeChart yearRatingChart = ChartFactory.createBarChart( + "年份与平均评分关系", + "年份", + "平均评分", + yearRatingDataset + ); + ChartUtils.saveChartAsPNG(new File("year_rating_relation.png"), yearRatingChart, 800, 600); + + System.out.println("\n图表已生成:rating_distribution.png 和 year_rating_relation.png"); + } +} diff --git a/W3/Movie.java b/W3/Movie.java new file mode 100644 index 0000000..2e4dc55 --- /dev/null +++ b/W3/Movie.java @@ -0,0 +1,89 @@ +public class Movie { + private String title; + private int year; + private double rating; + private String genre; + private String director; + private String actors; + private String synopsis; + + public Movie() { + } + + public Movie(String title, int year, double rating, String genre, String director, String actors, String synopsis) { + this.title = title; + this.year = year; + this.rating = rating; + this.genre = genre; + this.director = director; + this.actors = actors; + this.synopsis = synopsis; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public double getRating() { + return rating; + } + + public void setRating(double rating) { + this.rating = rating; + } + + public String getGenre() { + return genre; + } + + public void setGenre(String genre) { + this.genre = genre; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public String getActors() { + return actors; + } + + public void setActors(String actors) { + this.actors = actors; + } + + public String getSynopsis() { + return synopsis; + } + + public void setSynopsis(String synopsis) { + this.synopsis = synopsis; + } + + @Override + public String toString() { + return "Movie{" + + "title='" + title + '\'' + + ", year=" + year + + ", rating=" + rating + + ", genre='" + genre + '\'' + + ", director='" + director + '\'' + + "}"; + } +} diff --git a/W3/MovieCrawler.java b/W3/MovieCrawler.java new file mode 100644 index 0000000..851fbb0 --- /dev/null +++ b/W3/MovieCrawler.java @@ -0,0 +1,141 @@ +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class MovieCrawler { + private static final String BASE_URL = "https://movie.douban.com/top250"; + private static final int DELAY_MS = 1000; // 控制请求频率 + + public List crawlTopMovies(int limit) throws IOException { + List movies = new ArrayList<>(); + int page = 0; + + System.out.println("Starting to crawl movies..."); + + while (movies.size() < limit) { + String url = BASE_URL + "?start=" + page * 25; + System.out.println("Crawling page: " + url); + + try { + Document doc = Jsoup.connect(url) + .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") + .timeout(10000) + .get(); + + // 打印页面标题,确认是否成功获取页面 + System.out.println("Page title: " + doc.title()); + + // 选择电影元素 + Elements movieElements = doc.select(".item"); + System.out.println("Found " + movieElements.size() + " movie elements"); + + for (Element element : movieElements) { + if (movies.size() >= limit) break; + + int currentCount = movies.size() + 1; + System.out.println("Processing movie " + currentCount + "..."); + + try { + Movie movie = parseMovie(element); + if (movie != null) { + movies.add(movie); + System.out.println("Added movie: " + movie.getTitle()); + } else { + System.out.println("Skipping movie, parsing failed"); + } + + // 控制请求频率 + Thread.sleep(DELAY_MS); + } catch (Exception e) { + System.err.println("Error parsing movie: " + e.getMessage()); + e.printStackTrace(); + } + } + + page++; + } catch (Exception e) { + System.err.println("Error crawling page: " + e.getMessage()); + e.printStackTrace(); + break; + } + } + + System.out.println("Crawling finished. Found " + movies.size() + " movies."); + return movies; + } + + private Movie parseMovie(Element element) { + try { + // 提取标题 + Element titleElement = element.selectFirst(".hd .title"); + if (titleElement == null) { + System.err.println("Title element not found"); + return null; + } + String title = titleElement.text(); + System.out.println("Title: " + title); + + // 提取年份 + Element yearElement = element.selectFirst(".bd p:first-child"); + if (yearElement == null) { + System.err.println("Year element not found"); + return null; + } + String yearText = yearElement.text().trim(); + System.out.println("Year text: " + yearText); + + // 从字符串中提取年份 + int year = 0; + // 使用正则表达式提取年份 + java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(\\d{4})").matcher(yearText); + if (matcher.find()) { + year = Integer.parseInt(matcher.group(1)); + } + if (year == 0) { + System.err.println("Year not found in text: " + yearText); + return null; + } + System.out.println("Year: " + year); + + // 提取评分 + Element ratingElement = element.selectFirst(".rating_num"); + if (ratingElement == null) { + System.err.println("Rating element not found"); + return null; + } + String ratingText = ratingElement.text(); + System.out.println("Rating text: " + ratingText); + + double rating = Double.parseDouble(ratingText); + System.out.println("Rating: " + rating); + + // 提取类型 + String genre = ""; + String infoText = yearElement.text(); + if (infoText.contains("/")) { + String[] parts = infoText.split("/"); + if (parts.length > 2) { + genre = parts[2].trim(); + } + } + System.out.println("Genre: " + genre); + + // 简化处理,不进入详情页 + String director = ""; + String actors = ""; + String synopsis = ""; + + System.out.println("Parsed movie: " + title + " (" + year + ") - " + rating + " - " + genre); + return new Movie(title, year, rating, genre, director, actors, synopsis); + } catch (Exception e) { + System.err.println("Error parsing movie: " + e.getMessage()); + e.printStackTrace(); + return null; + } + } +} diff --git a/W3/jcommon-1.0.24.jar b/W3/jcommon-1.0.24.jar new file mode 100644 index 0000000..4f1015d Binary files /dev/null and b/W3/jcommon-1.0.24.jar differ diff --git a/W3/jfreechart-1.5.4.jar b/W3/jfreechart-1.5.4.jar new file mode 100644 index 0000000..ddd7c23 Binary files /dev/null and b/W3/jfreechart-1.5.4.jar differ diff --git a/W3/jsoup-1.17.2.jar b/W3/jsoup-1.17.2.jar new file mode 100644 index 0000000..52ae16d Binary files /dev/null and b/W3/jsoup-1.17.2.jar differ diff --git a/W3/movies.csv b/W3/movies.csv new file mode 100644 index 0000000..59bd512 --- /dev/null +++ b/W3/movies.csv @@ -0,0 +1,51 @@ +Title,Year,Rating,Genre,Director,Actors,Synopsis +肖申克的救赎,1994,9.7,美国,,, +霸王别姬,1993,9.6,中国大陆 中国香港,,, +泰坦尼克号,1997,9.5,剧情 爱情 灾难,,, +阿甘正传,1994,9.5,美国,,, +千与千寻,2001,9.4,日本,,, +美丽人生,1997,9.5,剧情 喜剧 爱情 战争,,, +星际穿越,2014,9.4,剧情 科幻 冒险,,, +这个杀手不太冷,1994,9.4,法国 美国,,, +盗梦空间,2010,9.4,剧情 科幻 悬疑 冒险,,, +楚门的世界,1998,9.4,美国,,, +辛德勒的名单,1993,9.5,剧情 历史 战争,,, +忠犬八公的故事,2009,9.4,剧情,,, +海上钢琴师,1998,9.3,意大利,,, +疯狂动物城,2016,9.3,美国,,, +三傻大闹宝莱坞,2009,9.2,印度,,, +机器人总动员,2008,9.3,美国,,, +放牛班的春天,2004,9.3,剧情 音乐,,, +无间道,2002,9.3,梁朝伟 Tony Leung Chiu W... 2002,,, +控方证人,1957,9.6,美国,,, +寻梦环游记,2017,9.1,美国,,, +大话西游之大圣娶亲,1995,9.2,中国香港 中国大陆,,, +熔炉,2011,9.3,... 2011,,, +触不可及,2011,9.3,法国,,, +教父,1972,9.3,剧情 犯罪,,, +末代皇帝,1987,9.3,英国 意大利 中国大陆 法国,,, +哈利·波特与魔法石,2001,9.2,Rupert Grint 2001,,, +当幸福来敲门,2006,9.1,剧情 传记 家庭,,, +龙猫,1988,9.2,日本,,, +活着,1994,9.3,姜武 Wu Jiang 1994,,, +怦然心动,2010,9.1,美国,,, +蝙蝠侠:黑暗骑士,2008,9.2,剧情 动作 科幻 犯罪 惊悚,,, +指环王3:王者无敌,2003,9.3,美国 新西兰,,, +我不是药神,2018,9.0,周... 2018,,, +乱世佳人,1939,9.3,美国,,, +飞屋环游记,2009,9.1,美国,,, +让子弹飞,2010,9.0,周润发 Yun-F... 2010,,, +哈尔的移动城堡,2004,9.1,日本,,, +十二怒汉,1957,9.4,美国,,, +海蒂和爷爷,2015,9.3,德国 瑞士,,, +素媛,2013,9.3,韩国,,, +猫鼠游戏,2002,9.1,传记 犯罪 剧情,,, +天空之城,1986,9.2,日本,,, +鬼子来了,2000,9.3,... 2000,,, +摔跤吧!爸爸,2016,9.0,印度,,, +少年派的奇幻漂流,2012,9.1,美国 中国台湾 英国 加拿大,,, +钢琴家,2002,9.3,剧情 传记 战争 音乐,,, +指环王2:双塔奇兵,2002,9.2,美国 新西兰,,, +死亡诗社,1989,9.2,美国,,, +大话西游之月光宝盒,1995,9.0,中国香港 中国大陆,,, +绿皮书,2018,8.9,美国 中国大陆,,, diff --git a/W3/rating_distribution.png b/W3/rating_distribution.png new file mode 100644 index 0000000..90e4c1b Binary files /dev/null and b/W3/rating_distribution.png differ diff --git a/W3/year_rating_relation.png b/W3/year_rating_relation.png new file mode 100644 index 0000000..f4dcc9f Binary files /dev/null and b/W3/year_rating_relation.png differ diff --git a/作业.txt b/作业.txt new file mode 100644 index 0000000..e69de29 diff --git a/心得2.txt b/心得2.txt new file mode 100644 index 0000000..e69de29