Как вы заставляете объект возвращать отсортированный массив вместо пустого в Python? - PullRequest
2 голосов
/ 29 декабря 2011

Я пытаюсь создать библиотеку некоторых распространенных алгоритмов, чтобы люди могли легко их использовать. Я создал объект с именем 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 для возврата отсортированного массива.

Ответы [ 3 ]

1 голос
/ 29 декабря 2011

В вашем коде много проблем, некоторые из них приводят к сбою, например

  • в отсортированном виде вы используете возможно глобальный arr, который не существует, вместо self.arr).
  • в свопе вы также используете a[j] = temp, но a является локальным для метода, и вы не используете его ни для чего
  • вы используете два подчеркивания для своих методов.Это приводит к искажению имен, поэтому вызовы функции не работают так, как вы их делаете.Вероятно, вы хотите, чтобы одно подчеркивание указывало на то, что это закрытые методы.

Но главная проблема в том, что Compare не возвращает список.Для этого вам нужно:

class Compare(list):
    def __init__(self, arr):
        list.__init__(self, arr)

затем:

>>> print Compare([1,2,3,4])
[1, 2, 3, 4]

Таким образом, вы должны использовать в своих методах self вместо self.arr, потому что ваш экземпляр является списком (илиэкземпляр подкласса list).

Итак, ваш код изменен для реальной работы.Единственная проблема заключается в том, что ваш алгоритм сортировки неверен, а сортировка неверна.Но вы можете сделать отсюда, я полагаю:

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."
1 голос
/ 29 декабря 2011

Я почти уверен, что это то, что происходит.При вызове:

array = Compare(array)

Вы перезаписываете ссылку на исходный массив.Массив теперь является ссылкой на объект сравнения.Замените массив на array.arr (или назовите массив как-нибудь лучше), и я думаю, это должно сработать!:)

Помните, что python свободно набран, так что ваша переменная "массив" является просто ссылкой на некоторые данные.В этом случае вы переключаете его со ссылки на список на ссылку на объект сравнения.

Подумайте о:

>>> x = 1
>>> x
1
>>> x = 's'
>>> x
's'

И подумайте о том, что происходит с 1;)

0 голосов
/ 29 декабря 2011

Вы не возвращаете массив, вы возвращаете Compare, обернутый вокруг массива.Если вы намереваетесь Compare быть прокси-сервером, перенос будет неполным, так как вы не перенаправляете стандартные операции контейнера в проксируемый массив.Кроме того, вам необходимо постоянно использовать экземпляр Compare.В настоящее время вы иногда используете Compare, а в других случаях используете исходный объект последовательности, например, каждый раз, когда вы передаете последовательность методу.Вместо этого используйте объект Compare в его собственных методах.

Однако он имеет Compare do две вещи : быть набором алгоритмов и быть последовательностью.Если вы держите объект Compare отдельно и работаете со списком напрямую, вы можете легко переключать алгоритмы.Это более типичный подход;list.sort работает таким образом, принимая в качестве аргумента компаратор.Вам также необходимо исправить вашу реализацию Compare, которая использует неправильное имя переменной во многих местах (array, когда локальная переменная называется arr).Если вы хотите, чтобы кто-нибудь использовал вашу библиотеку, она должна быть намного лучше спроектирована.

В качестве дальнейших причин не превращать Compare в последовательность, подумайте, что происходит, когда вам нужно изменить методы сравнения: вы заканчиваетеобернуть Compare в другой, сделав обернутый Compare бесполезным.

Рассмотрим подход, используемый в математике: порядок - это отношение, определенное в наборе, а не внутренняя часть набора, и особенно это не часть последовательностей элементов из набора.Это обнаруживает еще одну концептуальную ошибку с вашим оригинальным подходом: он связывает упорядочение (которое является отношением набора) с операциями над последовательностями элементов из набора.Они должны храниться отдельно, чтобы вы могли использовать разные сравнения с операциями последовательности.

Вне темы

В коде есть ряд других ошибок различных типов.Например, в SelectionSort вы предполагаете, что ошибки типа должны быть из-за непоследовательности, передаваемой как array.Сравнение экземпляров несопоставимых типов (таких как 0 и 'd') также приведет к ошибке типа.Для другого примера Compare.sorted бесполезен;это имеет вид:

if test:
    return True
return False

Это логически эквивалентно:

return test

, что означает Compare.sorted эквивалентно Compare.__determine.Сделайте последнее первым, так как sorted - более описательное имя.«определить» слишком двусмысленно;напрашивается вопрос о том, что определяется.

Вы можете получить больше обзоров кода на codereview.stackexchange.com .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...