刚接触编程的同学可以看看的几个编程练习(python实现)(二)

 

本大白最近带一只小白入手编程,想法是在练习中学习,所以弄了几个题目。其中不少是经典的练习题,在很多编程入门书籍中都有出现;有的题涉及到一点数据结构的理念。在这里分享出来,刚接触编程的同学可以和我们一起做一做(无论学的是哪种语言都可以看一看,思路是通用的。这里我们学的是python),也欢迎大家指正。

8.统计字符

输入一段话,统计其中字母、数字、空格、其他符号的个数

s = input("Enter a string: ")
summarize(s)

def summarize(s):
    space_count = 0
    number_count = 0
    letter_count = 0
    other_count = 0
    for i in s:
        if i == '\n':
            break
        elif i == " ":
            space_count += 1
        elif (i >= 'a' and i <= 'z') or (i >= 'A' and i <= 'Z'):
            letter_count += 1
        elif i in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
            number_count += 1
        else:
            other_count += 1

    print(str(letter_count) + " letters.")
    print(str(number_count) + " numbers.")
    print(str(space_count) + " spaces.")
    print(str(other_count) + " other signals.")

9.整数数位拆解

输入一个正整数及其位数,获取其每个数位上的数字

通过整除10得到个位数;减去个位后,整除100得到十位数字;减去十位数字后整除1000得到千位数字……这样先获取个位,最后获取最高位。当然也可以先获取最高位,最后获取个位。

### 先获取最高位,最后获取个位
def split(n, digits):
    result = []
    digit = 1
    while digit <= digits:
        temp = int((n % (10 ** digit)) / (10 ** (digit - 1)))
        result.append(temp)
        n -= 10 ** (digit - 1) * temp
        digit += 1
    return result

### 先获取个位,最后获取最高位
def seperate(integer,digit):
    result=[]
    while digit > 0:
        tens = 10 ** (digit - 1)
        number = int(integer / tens)
        result.append(number)
        integer -= number*tens
        digit -= 1
    return result        

# example
split(6128, 4)

10.求最大公约数与最小公倍数

求两个正整数m, n的最大公约数和最小公倍数。由于m * n = 最大公约数 * 最小公倍数,所以关键在于求最大公约数。

最大公约数法一:枚举法。记min = min{m, n}, 那么按这个顺序:min, min-1, min-2, ..., 2, 1,寻找第一个既能整除m又能整除n的数,这个数就是m, n的最大公约数。

最大公约数法二:欧几里得法。记n = pm + r,其中r为余数,则m,n的最大公约数也是m,r的最大公约数。这可以用递归实现。

### 枚举法
n = int(input("Enter m: "))
m = int(input("Enter n: "))
divisor = greatest_common_divisor(n, m)
print("The greatest common divisor of " + str(n) + " and " + str(m) 
    + " is: " + str(divisor))
print("The minimum common multiple of " + str(n) + " and " + str(m)
    + " is: " + str(int(n * m / divisor)))

def greatest_common_divisor(n, m):
    integer_min = min(n, m)
    for i in range(integer_min, 0, -1):
        if n % i == 0 and m % i == 0:
            return i

### 欧几里得除法
n = int(input("Enter m: "))
m = int(input("Enter n: "))
divisor = euclid(n, m)
print("The greatest common divisor of " + str(n) + " and " + str(m) 
    + " is: " + str(divisor))
print("The minimum common multiple of " + str(n) + " and " + str(m)
    + " is: " + str(int(n * m / divisor)))

def euclid(n, m):
    if n % m == 0:
        return m
    else:
        return euclid(m, n % m)

11.一元二次方程的根的逼近

解一元二次方程当然可以由求根解析式直接得到,但作为练习,我们在这里使用逼近的方法计算近似解。这中数值方法可以用在没用解析解的方程中。

法一 二分法:在区间[a, b]严格单调的连续函数f(x),若f(a) * f(b)  <  0,即f(a)与f(b)异号,则f在开区间(a, b) 有且仅有一解。我们可以取mid = (a + b) / 2,若f(mid) 等于0,则mid即为解;若f(mid)与f(a)异号,则解在区间(a, mid),我们令右端点为mid;若f(mid)与f(b)异号,则解在区间(mid, b),我们令左端点为mid。照此迭代,可将解所在区间不断缩小,直到达到我们要求的精度epsilon。

法二 牛顿法:若函数有解,由二次函数的对称性及单侧的严格单调性,我们考虑右侧(即x > -b / (2a) 的部分)。在区间( -b / (2a), +infinite ) 上任取一点x作为考察点,若f(x) = 0,则x为解;否则过点( x, f(x) )做f的切线,并设x0为该切线与x轴的交点,则让x0为我们的新考察点。照此迭代,当f(考察点)足够小时,考察点也接近真正的解。

我们可以比较求解同一方程时,二分法与牛顿法的迭代次数。

""" y = a*x^2 + b*x + c """
# 二次函数
def f(x, a, b, c):
    return a*x**2 + b*x + c
# 二次函数的一阶导
def f_diff(x, a, b, c):
    return 2*a*x + b

### 12.1 二分法
a = float(input("Enter a: "))
b = float(input("Enter b: "))
c = float(input("Enter c: "))

if b ** 2 - 4 * a * c < 0:
    print("The equation has no resolve in Rational!")
elif b ** 2 - 4 * a * c == 0:
    print("The equation has only one resolve in Rational: " 
          + str(-b / (2 * a)))
else:
    dichotomy(a, b, c)

def dichotomy(a, b, c):
    count = 0
    epsilon = 1e-6
    left = -b / ( 2 * a)
    right = abs(left) + 1
    while f(left, a, b, c) * f(right, a, b, c) >= 0:
        right *= 2
        
    mid = (left + right) / 2
    while right - left > epsilon:
        count += 1
        if f(mid, a, b, c) == 0:
            break
        elif f(left, a, b, c) * f(mid, a, b, c) < 0:
            right = mid
        elif f(mid, a, b, c) * f(right, a, b, c) < 0:
            left = mid
        mid = (left + right) / 2
        
    print("The equation has two resolves in Rational")
    print("The first resolve is " + str(mid))
    print("The second resolve is " + str(2 * (-b / (2 * a)) - mid))
    print("Iretation times: " + str(count))

### 12.2 牛顿法
a = float(input("Enter a: "))
b = float(input("Enter b: "))
c = float(input("Enter c: "))

if b ** 2 - 4 * a * c < 0:
    print("The equation has no resolve in Rational!")
elif b ** 2 - 4 * a * c == 0:
    print("The equation has only one resolve in Rational: " 
          + str(-b / (2 * a)))
else:
    newton(a, b, c)
    
def newton(a, b, c):
    count = 0
    epsilon = 1e-6
    
    point = abs(-b / (2 * a)) + 1
    while abs(f(point, a, b, c)) > epsilon:
        point += - f(point, a, b, c) / f_diff(point, a, b, c)
        count += 1
        
    print("The equation has two resolves in Rational")
    print("The first resolve is " + str(point))
    print("The second resolve is " + str(2 * (-b / (2 * a)) - point))
    print("Iretation times: " + str(count))

12.寻找素数

给定一个正整数n,找出所有不大于n的素数

法一 枚举法:number遍历2至n, 对每一number,调用判断函数,判断number是否为素数。若number为素数,则将number打印。

         判断函数:输入一大于或等于2的正整数number。若等于2,则返回真;若number大于2,令i遍历2到n-1,一旦某个i能整除number,则立刻返回假。

法二 改进的枚举法:与一类似,不同的是判断函数中,i无需遍历2到n-1,只需遍历2到(number的平方根取整加1)

法三:筛选法:定义一个长度为n+1的真值表,0位置、1位置取假,其余位置取真,即初始时假定2~n均为素数。取筛选数为2,将所有2的倍数(大于2)的位置的值取为假;接下来取筛选数为3,将所有3的倍数(大于3)的位置取假;接下来取筛选数为5……这样下去,表中的逻辑值与该位置序号是否为素数就对应上了。将表中值为真的位置号打印出来,即是将素数输出。

### 12.1 n
n = int(input("Enter an integer: "))
print_prime_1(n)

def print_prime_1(n):
    count = 0
    print("Prime numbers equal or less than " + str(n) + " are:")
    for i in range(2, n+1):
        if is_prime_1(i):
            count += 1
            print(str(i) + ' ', end = '')  
            if count % 10 == 0:
                print('')

def is_prime_1(n):
    if n != 2:
        for i in range(2, n):
            if n % i == 0:
                return False
        
    return True
    
### 12.2 sqrt(n)
import math
n = int(input("Enter an integer: "))
print_prime_2(n)

def print_prime_2(n):
    count = 0
    print("Prime numbers equal or less than " + str(n) + " are:")
    for i in range(2, n+1):
        if is_prime_2(i):
            count += 1
            print(str(i) + ' ', end = '')  
            if count % 10 == 0:
                print('')

def is_prime_2(n):
    if n != 2:
        for i in range(2, int(math.sqrt(n)) + 1):
            if n % i == 0:
                return False
        
    return True    

### 12.3 筛选法
n = int(input("Enter an integer: "))
print_prime_3(n)

def print_prime_3(n):
    count = 0
    number = -1
    print("Prime numbers equal or less than " + str(n) + " are:")
    
    table = [False]
    for i in range(1, n + 1):
        table.append(True)
    
    table[1] = False
    try_num = 2
    while try_num <= int(math.sqrt(n)) + 1:
        for num in range(try_num + 1, n + 1):
            if table[num] == True:
                if num % try_num == 0:
                    table[num] = False
        for i in range(try_num + 1, n + 1):
            if table[i] == True:
                try_num = i
                break
            
    for flag in table:
        number += 1
        if flag:
            print(str(number) + ' ', end = '')
            count += 1
            if count % 10 == 0:
                print('')

这里我还比较了不同方法的运行时间:找出100000以内的素数,并将它们写入一个文件中。

# n
import datetime
import time

def is_prime_1(n):
    if n != 2:
        for i in range(2, n):
            if n % i == 0:
                return False     
    return True
 
N = 100000    
filename = "prime_number.dat"
with open(filename, 'a') as file:   
    start_time = int(round(time.time()))
    for i in range(2, N+1):
        if is_prime_1(i):
            file.write(str(i) + ' ')
    end_time = int(round(time.time()))
 
try:
    with open(filename, 'r') as file:
        contends = file.read()
except FileNotFoundError:
    print("File do not exist")
else:
    numbers = contends.split()
    print("There are " + str(len(numbers)) + " numbers in the file")
    print("Running time: " + str(end_time - start_time) + " seconds")

    
# sqrt(n)
def is_prime_2(n):
    if n != 2:
        for i in range(2, n):
            if n % i == 0:
                return False     
    return True
 
N = 100000    
filename = "prime_number.dat"
with open(filename, 'a') as file:   
    start_time = int(round(time.time()))
    for i in range(2, N+1):
        if is_prime_2(i):
            file.write(str(i) + ' ')
    end_time = int(round(time.time()))
 
try:
    with open(filename, 'r') as file:
        contends = file.read()
except FileNotFoundError:
    print("File do not exist")
else:
    numbers = contends.split()
    print("There are " + str(len(numbers)) + " numbers in the file")
    print("Running time: " + str(end_time - start_time) + " seconds")

    
# 筛选法
import math
N = 100000    
filename = "prime_number.dat"
with open(filename, 'a') as file:
    start_time = int(round(time.time()))
    
    number = -1
    table = [False]
    for i in range(1, N):
        table.append(True)
    
    table[1] = False
    table[2] = True
    try_num = 2
    while try_num <= int(math.sqrt(N)) + 1:
        for num in range(try_num + 1, N):
            if table[num] == True:
                if num % try_num == 0:
                    table[num] = False
        for i in range(try_num + 1, N + 1):
            if table[i] == True:
                try_num = i
                break           
    for flag in table:
        number += 1
        if flag:
            file.write(str(number) + ' ')
         
    end_time = int(round(time.time()))


try:
    with open(filename, 'r') as file:
        contends = file.read()
except FileNotFoundError:
    print("File do not exist")
else:
    numbers = contends.split()
    print("There are " + str(len(numbers)) + " numbers in the file")
    print("Running time: " + str(end_time - start_time) + " seconds")

后续部分请见 刚接触编程的同学可以看看的几个编程练习(python实现)(三)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值