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

2017-10-25 21:34:33 +08:00
 hunk

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

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

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

出题的话就是从 0-71 中随机抽取一个数字,转成 5 进制,拆出每一位,搞定。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/400744

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX