欧几里德算法的步数打印(或输出到文件)表

时间:2013-01-24 04:12:57

标签: algorithm python-3.x pretty-print

我想打印(或以类似下面的人类可读格式发送文件)任意大小的方形表,其中每个表格单元格包含解决Euclid所需的步数 #39;对于行/列标题中的两个整数的算法是这样的(手写的表格,但我认为这些数字都是正确的):

  1  2  3  4  5  6
1 1  1  1  1  1  1 
2 1  1  2  1  2  1
3 1  2  1  2  3  1
4 1  1  2  1  2  2
5 1  2  3  2  1  2
6 1  1  1  2  2  1

理想情况下,脚本允许我选择起始整数(如上所述为1或如下所示为11或其他任意值)和结束整数(如上所述为6或如下所示为16或其他任意且大于起始整数的其他内容),所以我也可以这样做:

   11 12 13 14 15 16
11  1  2  3  4  4  3
12  2  1  2  2  2  2
13  3  2  1  2  3  3
14  4  2  2  1  2  2
15  4  2  3  2  1  2
16  3  2  3  2  2  1

我意识到该表是关于对角线的对称的,因此表中只有一半包含唯一信息,并且对角线本身始终是一步算法。

请参阅thisnumber of steps required to solve Euclid's algorithm,了解我之后的图片,但我想了解图片所用的任意两个整数的实际步数#39;告诉我。

我有算法(可能有更好的实现,但我认为这些有用):

步数计数器:

def gcd(a,b):
    """Step counter."""
    if b > a:
        x = a
        a = b
        b = x
    counter = 0
    while b:
        c = a % b
        a = b
        b = c
        counter += 1
    return counter

列表构建器:

def gcd_steps(n):
    """List builder."""
    print("Table of size", n - 1, "x", n - 1)
    list_of_steps = []
    for i in range(1, n):
        for j in range(1, n):
            list_of_steps.append(gcd(i,j))
    print(list_of_steps)
    return list_of_steps

但我完全不知道如何写表。我想到了一个带有i和j的东西的双嵌套for循环,但我是Python的新手,并且没有关于写表的最佳方式(或任何方式)的线索。我不需要像表格单元格那样将行/列头偏移到表格单元格中的特殊格式,因为我可以用眼睛做到这一点,但只是让所有内容排成一行以便我能够轻松阅读它对我来说太难了在我目前的技能水平,我很害怕。我认为在两个嵌套的for循环中打印/输出可能是有意义的,因为我计算了我需要的数字,这就是列表生成器有一些打印语句以及返回列表的原因,但是我不知道如何使用印刷魔术来完成我之后的工作。

1 个答案:

答案 0 :(得分:1)

试试这个。程序逐行计算数据并在可用时打印每一行, 为了限制内存使用量。

import sys, os

def gcd(a,b):
   k = 0
   if b > a:
      a, b = b, a
   while b > 0:
      a, b = b, a%b
      k += 1
   return k

def printgcd(name, a, b):
   f = open(name, "wt")
   s = ""
   for i in range(a, b + 1):
      s = "{}\t{}".format(s, i)
   f.write("{}\n".format(s))
   for i in range(a, b + 1):
      s = "{}".format(i)
      for j in range (a, b + 1):
         s = "{}\t{}".format(s, gcd(i, j))
      f.write("{}\n".format(s))
   f.close()

printgcd("gcd-1-6.txt", 1, 6)

前面的内容不会返回包含所有计算值的列表,因为它们是故意销毁的。但是很容易做到。这是一个带有哈希表的解决方案

def printgcd2(name, a, b):
   f = open(name, "wt")
   s = ""
   h = { }
   for i in range(a, b + 1):
      s = "{}\t{}".format(s, i)
   f.write("{}\n".format(s))
   for i in range(a, b + 1):
      s = "{}".format(i)
      for j in range (a, b + 1):
         k = gcd(i, j)
         s = "{}\t{}".format(s, k)
         h[i, j] = k
      f.write("{}\n".format(s))
   f.close()
   return h

这是另一个列表

def printgcd3(name, a, b):
   f = open(name, "wt")
   s = ""
   u = [ ]
   for i in range(a, b + 1):
      s = "{}\t{}".format(s, i)
   f.write("{}\n".format(s))
   for i in range(a, b + 1):
      v = [ ]
      s = "{}".format(i)
      for j in range (a, b + 1):
         k = gcd(i, j)
         s = "{}\t{}".format(s, k)
         v.append(k)
      f.write("{}\n".format(s))
      u.append(v)
   f.close()
   return u