Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使分数计算器代码更优化(更快、使用更少内存)的提示_Python_Performance_Optimization - Fatal编程技术网

Python 使分数计算器代码更优化(更快、使用更少内存)的提示

Python 使分数计算器代码更优化(更快、使用更少内存)的提示,python,performance,optimization,Python,Performance,Optimization,基本上,我需要程序做的是充当一个简单的分数计算器(用于加法、减法、乘法和除法),用于一行输入,例如: -输入:1/7+3/5 -输出:26/35 我的初始代码: import sys def euclid(numA, numB): while numB != 0: numRem = numA % numB numA = numB numB = numRem return numA for wejscie in sys.stdin

基本上,我需要程序做的是充当一个简单的分数计算器(用于加法、减法、乘法和除法),用于一行输入,例如:
-输入:
1/7+3/5

-输出:
26/35

我的初始代码:

import sys

def euclid(numA, numB):
    while numB != 0:
        numRem = numA % numB
        numA = numB
        numB = numRem
    return numA

for wejscie in sys.stdin:
    wyjscie = wejscie.split(' ')
    a, b = [int(x) for x in wyjscie[0].split("/")]
    c, d = [int(x) for x in wyjscie[2].split("/")]
    if wyjscie[1] == '+':
        licz = a * d + b * c
        mian= b * d
        nwd = euclid(licz, mian)
        konA = licz/nwd
        konB = mian/nwd
        wynik = str(konA) + '/' + str(konB)
        print(wynik)
    elif wyjscie[1] == '-':
        licz= a * d - b * c
        mian= b * d
        nwd = euclid(licz, mian)
        konA = licz/nwd
        konB = mian/nwd
        wynik = str(konA) + '/' + str(konB)
        print(wynik)
    elif wyjscie[1] == '*':
        licz= a * c
        mian= b * d
        nwd = euclid(licz, mian)
        konA = licz/nwd
        konB = mian/nwd
        wynik = str(konA) + '/' + str(konB)
        print(wynik)
    else:
        licz= a * d
        mian= b * c
        nwd = euclid(licz, mian)
        konA = licz/nwd
        konB = mian/nwd
        wynik = str(konA) + '/' + str(konB)
        print(wynik)
我把它简化为:

import sys

def euclid(numA, numB):
    while numB != 0:
        numRem = numA % numB
        numA = numB
        numB = numRem
    return numA

for wejscie in sys.stdin:
    wyjscie = wejscie.split(' ')
    a, b = [int(x) for x in wyjscie[0].split("/")]
    c, d = [int(x) for x in wyjscie[2].split("/")]
    if wyjscie[1] == '+':
        print("/".join([str((a * d + b * c)/euclid(a * d + b * c, b * d)),str((b * d)/euclid(a * d + b * c, b * d))]))
    elif wyjscie[1] == '-':
        print("/".join([str((a * d - b * c)/euclid(a * d - b * c, b * d)),str((b * d)/euclid(a * d - b * c, b * d))]))
    elif wyjscie[1] == '*':
        print("/".join([str((a * c)/euclid(a * c, b * d)),str((b * d)/euclid(a * c, b * d))]))
    else:
        print("/".join([str((a * d)/euclid(a * d, b * c)),str((b * c)/euclid(a * d, b * c))]))
欢迎提供任何关于如何进一步改进的建议


编辑:还有一件我忘了提到的事情——代码不能使用除sys之外的任何库。

您可以做的最大改进可能是使用Python(2.6)的库:


您可以从单个“+”、“-”等中找出将分数减少到最低项的代码。这将使代码更干净、更紧凑、更可读。

您可以在
欧几里德
函数上使用,这可能有助于根据输入数据加快速度。但是,这将使用更多内存

您还可以在
euclid

def euclid(numA, numB):
    while numB != 0:
        numA, numB = numB, numA % numB
    return numA
这里的地图更快

a, b, c, d = map(int, wyjscie[0].split("/")+wyjscie[2].split("/"))

欧几里德
分解成辅助函数是一个好主意。我建议尝试将代码进一步分解为更多的帮助函数

一个想法是创建如下四个函数(加、减、乘、除):

def multiply(val1, val2):
    # Unpack the tuples.
    numerator1, denominator1 = val1
    numerator2, denoninator2 = val2

    # Figure out the resulting numerator and denominator here.

    # Return the result as a tuple.
    return numerator, denominator

重构代码以使用helper函数,我认为您的主代码将更干净。

我将创建一个包含
分子
分母
字段(两个整数)的类,并实现
\uuuuu添加
\uu子
\uu多
\uuuu div。然后,您可以简单地使用普通数学函数来组合实例

出于您的目的,这可能有点过头了,但代码会更干净


事实上,基于类的方法正是
分数
模块的实现方式。通常我会建议检查分数模块的源代码,看看它是如何编写的,但由于这是为了家庭作业,我不确定这是允许的。赋值结束后,可能值得检查一下,看看完整的小数类型是如何实现的。

您还可以优化欧几里德函数。你可以使用欧几里德算法来代替


可以找到两种实现算法的方法,不幸的是,代码是用C编写的。但我认为,如果将其翻译成python,这并不难

如果不是因为我不能使用除sys之外的任何库这一事实(a忘了提到-对不起!),这可能会完成这项工作。请注意,我不需要一个完整的解决方案。我要寻找的是在这种情况下可能应用的一般提示。通过多次调用
euclid(a*d,b*c)
,您可能会使它比将结果存储在变量+1中的版本慢,因为它承认这是家庭作业,而不仅仅是找人为您做的。:)另一方面,你的变量名是怎么回事?这些是用另一种语言写的,还是仅仅是晦涩难懂的缩写
wyjscie
?@musicfreak,可能是波利谢克利德的算法需要O(logn)个步骤,所以记忆它不会有多大帮助。此外,许多输入可能永远不会重复,因此程序运行的时间越长,记忆就会慢慢泄漏内存。您可以尝试记忆和非记忆,看看哪一个更快。我认为使用timeit模块()是可以接受的,尽管有禁止使用库的规定。+1我认为阅读别人编写的好代码可能是学习如何编写好代码的最好方法之一。您一定要在某个时候查看
分数
模块的源代码,因为它可能写得非常好。非常好!我一定会努力理解分数模块是如何完成的。正如丹尼尔所说,这可能有点过分,但这肯定不是浪费。非常感谢。
def multiply(val1, val2):
    # Unpack the tuples.
    numerator1, denominator1 = val1
    numerator2, denoninator2 = val2

    # Figure out the resulting numerator and denominator here.

    # Return the result as a tuple.
    return numerator, denominator