查找成千上万的词组,按词汇顺序求和成给定的数字

问题描述 投票:0回答:2

大量的数字可以用逗号格式化以更容易地分成三组阅读。例如。 1050 = 1,05010200 = 10,200

每三人一组的总和为:

[1050=1,050给出:1+50=51

[10200=10,200给出:10+200=210

我需要搜索三分之和的匹配项。即,如果我正在搜索1234,那么我正在寻找3s = 1234之和的数字。

235,999起,最小的匹配为235+999=1234。没有其他小于235,999的整数给出3s的总和等于1234。

236,998以来的下一个最小匹配是236+998=1234。每次可以加999,但是在达到999后失败,因为数字加了1。

更一般而言,我要求的解决方案(从最小到最大)为:

a + b + c + d…= x

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

注意,对于任何正整数x,对此都有无限的解决方案。

一个人如何从最小的数字(任意长度,甚至数百万以上)开始获得解决方案?

有没有一种方法可以做到,而无需蛮力一一循环?我正在处理可能非常大的数字,这可能需要数年时间才能直通。理想情况下,应该做到这一点而不会失败。

math numbers partition
2个回答
1
投票

答案相当简单。假设数字N可被n=Floor(N/999)整除,并且余数N%999。那么最小的数字是

rrr 999 999 ... 999 999
     n  n-1      2   1

带有rrr=N%999

第二个最小数字是:

rrr+1 998 999 ... 999 999
       n  n-1      2   1

[(m+1)th中带有2m<(999-rrr)的最小数字是:

rrr+m 999-m 999 ... 999 999

(m+2)th最小数字现在有所不同。遵循相同的规则,您必须交换rrr+m+1999-m-1以使其最小。但是此数字将与mth最小数字相同。因此,您需要开始减少第二个999,并且必须将其分配到前两个三胞胎上。假设pppqqq(m+1)th最小数字的解决方案:

ppp qqq 999 ... 999 999

顺序进行:

ppp qqq+1 999-1 ... 999 999
ppp qqq+2 999-2 ... 999 999
ppp qqq+3 999-3 ... 999 999
...
ppp sss ttt ... 999 999      with sss = ttt or sss+1 = ttt

现在您需要再次减少sssttt并增加ppp才能到达

aaa bbb ccc 999 ... 999    with aaa=bbb or aaa+1=bbb
                                bbb=ccc or bbb+1=ccc

从现在开始,您可以减少第4个999。

我可能在这里错了,但这是我的第一次尝试。


0
投票

如果不考虑由3位数字组成的组,而一次只考虑1位数字,则更容易考虑这个问题。

一种算法:

  • 首先用0填充0位数字组。

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

    • “通过将所有太大的东西从右移到左,仅在最大值处保留最大值。”对这些组进行标准化。
    • 输出解决方案
    • 重复:
      • 倒数第二组加1
      • [如果群组太大(例如999 + 1太大),则可以向左携带]
      • 检查结果是否没有太大(a [0]应该能够吸收所添加的内容)
      • 如果结果太大,则将该组设置为零,然后继续递增较早的组
    • 计算最后一组以吸收盈余(可以是正数或负数)

一些用于说明的Python代码:

x = 1234
grouping = 3
max_iterations = 200
max_in_group = 10**grouping - 1

a = [x]

while max_iterations > 0:
    #step 1: while a[0] is too large: redistribute to the left
    i = 0
    while a[i] > max_in_group:
        if i == len(a) - 1:
            a.append(0)
        a[i + 1] += a[i] - max_in_group
        a[i] = max_in_group
        i += 1

    print("".join([str(t) for t in a[::-1]]), ",".join([str(t) for t in a[::-1]]))

    # step 2:  add one to the penultimate group, while group already full: set to 0 and increment the
    #   group left of it;
    #   while the surplus is too large (because a[0] is too small) repeat the incrementing
    i0 = 1
    surplus = 0
    while True:  # needs to be executed at least once, and repeated if the surplus became too large
        i = i0
        while True:  # increment a[i] by 1, which can carry to the left
            if i == len(a):
                a.append(1)
                surplus += 1
                break
            else:
                if a[i] == max_in_group:
                    a[i] = 0
                    surplus -= max_in_group
                    i += 1
                else:
                    a[i] += 1
                    surplus += 1
                    break
        if a[0] >= surplus:
            break
        else:
            surplus -= a[i0]
            a[i0] = 0
            i0 += 1

    #step 3: a[0] should absorb the surplus created in step 1, although a[0] can get out of bounds
    a[0] -= surplus
    surplus = 0
    max_iterations -= 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 ... 

grouping=3x=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 ...

grouping=1x=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 ...
© www.soinside.com 2019 - 2024. All rights reserved.