Синтаксическая ошибка Smalltalk - PullRequest
1 голос
/ 23 февраля 2012

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

| list max |
list := #(1 8 4 5 3).
    1 to: list size do: [:i |
    max < (list at: i)
        ifTrue: [max := (list at: i)].
        ifFalse: [max := max].
    ].

Когда я запускаю этот код, я получаю "stdin: 7: ошибка синтаксического анализа, ожидается ']'".Я немного сбит с толку относительно того, что вызывает это.Мне кажется, что все мои квадратные скобки соответствуют.Помощь

Ответы [ 3 ]

5 голосов
/ 23 февраля 2012

Александр уже говорил вам, что вполне вероятно, что коллекция предоставляет метод max.Вам может быть интересно несколько способов, как это сделать.

Использование коллекции max (максимум всех элементов)

#(1 8 4 5 3) max

Использование числа max: (какое из двух чисел больше)

#(1 8 4 5 3) inject: 0 into: [:max :elem|
     max max: elem ]

Или используя только внутренний итератор

#(1 8 4 5 3) inject: 0 into: [:max :elem|
    max < elem 
       ifTrue: [ elem ]
       ifFalse:[ max ] ]

Вместе с вашим решением использовать внешнюю итерацию вы можете увидеть, что существует множество возможностей.

Надеюсь, это что-то добавит

4 голосов
/ 23 февраля 2012

Номер строки кажется выключенным, но, глядя на ваш код, кажется, что ошибка, вероятно, вызвана периодом после ifTrue: [max := (list at: i)].#ifTrue:ifFalse - это одиночный селектор метода, и нет смысла разбивать его на два оператора.

На самом деле вы можете полностью удалить часть кода ifFalse.Назначение max для себя не имеет никакого эффекта.Также циклы по индексам здесь не нужны.Вы можете работать со значениями напрямую с помощью list do: […].

Переменная max также должна быть инициализирована.Ноль кажется хорошим выбором для сравнения с положительными числами в вашем массиве.

Но вместо того, чтобы делать все, что нужно для изучения класса Collection.Ваш диалект Smalltalk может уже предложить метод max для этой задачи.

3 голосов
/ 23 февраля 2012

Ваша немедленная проблема заключается в том, что вы заканчиваете раздел ifTrue точкой.Обычно вы можете просто удалить точку, но, поскольку ваша секция ifFalse фактически не работает, вероятно, лучше удалить этот бит.

Но даже когда вы исправите это, вам все равно придется инициализировать max чтобы вы не получили сообщение <, отправленное объекту nil.Вы можете инициализировать его первым элементом, если таковой имеется, тогда вы можете изменить цикл так, чтобы он начинался со второго.

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

Исправленный код:

| list max |
list := #(1 8 4 5 3).
max := -99999.
(list size) > 0 ifTrue: [max := (list at: 1)].
2 to: list size do: [:i |
    max < (list at: i) ifTrue: [max := (list at: i)].
]
(max) displayNl

Этовыводит 8 как положено, а также отлично работает на крайних случаях (размер списка ноль и один).

...