高效算法:确定在列表中不频繁出现的值

2024-06-06 19:48:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个测试应用程序,从一堆问题中随机抽取问题。但是,有一个要求是,问题库仅限于用户尚未看到的问题。但是,如果用户已经看到了所有的问题,那么算法应该“重置”,并且只显示用户见过一次的问题。也就是说,始终向用户显示他们从未见过的问题,或者,如果用户已经看到了所有问题,则在显示他们更频繁看到的问题之前,始终向他们显示他们很少看到的问题。在

列表(L)的创建方式如下所示:列表(I)中的任何值都可以存在一次或在列表中重复多次。让我们在列表中定义另一个值J,使其与I的值不同,那么0 <= abs(frequency(I) - frequency(J)) <= 1将始终为true。在

换句话说,如果一个值在列表中重复了5次,而5次是列表中任何值重复的最大次数,则列表中的所有值都将重复4次或5次。该算法应该返回列表中所有带有frequency == 4的值,然后返回任何带有frequency == 5的值。在

很抱歉,我很难说清楚这个问题。请随时留下意见与问题,我将进一步资格,如果需要。在

提前感谢您能提供的任何帮助。在

澄清

感谢您迄今提出的答案。我想他们中还没有人在那里。让我进一步解释。在

我不会和用户互动,也不会问他们问题。我将问题ID分配给一个考试记录,这样当用户开始考试时,他们可以访问的问题列表就确定了。因此,我需要处理两个数据结构:

  • 用户有权访问的可能问题ID的列表
  • 此用户以前分配的所有问题ID的列表。这是我上面描述的名单。

因此,除非我弄错了,否则这个问题的算法/解决方案将需要使用上述两个列表进行基于列表和/或基于集合的操作。在

结果将是一个问题id的列表,我可以将其与考试记录相关联,然后插入数据库。在


Tags: 用户算法idtrue应用程序列表定义方式
3条回答

要实现你的算法,你只需要洗牌并通过它,完成后,重复。在

不需要复制列表或在两个列表之间切换项目,只需使用以下控制流,例如:

import random

def ask_questions(list_of_questions):
    while True:
        random.shuffle(list_of_questions)
        for question in list_of_questions:
            print(question)
            # Python 3 use input not raw_input
            cont = raw_input('Another question?') 
            if not cont:
                break
        if not cont:
            break

用数据库重写填充伪代码。在

如果我正确地理解了这个问题,我会把这些问题(或他们的id作为代理)当作一副物理卡片:对于每个用户,洗牌,一次处理一个问题;如果他们想要多于len(deck)个问题,就重新开始:将牌组重新排列成一个新的顺序,然后再做一次。当一个问题被第n次看到时,所有其他问题都将被看到nn-1次。在

为了跟踪用户有哪些可用的问题,我们将未使用的问题id放回数据库中,并在需要新交易时增加“通过多少次”计数器。在

比如:

from random import shuffle

def deal():
    question_IDs = get_all_questions(dbconn) # all questions
    shuffle(question_IDs)
    increment_deal_count(dbconn, userID) # how often this student has gotten questions
    return question_IDs


count_deals = get_stored_deals(dbconn, userID) # specific to this user
if count_deals: 
    question_IDs = get_stored_questions(dbconn, userID) # questions stored for this user 
else: # If 0 or missing, this is the first time for this student
    question_IDs = deal()


while need_another_question(): #based on exam requirements
    try:
        id = question_IDs.pop()
    except IndexError:
        question_IDs = deal()
        id = question_IDs.pop() # Trouble if db is ever empty. 

    use_question(id) # query db with the ID, then put question in print, CMS, whatever

# When we leave that while loop, we have used at least some of the questions
# question_IDs lists the *unused* ones for this deal
# and we know how many times we've dealt.

store_in_db(dbconn, userinfo, question_IDs)
# If you want to know how many times a question has been available, it's
# count_deals - (ID in question_IDs)
# because True evaluates to 1 if you try to subtract it from an integer. 

为什么没有两个列表,一个用于尚未选择的问题,另一个用于已选择的问题。最初,尚未拾取的列表将是完整的,您将从中拾取元素,这些元素将被移除并添加到拾取列表中。一旦“尚未拾取”列表为空,请重复与上述相同的过程,这次将“完全拾取”列表用作“尚未拾取”列表,反之亦然。在

相关问题 更多 >