【问题标题】:Russian Peasant Multiplication Python 3.3俄罗斯农民乘法 Python 3.3
【发布时间】:2013-01-16 06:43:26
【问题描述】:

我需要有关 python 3.3 中的一个程序的帮助,该程序应该进行俄罗斯农民乘法/古埃及乘法。作业说,“如果“A”和“B”是要相乘的两个整数,我们反复将“A”乘以 2,然后将“B”除以 2,直到“B”不能再除且不为零(整数除法)。在每组乘“A”除“B”的过程中,如果“B”的值为奇数,则将“A”的值加到总数中。最后,总和所有“A”值(当“B”为奇数时)应等于原始“A”和“B”输入的乘积。简而言之,将“B”为奇数的所有“A”值相加它将等于(或接近)“A”和“B”的乘积。

编辑

我可能对某些问题的措辞有误。

这是一个例子:

如果“A”是 34,“B”是 19,则将“A”乘以 2,然后将“B”除以 2。

“A”“B”

(34) (19) (“B”为奇数,加“A”)

(68) (9) (“B”为奇数,加“A”)

(136) (4)(“B”为偶数,忽略“A”值)

(272) (2)(“B”为偶数,忽略“A”值)

(544) (1)(“B”是奇数,加“A”到总数)

将“A”的所有“B”为奇数的值相加,得到 (34 + 68 + 544 = 646), 这等于将“A”和“B”相乘,(34 * 19 = 646)。

我遇到问题的部分是每当“B”是奇数时将“A”添加到总数中。

这是我目前所拥有的,

x = int(input("What is the first number? "))
y = int(input("What is the second number? "))
answer = 0

while y != 0:
    if (y%2 != 0):
        x*2
        y//2
        answer == answer + x
    if (y%2 == 0):
        x*2
        y//2
print("the product is",(answer))

我对 python 和编程非常陌生,因此非常感谢任何有关其错误原因的帮助和/或解释。

【问题讨论】:

  • 您的代码不会重新分配 yx。您需要将x*2y//2 分别替换为x = x*2y = y//2
  • 没关系。我想我只是误解了你的解释。
  • 您也没有分配给answer。如果answer 等于answer + x,您正在测试。使用单个 = 分配,或者更好的是,使用就地添加:answer += x
  • 将 2 设为变量,以便测试它是否适用于其他值。可以加分
  • 当我问用户是否想用新的输入再次运行代码时,我怎样才能让它重复程序?

标签: python if-statement python-3.x while-loop


【解决方案1】:

最后一次加 x 是 y 等于 1 的时候。如果你一直减半直到数字 达到 0,将需要非常大量的迭代(从逻辑上讲,它需要 永远)。

想想 2x2。如果你将 x 加倍为 4,将 y 减半为 1,x 就是你的答案。

换句话说,将y 视为how many of x I need to yield answer。由于您不能相乘,只能加/加/减半,因此您可以选择 - 您可以等到 y 为 2,然后添加 x 的两倍值,或者您可以等到 y 为 1 并简单地添加 x 的值。后者更简单明了,仅此而已。

我认为在这种情况下使用while True 循环会更清楚:

def mult2(x, y):
    answer = 0
    while True:
        if y % 2:
            answer += x
        if y < 1:
            break
        x *= 2
        y //= 2
    print("the product is", answer)

递归调用函数:

def mult2(x, y):
    """aka 'Russian peasant method'; allowed: addition, halving, doubling."""
    if y==1:
        return x
    else:
        add = x if y%2 else 0
        return mult2(x*2, y//2) + add

【讨论】:

    【解决方案2】:

    附注。坦率地说,直到现在我才知道算法。它被古埃及人或旧俄罗斯使用的越让我感到惊讶。 (实际上,我倾向于认为俄罗斯起源的可能性更大,因为斯拉夫民族似乎与古老的伊特鲁里亚人直接相关)。

    旧的起源让我感到惊讶,因为它实际上是你在基础学校学到的简单的手工乘法。唯一的区别是数字首先转换为 binary 表示。而是面向机器的,不是吗? :)

    对于问题中的数字,十进制的 34 等于二进制的 100010,十进制的 19 是二进制的 10011。现在是纸上简单的基础学校乘法:

        100010
    x    10011
    ------------
        100010   i.e. 100010 times 1
       100010        1000100 times 1
      000000        10001000 times 0
     000000        100010000 times 0
    100010        1000100000 times 1
    ------------                   ^ binary digits of the multiplier
    1010000110                       (reminder of division by 2)
                           ^ adding the zero means multiplying by 2
    i.e. sum only when 1 is the reminder of division
    

    似乎设计方法的人(在古代)知道二进制数是什么。

    【讨论】:

      【解决方案3】:

      我不熟悉您尝试实现的算法,但我对您的代码做了一些修改。

      x = int(input("What is the first number? "))
      y = int(input("What is the second number? "))
      answer = 0
      
      # != 0 is redundant: y is True if it is not 0
      while y:
          # no need to have parentheses here
          if y % 2:
              # this needs to be an assignment, not a check for equality
              answer += x  # shorthand for answer = answer + x
          # These happen every time, so does not need to be inside the if
          # these also need to be an assignment, not just an expression
          x *= 2
          y /= 2
      # total was never defined
      print("the product is", (answer))
      

      【讨论】:

        【解决方案4】:

        你需要先加x回答,然后更新x

        这是正确的代码

        x = int(input("What is the first number? "))
        y = int(input("What is the second number? "))
        answer = 0
        
        while y != 0:
           if (y%2 != 0):
              answer=answer+x
              x=x*2
              y=y//2
           if (y%2 == 0):
              x=x*2
              y=y//2
        
        print("the product is",(answer))
        

        【讨论】:

        • 下一个x 和下一个y 的计算在两个if 命令中是相同的。这样,它可以移动到if 之外(在每个循环中计算值并且始终以相同的方式)。然后第二个if 变为空,可以删除。那么y % 2 != 0y % 2 == 1 相同(但更模糊的版本)。后者只是显式转换为 bool,而 y % 2 是在布尔上下文中将被解释为 True 的值。
        • 我在写那个答案时就知道了。我试图对提问者的问题做出最小的改变,以便他能更好地理解他错在哪里。
        猜你喜欢
        • 2010-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-28
        • 1970-01-01
        相关资源
        最近更新 更多