我正在尝试创建一些常用算法库,以便人们可以轻松使用它们。我创建了一个名为Compare的对象,它有一些在这些算法中很有用的方法。
比较代码:
class Compare(list):
def __init__(self,arr):
self.arr = arr
def __compare(self,u,v):
# Compares one item of a Compare
# object to another
if u < v:
return 1
if u == v:
return 0
if u > v:
return -1
def __swap(self,arr,i,j):
# Exchanges i and j
temp = arr[i]
arr[i] = arr[j]
a[j] = temp
def __determine(self,arr):
# Determines if the array is sorted or not
for i in range(0,len(array)):
if self.__compare(arr[i], arr[i+1]) == -1:
return False
return True
def __printout(self,arr):
for i in range(0,len(array)):
return arr[i] + '\n'
def sorted(self):
if self.__determine(arr):
return True
return False
以下是使用此类的算法之一:
def SelectionSort(array):
try:
array = Compare(array)
for ix in range(0, len(array)):
m = ix
j = ix+1
for j in range(0,len(array)):
if array.__compare(array[j], array[m]) == -1:
m = j
array.__swap(arr, ix, m)
return array
except(TypeError) as error:
print "Must insert array for sort to work."
我遇到的问题是每当我尝试使用这个或任何其他算法时,它会返回一个空数组而不是排序数组。我不知道如何让Compare对象返回已排序的数组。
答案 0 :(得分:1)
我很确定这就是正在发生的事情。当你打电话:
array = Compare(array)
您覆盖对原始数组的引用。 Array现在是对Compare对象的引用。用array.arr替换数组(或更好地命名数组),这应该可行! :)
请记住,python是松散类型的,所以你的“数组”变量只是对某些数据的引用。在这种情况下,您将它从对列表的引用切换为对Compare对象的引用。
想一想:
>>> x = 1
>>> x
1
>>> x = 's'
>>> x
's'
考虑一下发生了什么;)
答案 1 :(得分:1)
您的代码存在许多问题,其中一些问题导致其失败 例如
arr
self.arr
)。a[j] = temp
,但是a是本地方法而你不用它做任何事情但主要问题是比较不是一个列表。为此你需要:
class Compare(list):
def __init__(self, arr):
list.__init__(self, arr)
然后:
>>> print Compare([1,2,3,4])
[1, 2, 3, 4]
通过这种方式,您应该在方法self
而不是self.arr
中使用,因为您的实例是一个列表(或列表的子类的实例)。
以下是您修改的代码实际工作。唯一的问题是你的排序算法是错误的,它没有正确排序。但你可以从这里做到我想:
class Compare(list):
def __init__(self, arr):
list.__init__(self, arr)
def _compare(self, u, v):
# Compares one item of a Compare
# object to another
if u < v:
return 1
if u == v:
return 0
if u > v:
return -1
def _swap(self, i, j):
# Exchanges i and j
temp = self[i]
self[i] = self[j]
self[j] = temp
def _determine(self):
# Determines if the array is sorted or not
for i in range(len(array)):
if self._compare(self[i], self[i+1]) == -1:
return False
return True
def _printout(self):
for i in self:
return i + '\n'
def sorted(self):
if self._determine():
return True
return False
def SelectionSort(array):
try:
array = Compare(array)
for ix in range(len(array)):
m = ix
j = ix + 1
for j in range(len(array)):
if array._compare(array[j], array[m]) == -1:
m = j
array._swap(ix, m)
return array
except(TypeError) as error:
print "Must insert array for sort to work."
答案 2 :(得分:0)
你没有返回数组,你返回一个缠绕在数组中的Compare
。如果您希望Compare
成为代理,则包装不完整,因为您不将标准container operations转发到代理数组。此外,您需要始终使用Compare
实例。目前,您有时使用Compare
,有时使用原始序列对象,例如将序列传递给方法的每个位置。相反,在自己的方法中使用Compare
对象。
然而,那是Compare
做two things:是一个算法集合,并且是一个序列。如果将Compare
对象分开并直接在列表上工作,则可以轻松切换算法。这是更典型的方法; list.sort
以这种方式工作,以比较器为参数。您还需要修复Compare
的实现,当局部变量名为array
时,arr
在许多地方使用错误的变量名称Compare
。如果你想让任何人使用你的库,那么它的设计必须更好。
作为不使Compare
成为序列的进一步理由,请考虑当您需要更改比较方法时会发生什么:最终将Compare
包装在另一个中,使得包裹的SelectionSort
无用。
考虑数学中使用的方法:顺序是在集合上定义的关系,而不是集合的固有部分,它尤其不是集合中项目序列的一部分。这揭示了原始方法的另一个概念错误:它将一个排序(这是一个集合关系)与对集合中元素序列的操作相结合。这两者应该分开,这样你就可以对序列操作进行不同的比较。
代码中存在许多其他类型的错误。例如,在array
中,您认为类型错误必须是由于非序列传递为Compare.sorted
。比较不可比较类型的实例(例如0和'd')也会导致类型错误。再举一个例子,if test:
return True
return False
没用;这是模式:
return test
这在逻辑上等同于:
Compare.sorted
表示Compare.__determine
相当于sorted
。将后者设为前者,因为{{1}}是更具描述性的名称。 “确定”太模糊了;它引出了什么是决定的问题。
您可以在codereview.stackexchange.com获得更多代码评论。