【6】python语言代码---求解最大公约数+生成随机序列+查找问题+排序问题+N的阶乘问题+分离函数和测试代码

本文介绍了三种计算最大公约数的方法,包括穷举法、欧几里德算法和逐步相减法,并提供了随机序列生成的两种策略,以及顺序查找和串匹配的算法实现。此外,还探讨了将算法功能与测试功能分开的组织方式,并比较了循环和递归求解阶乘的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三种方法实现求解最大公约数
最大公约数–穷举法
def enumerative_method(m,n):
    #获取当前时间
    start = time.perf_counter()
    count = 1
    factor = 1
    mini = min(m,n)
    for i in range(2,mini+1):
        if m % i == 0 and n % i == 0:
            factor = i
        count = count + 1
    #获取运行结束的时间
    end = time.perf_counter()
    #执行时间
    exectime = end - start
    return factor,exectime,count
最大公约数–欧几里德算法
def euclidean_algorithm(m,n):
    #获取当前时间
    start = time.perf_counter()
    count = 1
    r = m % n
    while r != 0:
        m = n
        n = r
        r = m % n
        count = count + 1
    #获取运行结束的时间
    end = time.perf_counter()
    #执行时间
    exectime = end - start
    return n,exectime,count
最大公约数–逐步相减法
def subtract_method(m,n):
    #获取当前时间
    start = time.perf_counter()
    count = 1
    while m != n:
        if m > n:
            m = m -n
        else:
            n = n-m
        count = count + 1
    #获取运行结束的时间
    end = time.perf_counter()
    #执行时间
    exectime = end - start
    return n,exectime,count
生成随机序列
前N个自然数的随机序列生成算法(数字不能重复,也不能缺少)
生成随机序列–random内置函数
def random_sequence1(n):
    #获取当前时间
    start = time.perf_counter()
    randoms = random.sample(range(1, n+1),n)
    #获取运行结束的时间
    end = time.perf_counter()
    #执行时间
    exectime = end - start
    return randoms,exectime
生成随机序列–顺序序列打乱
def random_sequence2(n):
    #获取当前时间
    start = time.perf_counter()
    orders = []
    for order in range(1,n+1):
        orders.append(order)
    #将顺序排序序列随机打乱
    random.shuffle(orders)
    #获取运行结束的时间
    end = time.perf_counter()
    #执行时间
    exectime = end - start
    return orders,exectime
关于将算法功能函数与测试功能函数分成两个文件方法
具体操作

1、安装pytest,在命令行输入以下命令

pip install pytest

2、把自己的算法代码和测试代码分别放到两个文件中

  • 算法代码文件命名方式示例:bruteforce.py
  • 测试代码文件命名方式示例:bruteforce_test.py
  • 测试文件中测试函数的函数名必须是以test_开头,示例:test_select、test_bubble

3、pytest模块包的使用

  • 在测试代码文件头导入该模块包,同时导入算法代码文件的所有函数,测试文件和算法文件可以放在同一级目录下
import pytest
from bruteforce import *
  • 在测试代码文件中添加下面代码
if __name__ == '__main__':
	#只运行其中指定的一个测试函数
	pytest.main(['bruteforce_test.py::test_select','-s'])
	#运行该文件下所有测试函数
	pytest.main(['bruteforce_test.py','-s'])

4、即可运行测试代码文件了

穷举法实现查找问题
顺序查找
#两个算法的r列表的第一个元素都是,采用的是设置哨兵方法
def SeqSearch1(r:list,n:int,k:int):
    i = n
    while i > 0 and r[i] != k:
        i-= 1
    return i
#在第一个方法的基础上,把下标为0的第一个元素赋值为目标元素的值,减少了循环条件
def SeqSearch2(r:list,n:int,k:int):
    r[0] = k
    i = n
    while r[i] != k:
        i -= 1
    return i
顺序查找测试
def test_seq1():
    list = [0, 15, 4, 14, 7, 8, 10, 5, 12, 9, 13, 3, 11, 2, 1, 6]
    index1 = SeqSearch1(list,15,6)  #顺序查找
    print("\n顺序查找结果: 要查找的数在列表的第%d位... \n"%index1)

def test_seq2():
    list = [0, 15, 4, 14, 7, 8, 10, 5, 12, 9, 13, 3, 11, 2, 1, 6]
    index1 = SeqSearch2(list,15,6)  #顺序查找
    print("\n改进后顺序查找结果: 要查找的数在列表的第%d位... \n"%index1)
串匹配
def bf(s,t):
    i = 0; j = 0
    while i <= len(s)-1 and j <= len(t)-1:
        if s[i] == t[j]:
            i = i + 1
            j = j + 1
        else:
            i = i - j + 2
            j = 1
    if j > len(t)-1:
        return i - j + 1
    else:
        return 0

def getnext(t):
    next = [0] * len(t)
    next[1] = 0
    j = 1; k = 0
    while j < len(t)-1 :
        if k == 0 or t[j] == t[k]:
            j = j + 1
            k = k + 1
            next[j] = k
        else:
            k = next[k]
    return next

def kmp(s,t):
    i = 0; j = 0
    next = getnext(t)
    while i <= len(s)-1 and j <= len(t)-1:
        if s[i] == t[j]:
            i += 1
            j += 1
        else:
            i = i - j + 2 
            j = next[j]
    if j > len(t)-1:
        return i - j + 1
    else:
        return 0    
串匹配测试
def test_string():
    s = "ababcabcacbab"
    t = "abcac"
    next = [0] *len(t)
    index2 = bf(s,t)        #BF算法串匹配
    end2 = len(t) - 1 + index2
    print("\nBF算法串匹配结果:子串在主串的第%d位到第%d位上..."%(index2,end2))

    index3 = kmp(s,t)       #KMP算法串匹配
    end3 = len(t) - 1 + index3
    print("\nKMP算法中使用到的next数组为:")
    print(getnext(t))
    print("\nKMP算法串匹配结果:子串在主串的第%d位到第%d位上..."%(index3,end3))
穷举法实现排序问题
选择排序
def select_sort(r):
    n = len(r)
    for i in range(n):
        index = i
        for j in range(i+1,n):
            if r[j] < r[index]:
                index = j
        if index != i:
            r[i],r[index] = r[index],r[i]
    return r
#测试选择排序
def test_select():
	list = [20, 15, 47, 14, 76, 83, 10, 51, 12, 39, 13, 36, 11, 32, 61, 96]
    sortlist1 = select_sort(list)
    print("\n选择排序后的结果:")
    print(sortlist1)
冒泡排序
def bubblesort(r):
    n = len(r)
    for i in range(n-1):
        for j in range(n-i-1):
            if r[j] > r[j+1]:
                r[j],r[j+1] = r[j+1],r[j]
    return r
#改进的冒泡排序是增加了一个一趟交换记录,
#即在一趟起泡排序过程中,如果有多个记录交换到最终位置,则下一趟起泡排序将不处理这些记录;
#另外,在一趟起泡排序过程中,如果没有记录相交换,那么表明这个数组已经有序,算法将终止。
def bubblesort2(r):
    n = len(r)
    exchange = n
    while exchange:
        bound = exchange;exchange = 0
        for j in range(bound-1):
            if r[j] > r[j+1]:
                r[j],r[j+1] = r[j+1],r[j]
                exchange = j
    return r
#测试冒泡排序代码
def test_bubble():
	list = [20, 15, 47, 14, 76, 83, 10, 51, 12, 39, 13, 36, 11, 32, 61, 96]
    sortlist2 = bubblesort(list)
    sortlist3 = bubblesort2(list)
    print("\n冒泡排序后的结果:")
    print(sortlist2)
    print("\n改进后的冒泡排序结果:")
    print(sortlist3)
两种算法求解N的阶乘问题,并对两种方法进行比较
方法一:使用循环求解n的阶乘
def factorial(n):
    fact = 1
    while n>0:
        fact = fact * n
        n-=1
    return fact
方法二:使用递归算法求解n的阶乘
def factorial(n):
    fact = n
    if n>1:
        fact = fact * f1(n-1)
    return fact

比较两者的性能

方法一运行性能比方法二高。因为方法二递归涉及到的内存操作要比方法一使用的循环更加复杂,最主要的就是递归调用函数中的变量的压栈、出栈操作,使用了更多的寄存器,会对机器的运行效率影响较大,如果递归的层次太多肯定会导致内存溢出、系统崩溃。

代码笔记先写到这,有待进一步补充…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_x_w

你的肯定是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值