基于一道加拿大高中组合数学题解法的python代码验证---CALENDAR

本文通过Python代码验证一道加拿大高中组合数学题的解法,采用暴力枚举+搜索方法,分为生成所有可能单词和检查单词两部分。代码在遍历和检查过程中遇到的挑战包括重复元素处理、集合操作以及避免在遍历过程中修改数据结构导致的错误。最终,代码成功实现了检验正确答案的功能,展现了递归策略在生成排列问题上的应用。
摘要由CSDN通过智能技术生成
Calculate the number of 'words'  that can be formed from all the letters in
the word CALENDAR if C and A must be together, but N and D are not together.
用单词CALENDAR的字母重新组合成不同的单词,使得每个单词中的字母C与至少一个A在一起,
并且D和N不在一起,求满足条件的单词总个数。

本题来自加拿大的数学教材。由于收录此题的教材也给出了错误的参考答案,所以写一段代码来运行一下来检验计算结果的正确性,给正确的答案伸冤,是有价值的。

本文是通过Python的暴力枚举+搜索来得到答案,仅作为对答案的检验,对此题的数学解答并没有帮助,且本文不会对正确的解法作任何形式的提示 😃😃😃 然而,作者认为代码本身的算法很有意思,所以在此分享代码,兼自己心路历程的一个记录。

将代码分为两个部分,第一个部分是构造一个递归函数,将所有的组合,不管重复且是否符合要求都加入到一个存储单词的列表中;第二个部分是遍历整个列表,检查每一个元素是否符合要求,不符合便将其剔除。代码本身不难,however,中间有几个坑仍是值得注意。


生成所有单词

首先是生成所有可能单词的递归函数 assembling

该函数接受两个参数:current_stringcurrent_list. current_string是当前该循环下这一个单词的状态,已经有了哪几个字母;current_list存储了还有几个字母没有添加。有了这两个变量,当单词已经有n个字母长时,函数在for循环下将按剩下单词的顺序给current_string添加第n+1个字母,同时在列表中删除那个字母,并将添加后的current_string和删除后的current_list通过递归调用传给原函数,再添加第n+2个字母。

注意

  1. 同一个函数内,循环的每一步添加的都是第n+1个字母,而不是单纯的for循环下连续给同一个字符串添加第n+1,n+2,n+3…个字母,只有循环添加第n+1个字母才能达到穷举。而这正要靠for循环中声明一个替身变量copy_string,来替current_string接下增加的字母,每进入循环的下一步,copy_string的值就被刷新一次,这样才能保证同一个循环每一步都是在字符串的同一个位置加上不同的字母,以便传给下一个函数。
  2. 在本段代码的最后一行将列表转换为了集合,这样操作一来是为了剔去重复元素,而来是为了在后续要去掉不符合要求的元素时就可以直接用集合的取补集方法,而至于要取补集而不是直接在循环里删除那个元素的原因在下段代码解释。
characters, words= 'C A L E N D A R'.split(' '),[]

def assembling(current_string = '', current_list=None):
    if current_list is None: current_list = characters
    if len(current_string) == 8: words.append(current_string)
    else:
        for i in range(len
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值