Python 我的方法是暴力还是线性搜索?
我的问题如下: 给定整数值序列,确定序列中是否存在乘积为奇数的不同数字对。请为此问题提供两个Python函数,oddpair\u bf()和oddpair\u linear()。函数将给定的整数序列作为一个列表。oddpair_bf()函数使用蛮力方法,依次检查可能的对。当有一对乘积为奇数时,它返回True;否则,它将报告错误。第二个是oddpair_linear(),使用线性扫描方法,将访问每个元素一次。请用线性扫描来确定这一点 我试着自己解决它,结果:Python 我的方法是暴力还是线性搜索?,python,python-3.x,list,brute-force,linear-search,Python,Python 3.x,List,Brute Force,Linear Search,我的问题如下: 给定整数值序列,确定序列中是否存在乘积为奇数的不同数字对。请为此问题提供两个Python函数,oddpair\u bf()和oddpair\u linear()。函数将给定的整数序列作为一个列表。oddpair_bf()函数使用蛮力方法,依次检查可能的对。当有一对乘积为奇数时,它返回True;否则,它将报告错误。第二个是oddpair_linear(),使用线性扫描方法,将访问每个元素一次。请用线性扫描来确定这一点 我试着自己解决它,结果: def oddpair_bf(list
def oddpair_bf(list):
for i in list:
for j in list:
if i != j:
product = i*j
if product & 1:
return True
return False
现在我的问题是,这是蛮力方法还是“线性扫描”方法?我需要如何以不同的方式处理它呢?您的方法是蛮力,因为它探索了所有可能的组合 很好地使用了
&
运算符,而不是经典的(x%2)==1
蛮力
我建议对您的代码进行两项改进:
- 不要将
用作变量名,因为它是list的保留语言关键字list
- 减半测试,因为乘法是可交换的(对称的)
def oddpair\u bf(顺序):
n=长度(序号)
对于范围(n)中的i:
对于范围(i+1,n)内的j:
如果序号[i]*序号[j]&1:
返回真值
返回错误
可使用itertools
对其进行压缩:
def oddpair_bf2(序号):
对于itertools组合中的x,y(序号2):
如果x*y&1:
返回真值
返回错误
在最坏的情况下,这个新版本仍然处于O(n^2)
。但是您可以通过从n^2
(正方形,两个大小为n
)的嵌套循环中删除n+n*(n-1)/2
(对角线和下三角形)大小写来避免不必要的比较,因为乘法是可交换的:除了x*y
,我们不需要检查y*x
线性的
在暴力版本之前降低复杂性通常是通过强调系统的固有属性来实现的,该属性使计算更容易、强度更低,从而更易于处理
对于线性版本,使用问题的一个众所周知的性质:偶数的任何乘积都将始终是偶数,因为它至少有一个来自偶数的2因子
因此,解决这个问题相当于检查列表中是否至少有两个奇数。这可以写成:
def oddpair\u线性(seq):
n=0
对于序号中的x:
如果x&1:
n+=1
如果n>=2:
返回真值
返回错误
此代码段在最坏的情况下是
O(n)
(大小为n
的单个循环)。@pakpe已将此检查很好地压缩为一个一行程序。这里有一个简洁的线性函数,用于检查序列中是否有多个奇数(这将给出至少一个奇数乘积),并返回True
def oddpair_linear(seq):
return len([x for x in seq if x & 1]) > 1
既然您说的是distinct,那么您可以使用一个集合:
def oddpair_linear(seq):
return len({s for s in seq if s&1})>1
还是一个稍微好一点的方法
def oddpair_linear(seq):
found=0
for s in seq:
if s&1:
if not found:
found=s
else:
return True
return False
这是蛮力,您可以通过更改第二个迭代器来删除半格(对称)。