赞
踩
如何判断一个正整数是否是素数
素数(Prime Number
),又称质数,一个大于1
的自然数,除了1
和它自身外,不能整除其他自然数的数叫做质数;否则,称为合数(Composite Number
)。1
既不是素数,也不是合数。
如2、3、5、7、11
都是素数,因为找不到除了1
和其本身之外的约数;而4、6、8
都是合数,因为4
可以整除2
,6
可以整除2
和3
,8
可以整除2
和4
。
而一个数的约数必然是不超过该数的,加上素数必需是只有1
和本身是其约数的条件。于是,我们可以通过枚举小于该数,并且大于1
的整数,来判断该数是否是素数。
假设有一个正整数a
,则其可以被写成任意两个正整数之积,即a = p * q
。假设p < q
,那么正整数p
和q
都是a
的约数。注意到,如果我们知道p
是a
的约数,那么可以通过q = a / p
快速求得另外一个约数q
。同样的道理,如果某个数p
不是a
的约数,那么q
也不是a
的约数。这就意味着我们在枚举约数的时候,只需要枚举2
到不大于sqrt(a)
的正整数即可。
虽然通过上述方法,已经能让我们在根号级别的复杂度内,判断一个正整数是否为素数。但是我们其实还可以做得更快!回到我们最初的起点,我们之所以要枚举这些数,就是想找出原数的约数。然后除1
外,任何一个正整数都能写成多个素数的乘积的形式,所以我们枚举特定范围内的所有素数,也能达到相同的效果,而且数字范围越大,其区间内素数个数和区间长度之比也将越来越小,大家可以看看下面不同区间内的素数统计结果:
从上图的统计结果我们可以发现,我们用区间内的素数去判断一个整数是否素数,比较的次数相较之前来说更少。虽然就单次判断一个素数来说,这样的算法可能并没有优势,因为还需要时间去求出该区间内的所有素数。但是如果需要判断的数字很多,那么先把该区间内的所有素数求出来,无疑是个更好的选择。
而求不超过某个正整数x
内的所有素数,有一个著名的算法——埃拉托斯特尼筛法。其算法描述为:
vis
,把不大于该正整数x
的所有正整数标记为0
,表示没有访问;2
开始遍历整个区间,如果当前访问的数没有访问过,则可以认为它是一个素数。那么就将它在该区间内所有的倍数,全部标记为已访问,这样就保证外部的循环发现的没有访问过的数都是素数。其具体实现如下述代码所示:
- def sieve(x):
- vis = [0 for i in range(x+1)]
- prime_table = []
- for i in range(2, x+1):
- if vis[i] == 0:
- prime_table.append(i)
- for j in range(i*2, x+1, i):
- vis[j] = 1
- return prime_table
然而,除了上述筛法,还有其他高效的筛法,比如欧拉筛法,这里只给出其代码实现,希望大家能仔细去体会。
题目:
根据提示,在右侧编辑器Begin-End
区间补充代码,实现判断一个正整数是否是素数。如果是,则返回True
,否则返回False
(注意,返回值是布尔值)。
提示:如果要使用
sqrt
,需要通过import math
导入math
模块。
- class Solution:
- def solve(self, x):
- '''
- :type x: int
- :rtype : Boolean
- '''
- #请在此添加代码,实现判断一个数是否是素数
- #********** Begin *********#
- result=True
- if x==1:
- result=False
- for i in range(2,x):
- if x%i==0:
- result=False
- break
- return result
- #********** End *********#
使用 % 符号进行格式化输出
使用%
符号表示占位符,从而实现格式化输出的方法,应该在很多高级编程语言都是可以直接使用的。通常的有%d
表示输出十进制整数、%f
表示输出浮点小数、%s
表示输出字符串等等。
除了用占位符直接输出,我们有时候可能需要数字或字符串以左对齐或者右对齐的方式输出,或者需要输出占用指定位数的空间(保证数据显示比较整齐),又或者以保留指定位数的方式输出小数等等问题。这就需要我们对占位符有进一步的了解,对于第一个问题,比如我们要输出占10
个空间大小的整数,则可以写成%10d
,其他占位符可以类似操作。对于第二个问题,有占位符的情况下,输出是右对齐的。Python 如果需要左对齐,只要将%10d
变为%-10d
即可。对于第三个问题,比如我们要输出2
位小数,则可以写成%.2f
。注意,这里保留2
位小数默认是四舍五入的。
示例程序:
- #使用占位符直接输出
- print("%d %f %s" % (20, 20.5, "hello python!"))
- #以右对齐方式输出占10位空间大小的整数,并且用0补齐输出
- print("%010d" % 100)
- #以保留3位小数的方式输出小数,注意是四舍五入的方式
- print("%.3f" %(3.1416))
示例输出:
- 20 20.500000 hello python!
- 0000000100
- 3.142
更多的占位符表示可以参考下图:
使用 format 进行格式化输出
使用format
进行格式化输出,最早是在 Python 2.6 开始使用,主要是通过{}
和format
关键字来引出,用法和之前的占位符使用有点类似,不过这里不需要指明输出类型,而且需要多次输出的变量只需要显示传入一次即可。
示例程序:
- #指明要输出的变量的顺序
- print("{0} {1} {2} {0} {1}".format(20, 20.5, "hello python!"))
- #指明要输出的变量的名称
- print("{a} {b}".format(b=666, a=123))
- dt = {"a":123, "b":666}
- #以解析关键字参数的方式输出
- print("{a} {b}".format(**dt))
示例输出:
- 20 20.5 hello python! 20 20.5
- 123 666
- 123 666
那如果我们又遇到之前对齐方式或者保留指定位数等问题呢?可以参照下列示例程序。
示例程序:
- #以右对齐方式输出占10位空间大小的整数,并且用0补齐输出
- print("{:>010}".format(100))
- #以居中对齐方式输出占10位空间大小的整数,并且用0补齐输出
- print("{:^010}".format(100))
- #以保留3位小数的方式输出小数,注意是四舍五入的方式
- print("{:.3f}".format(3.1416))
示例输出:
- 0000000100
- 0001000000
- 3.142
使用 f-string 进行格式化输出
f-string
是从 Python 3.6 才开始使用的一种格式化输出的办法,相比前面两种格式化输出,使用f-string
更易读,更简洁,不易出错,而且速度更快!使用的时候通过f
关键字引出,然后要输出的变量直接在输出内容中用{}
引出。然后其他使用和前面的format
方式类似。
示例程序:
- a = 5
- dt = {'a': 123, 'b': 666}
- print(f"{a} {dt}")
- #以右对齐方式输出占10位空间大小的整数,并且用0补齐输出
- print(f"{a:>010}")
- b = 3.1416
- #以保留3位小数的方式输出小数,注意是四舍五入的方式
- print(f"{b:.3f}")
示例输出:
- 5 {'a': 123, 'b': 666}
- 0000000005
- 3.142
题目:
根据提示,在右侧编辑器Begin-End
区间补充代码,输出指定大小的乘法表。要求每一个乘法表项用一个空格隔开,并且让乘法表项的结果以右对齐且占3
个空间大小的方式输出,详情请看样例。
测试输入:
1
预期输出:
测试输入:
2
预期输出:
参考代码:
- class Solution:
- def solve(self, x):
- '''
- :type x: int
- :rtype : None
- '''
- #请在此添加代码,实现打印前x行乘法表的内容
- #********** Begin *********#
- for i in range(1,x+1):
- for j in range(i,10):
- if j==9:
- print("%d*%d=%3d" %(i,j,i*j),end='')
- else:
- print("%d*%d=%3d" %(i,j,i*j)+" ",end='')
- print()
- #********** End *********#
input 函数的使用
Python 2 中的输入函数有input
和raw_input
,而 Python 3 中的输入函数只有input
,这里只讲后者。每次使用input
函数,默认从缓冲区读取一行内容,并以字符串形式返回内容,而且给函数传的参数可作为输出内容,输出在缓冲区。
示例程序:
- #读取一行内容
- s1 = input("请输入:")
示例输入:
hello python
缓冲区的显示内容为:
请输入:hello python
而我们要对输入内容进行表达式运算,往往的操作就是将操作数和运算符分别提取出来,然后用栈的思想进行运算。这里只考虑最简单的情况——只有两个操作数和一个运算符,那么我们只需要将数字字符,通过int
将其强制类型转换成数字,然后通过进制特点还原成原来的数字,再判断运算符类型,进而完成对应的运算。
上述过程可能会是其他高级编程语言的通常做法,但在 Python 中有一个eval
函数,能够直接根据参数内容求出一些简单表达式字符串的值。
示例程序:
print(eval("9+5-2*10"))
示例输出:
-6
Python 的条件语句
Python 的条件语句由关键字if
、elif
或else
引出,其中if
和elif
后面可以接着写条件内容,else
后面不能写条件内容。使用elif
关键字,必须保证之前已经使用了if
关键字,表示不满足该语句之前所有所写的条件,且满足本次所写的条件。如果使用else
关键字,那么必须保证之前已经使用了if
或elif
关键字,且后面没有其他的条件语句,表示不满足该语句之前所有所写的条件。具体使用,请参照下面成绩判断程序。
示例程序:
- def judge(x):
- if x < 0 or x > 100:
- print(f"{x} 不是一个合法的分数")
- elif x < 60:
- print(f"不及格!")
- elif x < 90:
- print(f"及格!")
- else:
- print(f"很优秀!")
- judge(-2)
- judge(20)
- judge(66)
- judge(99)
示例输出:
- -2 不是一个合法的分数
- 不及格!
- 及格!
- 很优秀!
题目:
根据提示,在右侧编辑器Begin-End
区间补充代码,实现计算并返回简单表达式的值。返回结果请保留2
位小数。
每次测试输入3
行:
op
,表示要进行的运算,保证表达式进行的运算只有加减乘除,即该字符只可能是+ - * /
中的一个;num_1
;num_2
。测试输入:
- *
- 5
- 6
预期输出:
30.00
参考代码:
- class Solution:
- def solve(self, op, num_1, num_2):
- '''
- :type op, num_1, num_2: str, int, int
- :rtype : Str
- '''
- #请在此添加代码,实现计算并返回表达式的结果,要求结果保留2位小数
- #********** Begin *********#
- result=0
- if op=='+':
- result=num_1+num_2
- elif op=='-':
- result=num_1-num_2
- elif op=='*':
- result=num_1*num_2
- elif op=='/':
- result=num_1/num_2
-
-
- result=f"{result:.2f}"
- return result
-
- #********** End *********#
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。