【问题标题】:Speed up calculating sum of cartesian products加快计算笛卡尔积之和
【发布时间】:2021-02-17 12:20:56
【问题描述】:

由于我的代码运行时间过长,我未能通过自动筛选考试的几个测试用例。有没有办法更有效地写这个?

提示是这样的:

编写一个程序,将一个列表作为输入,并返回成对连接其元素的所有组合的总和。

例如,对于列表 [20, 5],这将是:

2020 + 205 + 520 + 55 = 2800

如果不强制转换为字符串并返回 int,我仍然想不出一种方法。列表推导以前嵌套在 for 循环中,性能较差,但我仍然需要更快的速度。

def concatenationsSum(a):
# turn into strings 
a = [str(i) for i in a]
# concat 
cartesian_product = [j + k for j in a for k in a]
# turn back into integers
total = [int(i) for i in cartesian_product]

return sum(total)

【问题讨论】:

  • 想想 A 和 B 各自贡献于 AB 的总和的 。然后考虑所有 A 的贡献,最后是所有 B 的贡献。
  • 你能换个说法吗?我不明白。
  • 从你的例子:2020+205+520+55 = 20*100+20 + 20*10+5 + 5*100+20 + 5*10+5 = (20+5)* 100 + (20+5)*10 + (20+5)*2。

标签: python-3.x sum cartesian-product


【解决方案1】:

所以我在你的代码中尝试了一些优化,你这里的主要瓶颈是转换为 str 并返回到 int 所以我修改了那部分

def concatenationsSum(a):
   numDigits = {i: (10 ** (int(math.log10(i)) + 1)) for i in a}
   cpro = product(a, a)

   cartesian_product = [i * numDigits[x] + x for i, x in cpro]
   return sum(cartesian_product)

在这里你可以看到我改变了一些部分,我添加了一个字典来查找每个数字需要相乘的位数,例如 5 返回 10,所以当你有 20 和 5 时,你可以这样做 @987654322 @ 加快整个过程。

也不需要在列表理解中使用双 for 循环 python itertools 提供了product(),它返回笛卡尔积。

测试完成:对于大约 8 个元素的小列表,我从 4.6e05 平均到 3.1e05,对于 5400 个元素的较大列表,它从平均 11.7 秒到 5.3 秒。这大约是速度的两倍。

【讨论】:

  • 谢谢,这是@Scott Hunter 在评论中建议的,对吗?从您的示例中: 2020+205+520+55 = 20*100+20 + 20*10+5 + 5*100+20 + 5*10+5 = (20+5)*100 + (20+5)* 10 + (20+5)*2 我用笔和纸做的,但数学很弱。用对数来查找要乘以的位数。不知道有对笛卡尔积的本机支持。谢谢。
  • 实际上它做了第一部分而不是第二部分。
猜你喜欢
  • 2014-02-01
  • 2011-03-24
  • 2017-03-07
  • 2013-04-20
  • 2021-11-19
  • 2015-07-13
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多