Math 按词法顺序查找数千个和为给定数字的组

Math 按词法顺序查找数千个和为给定数字的组,math,numbers,partition,Math,Numbers,Partition,大的数字可以用逗号格式化,以便更容易地分成三组。例如1050=1050和10200=10200 这三组中每一组的总和为: 1050=1050给出:1+50=51 10200=10200给出:10+200=210 我需要在三人一组的总和中搜索匹配项。 也就是说,如果我搜索的是1234,那么我要查找的是三个数之和=1234的数字 最小的匹配是235999,因为235+999=1234。任何小于235999的整数都不能给出等于1234的三和 下一个最小的匹配是236998,因为236+998=1234

大的数字可以用逗号格式化,以便更容易地分成三组。例如
1050=1050
10200=10200

这三组中每一组的总和为:

1050=1050
给出:
1+50=51

10200=10200
给出:
10+200=210

我需要在三人一组的总和中搜索匹配项。 也就是说,如果我搜索的是
1234
,那么我要查找的是三个数之和
=1234
的数字

最小的匹配是
235999
,因为
235+999=1234
。任何小于235999的整数都不能给出等于1234的三和

下一个最小的匹配是
236998
,因为
236+998=1234
。 每次都可以添加999,但在达到999后会失败,因为由于999中的溢出,会在数字中添加一个额外的数字1

更一般地说,我要求的解决方案(从最小到最高)是:

a+b+c+d..=x

其中a,b,c,d…是介于0-999和x之间的任意数目的整数 是一个固定整数

注意,对于任何正整数x,都有无穷多个解

如何从最小数量的解开始得到这个问题的解(对于y个解,y可以是任意大的数)


有没有办法不让暴力一个接一个地循环?我处理的是可能非常大的数字,这可能需要数年的时间才能在一个直接的循环中循环。理想情况下,一个人应该在没有失败的尝试的情况下做到这一点。

< P>这个问题更容易思考,如果不是3个数字的组,你只需要一次考虑1个数字。 算法:

  • 首先用x填充0位组

  • 创建一个循环,每次打印下一个解决方案

    • 将所有过大的组从右向左移动,只在右侧保留最大值,从而“规范化”组
    • 输出解决方案
    • 重复:
      • 将1添加到倒数第二组
      • 如果一个组太大(例如999+1太大),则可以将其带到左侧
      • 检查结果是否太大(a[0]应该能够吸收添加的内容)
      • 如果结果太大,请将组设置为零,然后继续递增先前的组
    • 计算最后一组以吸收盈余(可以是正的或负的)
一些用于说明的Python代码:

x=1234
分组=3
最大迭代次数=200
分组中的最大分组=10**分组-1
a=[x]
当最大迭代次数>0时:
#步骤1:当[0]太大时:向左重新分发
i=0
当[i]>max_在_组中时:
如果i==len(a)-1:
a、 追加(0)
a[i+1]+=a[i]-max\u在组中
a[i]=组中的最大值
i+=1
num=总和(10**(分组*i)*a[i]表示枚举(a)中的i,n)
打印(f“{num}{num:,}”)
#打印(“.join([str(t)代表a[:-1]]),”,“.join([str(t)代表a[:-1]]))
#步骤2:在组已满的情况下向倒数第二个组添加一个:设置为0并递增
#左组;
#当盈余太大时(因为[0]太小),重复递增
i0=1
盈余=0
虽然正确:#需要至少执行一次,如果盈余过大,则重复执行
i=i0
为True时:#将a[i]增加1,可以向左移动
如果i==len(a):
a、 附加(1)
盈余+=1
打破
其他:
如果a[i]==_组中的最大_:
a[i]=0
剩余-=组中的最大值
i+=1
其他:
a[i]+=1
盈余+=1
打破
如果[0]>=盈余:
打破
其他:
盈余-=a[i0]
a[i0]=0
i0+=1
#步骤3:a[0]应该吸收步骤1中创建的盈余,尽管a[0]可能会越界
[0]=盈余
盈余=0
最大迭代次数-=1
缩略输出:

235,999 236,998 ... 998,236 999,235 ... 1,234,999 1,235,998 ... 1,998,235 1,999,234 2,233,999 2,234,998 ... 
分组=3和
x=3456的输出:

459,999,999,999 460,998,999,999 460,999,998,999 460,999,999,998 461,997,999,999
461,998,998,999 461,998,999,998 461,999,997,999 461,999,998,998 461,999,999,997
462,996,999,999 ...
分组=1和
x=16的输出:

79 88 97 169 178 187 196 259 268 277 286 295 349 358 367 376 385 394 439 448 457 466
475 484 493 529 538 547 556 565 574 583 592 619 628 637 646 655 664 673 682 691 709
718 727 736 745 754 763 772 781 790 808 817 826 835 844 853 862 871 880 907 916 925
934 943 952 961 970 1069 1078 1087 1096 1159 1168 1177 1186 1195 1249 1258 1267 1276
1285 1294 1339 1348 1357 1366 1375 1384 1393 1429 1438 1447 1456 1465 1474 1483 1492
1519 1528 1537 1546 1555 1564 1573 1582 1591 1609 1618 1627 1636 1645 1654 1663 1672
1681 1690 1708 1717 1726 1735 1744 1753 1762 1771 1780 1807 1816 1825 1834 1843 1852
1861 1870 1906 1915 1924 1933 1942 1951 1960 2059 2068 2077 2086 2095 2149 2158 2167
2176 2185 2194 2239 2248 2257 2266 2275 2284 2293 2329 2338 2347 2356 2365 2374 2383
2392 2419 2428 2437 2446 2455 2464 2473 2482 2491 2509 2518 2527 2536 2545 2554 2563
2572 2581 2590 2608 2617 2626 2635 2644 2653 2662 2671 2680 2707 2716 2725 2734 ...

测试这个。在使用更大数量的解决方案之前,它是否跳过了任何可能的解决方案?thanksI认为该算法在当前解的基础上非常有效地找到下一个解。通常只需检查铲斗0和1。我没有做完整的复杂性分析,但我怀疑这是最快的。请检查更多以确保没有遗漏任何解决方案。是的,如果您遇到遗漏的解决方案,请告诉我。我做了一些测试,一切看起来都正常。它也能有效地处理大量问题。本答案的后续问题评论不适用于扩展讨论;这段对话已经结束。