import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.*;public class Ebbinghaus {private static final Logger log = LoggerFactory.getLogger(Ebbinghaus.class);private List<LearnRow> schemeTable = new ArrayList<>();//生成的计划表private HashMap<Integer, LearnRow> DayToTabMap = new HashMap<>();//映射计划表中行元素信息 <天数,映射对应的计划表Row>private LinkedHashMap<Integer, Integer> learnStateMap = new LinkedHashMap<>();//学习情况表 <当日计划表中是第几天,当日学习单词量>private int sumWordSize;//总单词量private int needLearnDay;//还需要学习的天数private int learnedWordCount = 0;//学习过的单词数private int nowDay = 1;//当前天数class LearnRow {private int toLearnIndex;//需要学习哪天的单词列表的索引private List<Integer> toReviewList;public LearnRow() {}public LearnRow(int toLearnIndex, List<Integer> toReviewList) {this.toLearnIndex = toLearnIndex;this.toReviewList = toReviewList;}@Overridepublic String toString() {return "LearnRow{" +"toLearnIndex=" + toLearnIndex +", toReviewList=" + toReviewList +'}';}public int getToLearnIndex() {return toLearnIndex;}public void setToLearnIndex(int toLearnIndex) {this.toLearnIndex = toLearnIndex;}public List<Integer> getToReviewList() {return toReviewList;}public void setToReviewList(List<Integer> toReviewList) {this.toReviewList = toReviewList;}}public Ebbinghaus(int sumWordSize) {this.sumWordSize = sumWordSize;}public List<LearnRow> getSchemeTable() {return schemeTable;}public HashMap<Integer, LearnRow> getDayToTabMap() {return DayToTabMap;}public LinkedHashMap<Integer, Integer> getLearnStateMap() {return learnStateMap;}/*** 添加一条学习记录信息,会导致更新*/public void pushLearnRecord(int dayToLearnWordSize) {learnStateMap.put(new Integer(nowDay++), new Integer(dayToLearnWordSize));this.learnedWordCount += dayToLearnWordSize;if (dayToLearnWordSize != 0) {this.needLearnDay = (this.sumWordSize - this.learnedWordCount) / dayToLearnWordSize;}//更新计划表此天后的计划if (learnStateMap.size() == 1) {//说明刚插入的是第一条记录,初始化计划表log.debug("初始化计划表");if (dayToLearnWordSize == 0) {//如果第一天计划0个单词,则返回错误throw new RuntimeException("第一天计划单词数不能为0");}//循环处理生成每一天的计划 每天学习当天的list 同时还要复习 1 天前的,2天前的 4天前的 7 天前的 15 天前的单词(如果存在的话)for (int i = 1; i <= this.needLearnDay + 1 + 15; i++) {if (i == 1) {//如果为第一天,生成RowArrayList<Integer> learnIndexList = new ArrayList<Integer>();LearnRow learnRow = new LearnRow(i, learnIndexList);schemeTable.add(learnRow);DayToTabMap.put(new Integer(i), learnRow);} else {//非第一天,生成RowArrayList<Integer> learnIndexList = new ArrayList<Integer>();//遍历前面每一个计划表Row,如果存在toLearnIndex不为0 的 1 天前的,2天前的 4天前的 7 天前的 15 天前的index 则加入learnIndexListfor (int j = 1; j < i; j++) {if (DayToTabMap.get(new Integer(j)).toLearnIndex != 0 && ((i - j) == 1 || (i - j) == 2 || (i - j) == 4 || (i - j) == 7 || (i - j) == 15)) {learnIndexList.add(new Integer(j));}}LearnRow learnRow = new LearnRow(i > (this.needLearnDay + 1) ? 0 : i % (this.needLearnDay + 2), learnIndexList);schemeTable.add(learnRow);DayToTabMap.put(new Integer(i), learnRow);}}log.debug(schemeTable.toString());} else {//新增的记录,判断学习单词数是否与前面一个的相同(前一天为nowDay - 2),如果不同则修改插入的该天后面的计划表 否则不变if (dayToLearnWordSize != learnStateMap.get(new Integer(nowDay - 2)).intValue()) {log.debug("需要重构表");//移除后面的表Row,重新插入新的重建Rowint size = schemeTable.size();for (int i = (this.nowDay - 1); i <= size; i++) {schemeTable.remove(this.nowDay - 2);}for (int i = (this.nowDay - 1); i <= size; i++) {DayToTabMap.remove(new Integer(i));}//重建删除项if (dayToLearnWordSize == 0) {//当插入一条学习计划为0的时候,重建删除项//需要先添加一条空的,再重建后续for (int i = this.nowDay - 1; i < this.needLearnDay + this.nowDay + 15; i++) {//处理重建数据的第一条数据,也就是当天的if (i == (this.nowDay - 1)) {ArrayList<Integer> learnIndexList = new ArrayList<Integer>();LearnRow learnRow = new LearnRow(0, learnIndexList);schemeTable.add(learnRow);DayToTabMap.put(new Integer(i), learnRow);} else {//生成RowArrayList<Integer> learnIndexList = new ArrayList<Integer>();//遍历前面每一个计划表Row,如果存在toLearnIndex不为0 的 1 天前的,2天前的 4天前的 7 天前的 15 天前的index 则加入learnIndexListfor (int j = 1; j < i; j++) {if (DayToTabMap.get(new Integer(j)).toLearnIndex != 0 && ((i - j) == 1 || (i - j) == 2 || (i - j) == 4 || (i - j) == 7 || (i - j) == 15)) {learnIndexList.add(new Integer(j));}}LearnRow learnRow = new LearnRow(i > (this.needLearnDay + this.nowDay - 1) ? 0 : i % (this.needLearnDay + this.nowDay), learnIndexList);schemeTable.add(learnRow);DayToTabMap.put(new Integer(i), learnRow);}}} else {for (int i = this.nowDay - 1; i < this.needLearnDay + this.nowDay + 15; i++) {//生成RowArrayList<Integer> learnIndexList = new ArrayList<Integer>();//遍历前面每一个计划表Row,如果存在toLearnIndex不为0 的 1 天前的,2天前的 4天前的 7 天前的 15 天前的index 则加入learnIndexListfor (int j = 1; j < i; j++) {if (DayToTabMap.get(new Integer(j)).toLearnIndex != 0 && ((i - j) == 1 || (i - j) == 2 || (i - j) == 4 || (i - j) == 7 || (i - j) == 15)) {learnIndexList.add(new Integer(j));}}LearnRow learnRow = new LearnRow(i > (this.needLearnDay + this.nowDay - 1) ? 0 : i % (this.needLearnDay + this.nowDay), learnIndexList);schemeTable.add(learnRow);DayToTabMap.put(new Integer(i), learnRow);}}} else {log.debug("不需要重构表");}log.debug(schemeTable.toString());}}public static void main(String[] args) {Ebbinghaus ebbinghaus = new Ebbinghaus(5612);ebbinghaus.pushLearnRecord(200);ebbinghaus.pushLearnRecord(200);//验证新增学习计划单词数改变ebbinghaus.pushLearnRecord(300);ebbinghaus.pushLearnRecord(300);//验证新增学习计划单词数改变 当天没进行学习,验证动态生成计划表ebbinghaus.pushLearnRecord(0);ebbinghaus.pushLearnRecord(300);ebbinghaus.pushLearnRecord(100);}
}

最近自己鼓捣的小玩意,模仿墨墨背单词APP中的的艾宾浩斯算法动态生成复习策略类似网上这种样式的计划表(不过我实现的没有打印出来只是基于内存中的)

不确定有什么Bug没,自己测试的比较简单

Java 实现简单的根据艾斯浩宾遗忘曲线动态生成计划表相关推荐

  1. Java 读取 Excel 文件内容, 根据 pdf 模板动态生成对应的 pdf 文件

    1. 下载 adobe acrobat https://www.cr173.com/soft/11135.html 2. 编辑 pdf 模板 1用 acrobat 打开 pdf 编辑模板 添加表单元素 ...

  2. Ajax简单示例之改变下拉框动态生成表格

    1.建立一个aspx页面,html代码 <html xmlns="http://www.w3.org/1999/xhtml" > <head runat=&quo ...

  3. 从零开始学习 webservice第一集,java webservice简单实例入门教程

    现在从零开始学习webservice 概念自己百度搜,总之,webservice就相当于一个接口,就像你走进了一家售货店,你不需要知道这家店怎么卖给你东西,你拿着钱去,说我要一包玉溪,人家就会给你返回 ...

  4. java简单通讯录的实现02person类_用java实现简单的小游戏(你一定玩过)

    用java实现简单的小游戏(你一定玩过) 对于java初学者来说,通过一些学习小游戏来对swing学习以及对java基础的学习是一个好的方法,同时也给学习带来了很多的乐趣,接下来就给大家分享一个jav ...

  5. java实现简单窗体小游戏----球球大作战

    java实现简单窗体小游戏----球球大作战 需求分析 1.分析小球的属性: ​ 坐标.大小.颜色.方向.速度 2.抽象类:Ball ​ 设计类:BallMain-创建窗体 ​ BallJPanel- ...

  6. Java JNI简单实现

    Java JNI简单实现 JNI(Java Native Interface)允许了Java和C&C++进行交互?这不折腾人嘛! 一.JNI简述 http://baike.baidu.com/ ...

  7. java实现账号单一ip登录,使用Java实现简单后台访问并获取IP示例

    使用Java实现简单后台访问并获取IP示例 发布时间:2020-10-28 21:57:57 来源:亿速云 阅读:92 作者:Leah 使用Java实现简单后台访问并获取IP示例?针对这个问题,这篇文 ...

  8. 用limit 实现java的简单分页

    https://blog.csdn.net/xinyuezitang/article/details/84324359 用limit 实现java的简单分页 xinyuezitang 2018-11- ...

  9. redis java应用_redis在JAVA的简单应用

    reids是一个高性能的key-value数据库.它存储的value支持各种类型的数据,如String,List,set,hash类型.在此基础上,各种不同方式的排序. 本文不具体争对redis数据库 ...

最新文章

  1. 90 后女科学家,四年完成清华大学硕博连读,解决多个世界级难题
  2. php猴子找大王算法,php 正常的猴子选大王算法
  3. python os 文件操作 chdir(path)方法
  4. 剑指OFFER之二进制中1的个数(九度OJ1513)
  5. 三思笔记_使用反射前先三思
  6. 执行Dockerfile构建基础镜像,建立python工作环境
  7. Redisson:这么强大的实现分布式锁框架,你还没有?
  8. OpenShift 4 概念 - OpenShift是如何通过ImageStream访问Image的
  9. android arcgis 添加地图,ArcGis for Android在地图上添加自定义图标
  10. org.apache.jasper.JasperException: /index.jsp(14,2) The s:form tag declares that it accepts dyna
  11. iOS知识点,iOS开发笔记
  12. Python已知经纬度求两点距离
  13. 淘宝店铺层级作用 店铺层级低有哪些影响
  14. 统计相关系数——Kendall Rank(肯德尔等级)相关系数
  15. 淡水鱼生鱼片含有大量肝吸虫 可寄生于肝脏内30年
  16. 一些个人电脑问题记录
  17. 秀动抢票教程,JS逆向分析与学习
  18. 极客时间课程笔记:业务安全
  19. 数学建模----拟合的实现
  20. Linux下查看文件和文件夹大小

热门文章

  1. winform控件缩写(七)印刷
  2. 24 Hours: 小米618三平台狂揽156项第1 科创板第1股花落华兴源创
  3. 3.HDFS之shell基本操作
  4. 新手使用GDAL详细教程
  5. 华为云AI入门赛——爱(AI)美食·美食图片分类分享
  6. Redis的配置、启动、操作和关闭
  7. 关于内聚和耦合的理解
  8. MATLAB中im2bw函数-将图像转换为二值图像
  9. 使用xtrabackup远程备份到及重建数据库
  10. 计算机美术设计基础说课教案,2012年全国“创新杯”工艺美术类说课大赛一等奖作品:《基本配色法》说课稿...