小说人物统计系统

该博客介绍了一个基于Java的小说人物统计系统,系统能够分析人物的出场次数、篇幅跨度,通过可视化图表展示,并计算人物间的关联程度,形成关系紧密度排名。此外,还能识别可能的人物小团队。
摘要由CSDN通过智能技术生成

 由于要求种类多,于是按照每一个要求相关功能设计了一个类名

设计要求

事先指定其中10个重要人物,考虑他们的姓名、别名等等一系列因素。

  1. 画出每个人在小说中出现位置的可视化图(图可以自行设计)。排序每人出现的次数,并在界面上用柱状图显示。
  2. 统计每个人在小说中出现的篇幅跨度(第一次出现距最后一次出现的篇幅)并排序,并在界面上用柱状图显示,针对每个人物,柱状图中列出该人篇幅跨度起始点到终点位于全文的百分比哪个位置。(1,2为字符串处理)
  3. 如果两人在较短的一段文字(如500字/1000字范围,具体可自定)中出现,我们认为两人有联系。有联系的次数越多,关系越紧密。自行设计统计标准,对于10个人物:
  4. 用表格列出10个人物相互关系紧密程度。并对关系紧密程度进行排序,列在界面上。(10*10)
  5. 输入一个人名,列出该人和其他九人关系的紧密程度并排名。
  6. 如果多人多次在一段文字中出现,我们认为多人组成小团队。自行设计算法,统计出10个人物中,哪些人可能是小团队?

运行结果

排序每人出现的次数,并在界面上用柱状图显示,鼠标悬停也可显示

用表格列出十个人物相互关系紧密程度

统计出10个人物中,哪些人可能是小团队

统计每个人在小说中出现的篇幅跨度并排序,横轴显示该人篇幅跨度起始点到终点位于全文的百分比哪个位置,鼠标悬停也可显示

画出每个人在小说中出现位置的可视化图

输入一个人名,列出该人和其他九人关系的紧密程度并排名

实验代码

AppearSpanSortingPanel类:

import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.List;
import javax.swing.*;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.chart.plot.PlotOrientation;


public class AppearSpanSortingPanel extends JPanel {

    public static JPanel AppearSpanSorting_Panel() throws IOException {
        String[] nameArray = new String[]{
                "刘备", "魏延", "关羽", "张飞", "董卓", "吕布", "孙权", "周瑜", "司马懿", "曹操"
        };

        ArrayList<Person> list = new ArrayList<>();
        CharacterReader getname = new CharacterReader();
        String U = getname.readNovel();

        for (int i = 0; i < nameArray.length; i++) {
            int times = getname.appearTimes(nameArray[i]);
            int span = getname.appearSpan(nameArray[i]);
            list.add(new Person(nameArray[i], times, span));
        }
        Collections.sort(list, Comparator.comparingInt(Person::getSpan));
        CategoryDataset dataset = createDataset(list);

        JFreeChart chart = ChartFactory.createBarChart(
                "人物篇幅跨度统计图",
                "人物",
                "篇幅跨度",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false);

        Font titleFont = new Font("黑体", Font.BOLD, 20);
        Font labelFont = new Font("黑体", Font.BOLD, 15);
        chart.getTitle().setFont(titleFont);

        CategoryAxis domainAxis1 = new CategoryAxis("人物");
        NumberAxis rangeAxis1 = new NumberAxis("篇幅跨度");
        NumberAxis rangeAxis2 = new NumberAxis("相对百分比");
        rangeAxis2.setNumberFormatOverride(new DecimalFormat("0%"));
        rangeAxis2.setRange(0, 1);

        BarRenderer renderer = new BarRenderer();
        renderer.setDefaultItemLabelsVisible(true);  // 启用数据标签显示
        //  renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator()); //在柱子上显示相应信息

        CategoryDataset dataset1 = createPercentageDataset(list, U);

        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setDataset(0, dataset1);
        plot.setDomainAxis(0, domainAxis1);


        renderer.setSeriesPaint(0,new Color(5, 189, 248));


        // 设置横轴标签字体
        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setTickLabelFont(labelFont);
        domainAxis.setLabelFont(labelFont);

        // 设置标签角度,防止中文标签乱码
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.toRadians(70))); // 70度倾斜
        domainAxis.setMaximumCategoryLabelWidthRatio(0.35f);



        plot.setRangeAxis(0, rangeAxis1);
        plot.setRangeAxis(1, rangeAxis2);
        plot.setRenderer(0, renderer);

        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(800, 700));
        JPanel AppearSpanSortingPanel = new JPanel();
        AppearSpanSortingPanel.add(chartPanel);

        return AppearSpanSortingPanel;
    }

    private static CategoryDataset createDataset(List<Person> list) {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (Person person : list) {
            dataset.addValue(person.getSpan(), "篇幅跨度", person.getName());
        }
        return dataset;
    }

    private static CategoryDataset createPercentageDataset(List<Person> list, String U) {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (Person person : list) {
            double startPercentage = (U.indexOf(person.getName()) / (double) U.length()) * 100;
            double endPercentage = (U.lastIndexOf(person.getName()) / (double) U.length()) * 100;

            // 使用 DecimalFormat 进行格式化,保留两位小数
            DecimalFormat decimalFormat = new DecimalFormat("#.##");
            String formattedStartPercentage = decimalFormat.format(startPercentage);
            String formattedEndPercentage = decimalFormat.format(endPercentage);

            dataset.addValue(
                    person.getSpan(),
                    "篇幅跨度"
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loop_kc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值