V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
hunk
V2EX  ›  问与答

程序生成 5 以内的所有加减法算式,随机出题,确保不重复,算法如何实现?

  •  
  •   hunk · 2017-10-25 21:34:33 +08:00 · 2729 次点击
    这是一个创建于 2593 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1+2 0+3 这样的算式没想到合适的数据类型保存,随机生成又无法保证不重复。

    18 条回复    2017-10-26 10:56:32 +08:00
    em70
        1
    em70  
       2017-10-25 21:38:10 +08:00
    随机生成一批放数据库里,去重,打乱,需要用的时候按顺序输出即可
    zapper
        2
    zapper  
       2017-10-25 21:43:20 +08:00
    5 以内的加减法算式 不是可以穷举出来吗,还是我想得太简单
    hunk
        3
    hunk  
    OP
       2017-10-25 21:43:52 +08:00
    @em70 存数据库,把 1+2 存成字符类型,出来再一个个拆开分析,转换为代码?
    这点没想好如何解决
    hunk
        4
    hunk  
    OP
       2017-10-25 21:45:54 +08:00
    @zapper 还想随机,所以考虑如何保存
    nbndco
        5
    nbndco  
       2017-10-25 21:51:16 +08:00 via iPhone
    不需要存啊,不过是生成一个 0-5 的随机排列而已
    hunk
        6
    hunk  
    OP
       2017-10-25 21:52:08 +08:00
    @nbndco 麻烦的是,要保证是全部,又不能重复。
    随机生成 10 道 20 道的,很好处理。
    binux
        7
    binux  
       2017-10-25 22:00:02 +08:00
    你把结果也一起存了不就完了,总共才 6*6*2 种。
    hunk
        8
    hunk  
    OP
       2017-10-25 22:02:21 +08:00
    @binux 结果分开存,会有重复,不知道对应的是哪道算式。
    如果存 2-1=1,那随机出题,还答个啥呢?
    binux
        9
    binux  
       2017-10-25 22:03:47 +08:00
    @hunk #8 你输出的时候按照 = split 一下不就知道问题和答案了吗?
    WuwuGin
        10
    WuwuGin  
       2017-10-25 22:06:08 +08:00 via Android
    5 以内的不一共就 36 种组合吗,三个数组搞定,除非你要第二次打开软件还要记录上次的出现情况。
    yangqi
        11
    yangqi  
       2017-10-25 22:08:25 +08:00
    一共就那么几种,全部列出来,然后随机抽取。之后把抽到的剔除再剩下的里面随机抽取,以此类推
    pual
        12
    pual  
       2017-10-25 22:23:27 +08:00 via Android
    递归计算,依次迭代缩小条件
    hunk
        13
    hunk  
    OP
       2017-10-25 22:23:34 +08:00
    @binux 谢谢,这个办法不错,只是感觉不太完美,只能把算式当作字符串来存储。
    azh7138m
        14
    azh7138m  
       2017-10-25 22:30:29 +08:00 via Android
    全生成放数组
    shuffle
    取前 N 个用
    ryd994
        15
    ryd994  
       2017-10-26 06:49:59 +08:00 via Android
    @hunk #13 那你存这样
    num1, op, num2, result
    要输出的时候拼接一下就好了啊
    xwyam
        16
    xwyam  
       2017-10-26 09:23:56 +08:00
    这个可以给每个算式指定特征数字啊,映射还是很简单的。个人觉得还是不要动用数据库了。

    对于所有 n 以内的数 a,b,所有(a,b)数对能一一对应到 a*n+b 这个特征数,总共有 n^2 种。这样每种标点符号就有 n^2 个特征数了。再把每种标点符号的特征数定义为 k*(n^2),这样从给定的特征数 code 就很容易转换出一个算式了——
    (sign) = code % (n^2)
    a = [code % (n^2)] // n
    b = [code % (n^2)] % n
    这样的特征数,能覆盖 0~k*(n^2)中的所有数字了,其中 k 是标点符号的个数。

    特征数搞定,下边说随机产生的问题。生成一个序列 0~k*(n^2),再指定一个变量 L 表示该序列中所剩数字的多少。循环执行下边的过程——
    1. 从 L 个数的序列中随机选出第 i 个数字,这个数字就是本轮要使用的特征数 code
    2. 将 code 用上边的映射关系转换出一个算式出来输出
    3. 如果 i 不是第 L 个数的话,就把第 L 个数放在 i 的位置上,然后把 L 减小 1 (这样做的好处是保证序列前 L 个数都是未输出的数字,下轮循环第 1 步容易取随机数)
    4. 如果取够了,就退出;如果序列取空了还没有取够,就再重新生成一个新的 0~k*(n^2)的序列,再次循环

    V2EX 贴代码似乎会乱掉,我就不贴了。如果 LZ 有其他问题,可以私信我。
    qwjhb
        17
    qwjhb  
       2017-10-26 09:53:11 +08:00
    才 5 以内 直接穷举扔字典 值是答案 然后输出好了 反正字典也无序
    msg7086
        18
    msg7086  
       2017-10-26 10:56:32 +08:00
    5 以内的加减法,其实就是 6 进制+2 进制+6 进制的映射。
    把问题简单化的话就是一个 3 位 6 进制数,最高位为运算符标志,后两位分别为运算数。
    数字范围是( 6 进制的) 000~155。

    其实就是上面说的 n 进制。

    出题的话就是从 0-71 中随机抽取一个数字,转成 5 进制,拆出每一位,搞定。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1115 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:49 · PVG 07:49 · LAX 15:49 · JFK 18:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.