有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#1

帖子 科学之子 » 2014-07-23 20:22

具体需求是这样的(一个单词复习程序):
遗忘时间点=ft,期望记忆时长=kt
当前系统时间=ct
ckt=当前和遗忘时间点的距离=abs(ft-ct)
r=距离遗忘的比例=ckt/kt
r越小说明越接近遗忘时间点
每一个单词都会根据系统记录中的数据和当前系统时间计算出一个r.
除了顺序方法,还有什么方法能找出一个最小的r?

(如果我的意思说清楚了,可以不用看)下面是顺序的实现:

代码: 全选

bool recognize_review(void)
{
    const time_t current_time=time(NULL);//当前系统时间
    double current_abs=0;//当前abs函数的返回值
    //遗忘和记忆比例,越小说明越接近遗忘临界点
    //遗忘最佳比例
    double forget_best_ratio=0.;
    //被遗忘的最适合复习的单词位置
    unsigned forget_best_word_site=current_word_array_start;//(如果没有更比例(更接近临界点)的单词,则推荐数组中第一个单词)
    //记忆最佳比例
    double memory_best_ratio=0.;
    //没被遗忘的最适合复习的单词位置
    unsigned memory_best_word_site=current_word_array_start;//(如果没有更比例(更接近临界点)的单词,则推荐数组中第一个单词)
    //当前单词比例
    double current_ratio=0.;
    //最适合复习的单词(如果没有更比例(更接近临界点)的单词,则推荐数组中第一个单词)
    unsigned best_word_site=current_word_array_start;
    bool be_forget=false;//是否存在被遗忘的单词,如果为false表示没有单词是被遗忘的
    if(!file_head.word_total)
    {
        fputs("主数据文件中没有任何单词\n",stderr);
        return false;
    }
    //如果第一次碰到被遗忘的单词,则直接设置其为最佳遗忘单词
    //该变量用来判断是否是第一次碰到被遗忘的单词.
    bool first_forget=true;
    //如果第一次碰到被记住的单词,则直接设置其为最佳记忆单词
    //该变量用来判断是否是第一次碰到被记住的单词.
    bool first_memory=true;
    //i是元素下标计数器
    for(unsigned i=current_word_array_start; i<file_head.word_total; i++)
    {
        //如果期望记忆时长是0,则不再继续查找,立即复习该单词
        if(word_array[i].M_X_EXPECT_MEMORY_DURATION==0)
        {
            //发现被遗忘的单词,无论如何都会推荐一个被遗忘的单词给用户复习.
            //因为期望记忆时长为0,所以认为它是被忘记的单词,把它当作被遗忘的单词处理.
            be_forget=true;
            //当前单词需要立即复习,设置为最佳单词
            forget_best_word_site=i;
            break;
        }
        //获取当前单词的绝对值
        current_abs=fabs((double)(word_array[i].M_X_EXPECT_FORGET_TIME-current_time));
        //如果单词被忘记
        if(current_time>=word_array[i].M_X_EXPECT_FORGET_TIME)
        {
            //发现被遗忘的单词,无论如何都会推荐一个被遗忘的单词给用户复习.
            be_forget=true;
            //如果第一次碰到被遗忘的单词
            if(first_forget)
            {
                //将first_forget置为false,表示已经遇到第一个被遗忘单词.
                first_forget=false;
                //将当前单词设置为最佳被遗忘单词.
                forget_best_word_site=i;
                //将遗忘最佳单词比例设置为当前单词的临界点比例
                forget_best_ratio=current_abs/(double)(word_array[i].M_X_EXPECT_MEMORY_DURATION);
            }
            //否则,即非第一次碰到被遗忘的单词
            else
            {
                //获取当前单词的临界点比例
                current_ratio=current_abs/(double)(word_array[i].M_X_EXPECT_MEMORY_DURATION);
                //如果当前单词的临界点比例更小则设置相应最佳单词和最佳比例
                if(current_ratio<forget_best_ratio)
                {
                    //设置最佳单词临界点比例
                    forget_best_ratio=current_ratio;
                    //设置最佳被遗忘单词
                    forget_best_word_site=i;
                }

            }
        }
        //否则单词没有被忘记(即单词被记住)
        else
        {
            //如果第一次碰到被记住的单词
            if(first_memory)
            {
                //将first_memory置为false,表示已经遇到第一个被记住单词
                first_memory=false;
                //将当前单词设置为最佳单词
                memory_best_word_site=i;
                //将记忆最佳比例设置为当前单词的临界点比例
                memory_best_ratio=current_abs/(double)(word_array[i].M_X_EXPECT_MEMORY_DURATION);
            }
            //否则,即非第一次碰到被记住的单词
            else
            {
                //获取当前单词的临界点比例
                current_ratio=current_abs/(double)(word_array[i].M_X_EXPECT_MEMORY_DURATION);
                //如果当前单词的临界点比例更小则设置相应最佳单词和最佳比例
                if(current_ratio<memory_best_ratio)
                {
                    //设置最佳单词临界点比例
                    memory_best_ratio=current_ratio;
                    //设置最佳被遗忘单词
                    memory_best_word_site=i;
                }
            }
        }
    }
    //如果发现被遗忘的单词则优先复习分数(比例)上最接近遗忘临界点的被遗忘单词
    if(be_forget)
    {
        best_word_site=forget_best_word_site;
    }
    //否则,即全部单词都被记住,优先复习分数(比例)上最接近遗忘临界点的被记住单词
    else
    {
        best_word_site=memory_best_word_site;
    }
    while(M_GIVE_USER_X_REVIEW(best_word_site));
    return true;
}
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#2

帖子 astolia » 2014-07-24 17:10

乱序数据中查找你还想讲什么效率。r=(abs(ft-ct))/kt,所以只要单词的ft/kt发生变化时重新进行一次排序,查找时就能用二分法了
排序对象也不需要是word_array,另外建个索引就够了
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#3

帖子 科学之子 » 2014-07-24 20:27

astolia 写了:乱序数据中查找你还想讲什么效率。r=(abs(ft-ct))/kt,所以只要单词的ft/kt发生变化时重新进行一次排序,查找时就能用二分法了
排序对象也不需要是word_array,另外建个索引就够了
那有什么方法能避免乱序查找?
问题是其中有一个变量是ct=当前时间,每次进行复习r=(abs(ft-ct))/kt,系统时间都不一样,导致每个单词r可能也不同(甚至因为时间的变化(遗忘和记住状态的变化),各个单词的r之间顺序也会发生变化),没看出提前排序的意义.
另一个问题是,每次复习之后,ft和kt也会因为复习来发生变化,决定下次复习时间.
其实我也只是来问问,希望万一有我不知道的方法可以提高效率.
目前采取的主要保持效率的方法就是尽可能减少所需信息大小,并把需要查找的信息装入高速存储介质(比如系统内存),以此在复杂度为n的情况下也能尽可能快速运行.
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#4

帖子 astolia » 2014-07-24 21:01

好吧,我完全不明白你的“期望记忆时长”到底是个什么东西。每个单词的kt、ft,和其上次复习时间又有什么关系?
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#5

帖子 科学之子 » 2014-07-25 22:14

astolia 写了:好吧,我完全不明白你的“期望记忆时长”到底是个什么东西。每个单词的kt、ft,和其上次复习时间又有什么关系?
"期望记忆时长"就是字面意思,期望能记忆多久.
kt=期望记忆时长
ft=遗忘时间点=当前系统时间(ct)+期望记忆时长
ckt=当前距离遗忘时间点的距离=abs(ft-ct(当前时间))
大体目标是选取一个(同比例)最接近遗忘时间点的单词进行复习.
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#6

帖子 astolia » 2014-07-26 11:07

要照你这么个说法
r=ckt/kt=abs(ft-ct)/kt=abs(ct+kt-ct)/kt=abs(kt)/kt,又kt>0,故r=kt/kt=1
所有单词的r都恒等于1了
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#7

帖子 科学之子 » 2014-07-26 18:53

astolia 写了:要照你这么个说法
r=ckt/kt=abs(ft-ct)/kt=abs(ct+kt-ct)/kt=abs(kt)/kt,又kt>0,故r=kt/kt=1
所有单词的r都恒等于1了
r是实数或浮点数,介于0和1之间,极限情况下可能会等于0或1
我或许应该考虑变相用整型去实现,这样至少数据类型的结构会简单一些,可能会因此找到提高效率的方法.
之所以一开始选用浮点数,是因为更符合人类的数学习惯,可读性更好.
Sat Jul 26 19:13:43 CST 2014补充:
用整型去代替浮点数会绕不少.
我先想想是否能用整型来提高效率吧.
Sat Jul 26 19:16:01 CST 2014补充:
貌似不仅是绕的麻烦,有些情况用整数根本无法实现.
比如表示遗忘进度大于100%如该单词已经被遗忘150%
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#8

帖子 astolia » 2014-07-26 22:20

这跟实数整数有什么关系,你用的那个公式本身就有问题,只要kt不为0,任何情况下r都为1。
ft根本不应该和ct扯上关系,我的理解是遗忘时间点=上次记忆时间+期望记忆长度。
而你去算绝对值也是没什么意义的,反正都完全忘了,是昨天忘的还是前天忘的有必要去区别吗?

我在4楼问的主要是想知道期望记忆时长这个东西到底是怎么取值的,在什么情况下同一个单词的期望记忆时长会变化。结果你解释了一堆没用的,还暴露出你对公式的理解都有问题

一般的复习程序,都是根据记忆曲线,确定每一个单词的所有复习时间点,排序后查找,整个算法是相当简单的
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#9

帖子 科学之子 » 2014-07-27 4:38

astolia 写了:这跟实数整数有什么关系,你用的那个公式本身就有问题,只要kt不为0,任何情况下r都为1。
ft根本不应该和ct扯上关系,我的理解是遗忘时间点=上次记忆时间+期望记忆长度。
而你去算绝对值也是没什么意义的,反正都完全忘了,是昨天忘的还是前天忘的有必要去区别吗?

我在4楼问的主要是想知道期望记忆时长这个东西到底是怎么取值的,在什么情况下同一个单词的期望记忆时长会变化。结果你解释了一堆没用的,还暴露出你对公式的理解都有问题

一般的复习程序,都是根据记忆曲线,确定每一个单词的所有复习时间点,排序后查找,整个算法是相当简单的
当前距离遗忘临界点
kt=期望记忆时长=60
ckt=当前距离遗忘的距离=30

r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
r从哪来的恒等于1?

昨天忘记的,可能还记得,前天忘记的,很可能就彻底忘记了,所以程序总是选取一个遗忘程度最轻的被遗忘单词进行复习.

这个期望记忆时长(kt)以前是由用户直接估计并输入,现在是登记(添加或修改)单词时直接输入,复习时是通过判断本次距离上次复习记忆保持了多久,如果用户选择记住,则会累加.
详情看18次修改:viewtopic.php?f=137&t=460280
体现在give_user_review.c(实现复习时的累加)和word_review.c(实现单词推荐)文件
两个文件都很小,也很简单.
DualThrust
帖子: 7
注册时间: 2014-02-21 14:33
系统: Ubuntu Kylin 14.04

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#10

帖子 DualThrust » 2014-07-27 21:02

亲 你选择的变量选择上面有些问题
我们增加一个变量oct
期望记忆时长 = kt
当前系统时间 = ct
遗忘时间点 = ft
假设用户键入期望记忆时长是时间为oct 那么ft = oct + kt
ckt=当前和遗忘时间点的距离 = ft-ct = oct + kt - ct
r=距离遗忘的比例=ckt/kt = (kt + oct - ct ) / kt = 1 - (oct - ct) / kt
因为 r = 1 - (oct - ct) / kt 这个式子中只存在一个不断刷新的变量ct 所以只需要不断更新(oct - ct) / kt这个值就可以了
假设我们将更新的值存入一个数组 tmp 每次更新后因为oct和kt的数值都不太相同 所以该数组是一个乱序的数组
从本质上来讲PO你这个问题的实质就是怎样处理一个乱序的数组并将时间复杂度压到n
就我现在掌握的算法只能用哈希了 要不然用链表实现的话太过于复杂 而且没必要
每次更新tmp后 按照精度(一般也就保留小数点后2位 再多的话相对于C来讲不太准确 除非你上双精度 但是没必要)设定出一个哈希表 并将数据填入该表 等需要读取的时候从头往后一个萝卜一个坑读取
因为该哈希表每个下标都有可能会存入复数个数字 最简单的处理办法是建立一个二维数组 当然这样占空间比较大 最佳的解决方法是用链表处理

我只是简单的说下我的想法 中间还涉及到哈希表下标取值范围等一大堆东西 PO自己想办法解决吧~
头像
qgymib
帖子: 539
注册时间: 2010-04-02 16:44
系统: openSUSE 13.2 x64

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#11

帖子 qgymib » 2014-07-27 23:37

1. 链表存取绝对是最简单的方法

2. 查找时对数据进行重新排序效率绝对不会高,以红黑树举例来说,其增删改的效率为o(log n),遍历的效率至少为o(n),因此查找总体运行效率至少为o(n) + o(log n),比直接遍历的效率差

3. 哈希表的方法应该不适用。不清楚lz的存储算法里存的是具体的数字还是公式,若储存的是数字且数字会变化,那么哈希表可能不太适用。哈希表的key和value是对应的,按照ls的说法,value应该与“最接近遗忘点时间”有关,所以key也与其有关。既然key会动态变化,那么你需要动态维护这个key以及其下属的value列表(这个时候的存储结构已经不是严格的hash表了,因为出现了一个key对应多个value的情况)。所以其存储、查找效率与你hash映射效率有关(假设用的是数组储存方式,其他储存方式在你的效率前提下都没有意义)。

4. 若lz写这个程序的目的不是用于算法研究,那么这个问题就没有意义,因为对于r的计算时间将超过查找时间(仅目测,因为我没搞懂kt什么的是单纯的一个变量还是两个字母相乘)。在应用情况下,对lz这种情况大体有两种解决方法:一、顺序存储结构,即使lz程序每一个存储单元所占用的内存达到了1kb,在10w单词量情况下(我真的不认为有人能存这么多。。。),所占用的内存空间为97MB,应该在可接收范围之内;二、利用数据库,sqlite等小型数据库的性能要求就完全能达到lz的预期了,数据库查询时间与内存中数据查询时间在人眼看来没有区别(虽然实际上有数量级的差异)。
正在建设中的个人博客
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#12

帖子 astolia » 2014-07-28 15:11

科学之子 写了: 当前距离遗忘临界点
kt=期望记忆时长=60
ckt=当前距离遗忘的距离=30

r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
r从哪来的恒等于1?
看吧,我就说你没把公式搞清楚。
问题在于当kt=60时, ckt根本不可能为30
你自己说的 ft=遗忘时间点=当前系统时间(ct)+期望记忆时长,后面也没见你修改说法,就照这个算
那么当kt为60时,ft=ct+kt=ct+60
则ckt=abs(ft-ct)=abs(ct+60-ct)=abs(60)=60,r=60/60=1
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#13

帖子 科学之子 » 2014-07-28 18:37

astolia 写了:
科学之子 写了: 当前距离遗忘临界点
kt=期望记忆时长=60
ckt=当前距离遗忘的距离=30

r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
r从哪来的恒等于1?
看吧,我就说你没把公式搞清楚。
问题在于当kt=60时, ckt根本不可能为30
你自己说的 ft=遗忘时间点=当前系统时间(ct)+期望记忆时长,后面也没见你修改说法,就照这个算
那么当kt为60时,ft=ct+kt=ct+60
则ckt=abs(ft-ct)=abs(ct+60-ct)=abs(60)=60,r=60/60=1
注意ct=当前系统时间,它是一个可变量,而非固定不变,它不是存储在记录中,而是运行时从当前环境获取.
如果当前系统时间ct不变,您的理解是没错,r始终恒等于1.
看来您还没有理解,我再重新描述一下我的问题
当前系统时间ct是一个不断变化的量(ct本身是不断增加,而非乱序变化(系统时间被修改情况除非)),所以感觉有规律,想问一下有没有方法能提高效率.
难点除了ct本身是不断增加的变量,还有一个就是比例的表示方式,系统时间增加相同的数量,但不同单词的遗忘比例却不同,导致次序发生变化,还有会导致遗忘状态的变化,由记住变为遗忘.
如果提前排序,新出现的被遗忘单词还是需要通过遍历的方式才能发现.
我能想到的方法,复杂度并没有本质或较大的提升,但程序的可读性却会降低很多(维护难度大大提升).
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#14

帖子 科学之子 » 2014-07-28 18:57

DualThrust 写了:亲 你选择的变量选择上面有些问题
我们增加一个变量oct
期望记忆时长 = kt
当前系统时间 = ct
遗忘时间点 = ft
假设用户键入期望记忆时长是时间为oct 那么ft = oct + kt
ckt=当前和遗忘时间点的距离 = ft-ct = oct + kt - ct
r=距离遗忘的比例=ckt/kt = (kt + oct - ct ) / kt = 1 - (oct - ct) / kt
因为 r = 1 - (oct - ct) / kt 这个式子中只存在一个不断刷新的变量ct 所以只需要不断更新(oct - ct) / kt这个值就可以了
假设我们将更新的值存入一个数组 tmp 每次更新后因为oct和kt的数值都不太相同 所以该数组是一个乱序的数组
从本质上来讲PO你这个问题的实质就是怎样处理一个乱序的数组并将时间复杂度压到n
就我现在掌握的算法只能用哈希了 要不然用链表实现的话太过于复杂 而且没必要
每次更新tmp后 按照精度(一般也就保留小数点后2位 再多的话相对于C来讲不太准确 除非你上双精度 但是没必要)设定出一个哈希表 并将数据填入该表 等需要读取的时候从头往后一个萝卜一个坑读取
因为该哈希表每个下标都有可能会存入复数个数字 最简单的处理办法是建立一个二维数组 当然这样占空间比较大 最佳的解决方法是用链表处理

我只是简单的说下我的想法 中间还涉及到哈希表下标取值范围等一大堆东西 PO自己想办法解决吧~
复杂度n顺序本身就能做到.
我希望的是让复杂度低于n
我不明白hash在我这个程序中有任何意义,目标是寻找一个最小的r,r是一个比例值,系统时间变化同样的量,不同单词的r的变化幅度可能不同.
另外,PO是什么意思?
科学之子
帖子: 2284
注册时间: 2013-05-26 6:58
系统: Debian 9

Re: 有什么办法能快速(复杂度小于n)找到一个最小比例值?(遇到的需求感觉用树办不到)

#15

帖子 科学之子 » 2014-07-28 20:03

qgymib 写了:1. 链表存取绝对是最简单的方法

2. 查找时对数据进行重新排序效率绝对不会高,以红黑树举例来说,其增删改的效率为o(log n),遍历的效率至少为o(n),因此查找总体运行效率至少为o(n) + o(log n),比直接遍历的效率差

3. 哈希表的方法应该不适用。不清楚lz的存储算法里存的是具体的数字还是公式,若储存的是数字且数字会变化,那么哈希表可能不太适用。哈希表的key和value是对应的,按照ls的说法,value应该与“最接近遗忘点时间”有关,所以key也与其有关。既然key会动态变化,那么你需要动态维护这个key以及其下属的value列表(这个时候的存储结构已经不是严格的hash表了,因为出现了一个key对应多个value的情况)。所以其存储、查找效率与你hash映射效率有关(假设用的是数组储存方式,其他储存方式在你的效率前提下都没有意义)。

4. 若lz写这个程序的目的不是用于算法研究,那么这个问题就没有意义,因为对于r的计算时间将超过查找时间(仅目测,因为我没搞懂kt什么的是单纯的一个变量还是两个字母相乘)。在应用情况下,对lz这种情况大体有两种解决方法:一、顺序存储结构,即使lz程序每一个存储单元所占用的内存达到了1kb,在10w单词量情况下(我真的不认为有人能存这么多。。。),所占用的内存空间为97MB,应该在可接收范围之内;二、利用数据库,sqlite等小型数据库的性能要求就完全能达到lz的预期了,数据库查询时间与内存中数据查询时间在人眼看来没有区别(虽然实际上有数量级的差异)。
记忆英文单词的话,足够实用,但有两点,一来是确实想看看有没有高效的方法,二来,我这个程序,未来也许会变成广义的帮助记忆的工具,比如记忆电话号码,记忆所有需要被长期记忆的东西,也许会超过普通的词汇量的数量.
kt是一个变量,是期望的记忆保持时间
ct是当前时间,ft是期望的遗忘时间点,ctk是当前保持了多长时间(当前系统时间距离上次复习时间的时差)
r是一个比例,表示距离ft(遗忘时间点)还有多久
r(0.5)=ctk(30)/kt(60)//还有30秒忘记
r(0.05)=ctk(3)/kt(60)//还有3秒忘记
r(0.0)=ctk(0)/kt(60)//还有0秒忘记(达到遗忘临界点,是数值上最理想的被复习状态)
如果存在被遗忘的单词,则在被遗忘的单词中寻找一个最接近0的r.
如果全部单词都是被记住的,没有被遗忘,则在被记住的单词中寻找一个最接近0的r.

如果真的只能用顺序实现,表示怀疑数据库软件能从数量级上提升效率?数量级上的效率提升,感觉这不是一些技巧性优化能办到的.
而且网上搜索数据库软件的相关资料,感觉貌似不是很适合我的需求,我的查找有点太"个性"了.
回复