Java 实现简单的根据艾斯浩宾遗忘曲线动态生成计划表 | 您所在的位置:网站首页 › 遗忘曲线天数 › Java 实现简单的根据艾斯浩宾遗忘曲线动态生成计划表 |
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 schemeTable = new ArrayList();//生成的计划表
private HashMap DayToTabMap = new HashMap();//映射计划表中行元素信息
private LinkedHashMap learnStateMap = new LinkedHashMap();//学习情况表
private int sumWordSize;//总单词量
private int needLearnDay;//还需要学习的天数
private int learnedWordCount = 0;//学习过的单词数
private int nowDay = 1;//当前天数
class LearnRow {
private int toLearnIndex;//需要学习哪天的单词列表的索引
private List toReviewList;
public LearnRow() {
}
public LearnRow(int toLearnIndex, List toReviewList) {
this.toLearnIndex = toLearnIndex;
this.toReviewList = toReviewList;
}
@Override
public String toString() {
return "LearnRow{" +
"toLearnIndex=" + toLearnIndex +
", toReviewList=" + toReviewList +
'}';
}
public int getToLearnIndex() {
return toLearnIndex;
}
public void setToLearnIndex(int toLearnIndex) {
this.toLearnIndex = toLearnIndex;
}
public List getToReviewList() {
return toReviewList;
}
public void setToReviewList(List toReviewList) {
this.toReviewList = toReviewList;
}
}
public Ebbinghaus(int sumWordSize) {
this.sumWordSize = sumWordSize;
}
public List getSchemeTable() {
return schemeTable;
}
public HashMap getDayToTabMap() {
return DayToTabMap;
}
public LinkedHashMap 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) ? 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,重新插入新的重建Row
int size = schemeTable.size();
for (int i = (this.nowDay - 1); 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没,自己测试的比较简单 |
CopyRight 2018-2019 实验室设备网 版权所有 |