趣味算法Python实现(三)

目录

1、最大公因数和最小公倍数

2、完美数

3、阿姆斯壮数

4、最大访客数

5、中序式转后序式


1、最大公因数和最小公倍数

        最大公因数使用辗转相除法来求,最小公倍数则由这个公式来求:

                GCD * LCM = 两数乘积

        最大公因数可以使用递回与非递回求解,因式分解基本上就是使用小于输入数的数值当作除
数,去除以输入数值,如果可以整除就视为因数,比较快的解法就是求出小于该数的所有质数,
并试试看是不是可以整除。
实现:
m = int(input("请输入第一个数字:"))
n = int(input("请输入第二个数字:"))
s = m*n
while n!=0:
    r = m%n
    m = n
    n = r

print("GCD:{}".format(m))
print("LCM:{}".format(s/m))

2、完美数

        如果有一数n其真因数Proper factor的总和等于n则称之为完美数(Perfect

Number), 例如以下几个数都是完美数:

        6 = 1 + 2 + 3

        28 = 1 + 2 + 4 + 7 + 14

        496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248

        这里考虑使用质数的方式来求解,主要分为三步:

        1、求出一定数目的质数

        2、利用质数求指定数的因式分解

        3、利用因式分解求所有真因数和,并检查是否为完美数

实现


N = 1000
P = 10000


def prime(pNum):
    prime = [0] * (N + 1)
    for i in range(2, N + 1):
        prime[i] = 1

    i = 2
    while i * i <= N:
        if prime[i] == 1:
            j = 2 * i
            while j <= N:
                if j % i == 0:
                    prime[j] = 0
                j += 1
        i += 1

    j = 0
    for i in range(2, N):
        if prime[i] == 1:
            pNum[j] = i
            j += 1
    return j


def factor(table, num, frecord):
    i, k = 0, 0
    while table[i] * table[i] <= num:
        if num % table[i] == 0:
            frecord[k] = table[i]
            k += 1
            num /= table[i]
        else:
            i += 1
    frecord[k] = num
    return k + 1


def fsum(farr, c):
    i = 0
    r = 1
    s = 1
    q = 1
    while i < c:
        result = False
        while not result:
            r *= farr[i]
            q += r
            i += 1
            if not (i < c - 1 and farr[i - 1] == farr[i]):
                result = True
                break
        s *= q
        r = 1
        q = 1
    return s / 2


if __name__ == '__main__':
    # 质子信息
    ptable = [0] * (N + 1)
    fact = [0] * (N + 1)

    count1 = prime(ptable)

    for i in range(P + 1):
        count2 = factor(ptable, i, fact)
        if i == fsum(fact, count2):
            print("Perfect Number: {}".format(i))

3、阿姆斯壮数

        在三位的整数中,例如153 可以满足 1 3 + 5 3 + 3 3 = 153 ,这样的数称之为 Armstrong数,这
一次我们通过程序找出所有的三位数 Armstrong 数。
        Armstrong数的寻找,其实就是将一个数字分解为个位数、十位数、百位数......,使用除法与
余数运算就可以了,例如输入 input为abc,则:
        a = input / 100
        
        b = (input%100) / 10
        
        c = input % 10
实现如下:
for input in range(100,1000):
    a = int(input / 100)
    b = int((input % 100) / 10)
    c = int(input % 10)
    if a*a*a+b*b*b+c*c*c == input:
        print(input)

4、最大访客数

        试想举行一个聚会,并记录每一位访客的到达与离开时间,如果去估算不同时间的最大访客

数呢?

        简单处理,我们记录访客的来访时间为x[i],离开时间为y[i]。将x[i]与y[i]分别进行排序(由小

到大),道理很简单,只要先计算某时之前总共来访了多少访客,然后再减去某时之前的离开访

客,就可以轻易的解出这个问题。

实现:


MAX = 100

def swap(x, y):
    t = x
    x = y
    y = t

def maxguest(x, y, count, time):
    num = 0
    for i in range(0, count+1):
        if time>x[i]:
            num += 1
        if time>y[i]:
            num -= 1
    return num

def partition(number, left, right):
    s = number[right]
    i = left - 1
    for j in range(left, right):
        if number[j] <= s:
            i += 1
            swap(number[i], number[j])

    swap(number[i+1], number[right])
    return i+1

def quicksort(number, left, right):
    q = 0
    if left<right:
        q = partition(number, left, right)
        quicksort(number, left, q-1)
        quicksort(number, q+1, right)

if __name__ == '__main__':
    x = [0]*MAX
    y = [0]*MAX
    time = 0
    count = 0
    print("输入来访与离开125;时间(0~24):")
    print("范例:10 15")
    print("输入-1 -1结束")

    while count<MAX:
        x[count] = int(input("来访时间(0~24):"))
        y[count] = int(input("离开时间(0~24):"))
        if x[count]<0:
            break
        count += 1

    if count >= MAX:
        print("超出最大访客数({})".format(MAX))
        count -= 1

    quicksort(x, 0, count)
    quicksort(y, 0, count)

    while time<25:
        print("{} 时的最大访客数:{}".format(time, maxguest(x, y, count, time)))
        time += 1

5、中序式转后序式

    平常所使用的运算式,主要是将运算元放在运算子的两旁,例如a+b/d这样的式子,这称之为中序

(Infix)表示式,对于人类来说,这样的式子很容易理解,但由于电脑执行指令时是有顺序的,遇到中序表

示式时,无法直接进行运算,而必须进一步判断运算的先后顺序,所以必须将中序表示式转换为另一种表示方

法。
    将中序表示式转换为后序(Postfix)表示式,后序表示式又称之为逆向波兰表示式(Reversepolish 

notation),它是由波兰的数学家卢卡谢维奇提出,例如(a+b)*(c+d)这个式子,表示为后序表示式时是

ab+cd+*

实现如下:

def postfix(infix):
    i = 0
    top = 0
    stack = ['']*80
    while True:
        op = infix[i]
        if op == '':
            while top > 0:
                print(stack[top]+' ',end="")
                top -= 1
                print("")
                return
        elif op == '(':
            if top<len(stack):
                top +=1
                stack[top] = op
        elif op == '+' or op =='-' or op=='*' or op=='/':
            while priority(stack[top]) >= priority(op):
                print(stack[top]+' ',end='')
                top -= 1
            if top<len(stack):
                top += 1
                stack[top] = op
        elif op==')':
            while stack[top]!='(':
                print(stack[top]+' ',end="")
                top -= 1
            top -= 1
        else:
            print(op+' ', end='')
        i += 1

def priority(op):
    if op=='+' or op=='-':
        p = 1
    elif op=='*' or op=='/':
        p = 2
    else:
        p = 0
    return p

if __name__ == '__main__':
    input = ['(','a','+','b',')','*','(','c','+','d',')','']
    postfix(input)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苜蓿花乐园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值