OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 19 Март, 2024 08:11

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 53 ]  На страницу 1, 2, 3  След.
Автор Сообщение
СообщениеДобавлено: Вторник, 12 Июнь, 2007 13:15 

Зарегистрирован: Понедельник, 04 Июнь, 2007 22:19
Сообщения: 3
Добрый день... У меня возникла проблема с массивом, нужна программа на BB, которая создаёт динамический массив, даёт возможность пользователю заполнить значения (буквы, цифры - что угодно), а после подсчитывает колличество одинаковых элементов в массиве и выводит пользователю. Если вас не затруднит помогите кто чем сможет. Заранее спасибо!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 12 Июнь, 2007 13:54 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
1) Динамический массив.
Объявляется так:
VAR a: POINTER TO ARRAY OF INTEGER;
Создается на заданное количество элементов так:
NEW(a, 150).
LEN(a) возвращает длину массива, а LEN(a)-1 соответственно номер его последнего элемента. Циклы надо писать с использованием "до LEN-1", это грамотно.
Удалять массив не надо, в ББ сборщик мусора, который сам его уничтожит потом.
2) Ввод данных.
А как Вы хотите получать данные от пользователя? Для учебных и "числомолотильных" задачек обычно используется модуль In (посмотрите его документацию). Он считывает данные из выделенного в момент запуска вашей программы куска текста.
Пример ввода:
Код:
VAR a: POINTER TO ARRAY OF INTEGER;
      i, n: INTEGER;
BEGIN
  n := 0;
  In.Open;
  (* Считаем количество элементов в выделенном фрагменте *)
  In.Int(i);
  WHILE In.Done DO (* Пока считывается успешно *)
    INC(n);   
    In.Int(x)
  END;
  (* создаем массив на посчитанное количество элементов *)
  NEW(a, n);
  (* Повторно считываем фрагмент - теперь уже запоминая в массиве *)
  In.Open;
  FOR i := 0 TO LEN(a)-1 DO
    In.Int(a[i])
  END


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 08:15 

Зарегистрирован: Суббота, 09 Декабрь, 2006 08:56
Сообщения: 35
Откуда: Беларусь
Возможно, допущена опечатка:
In.Int(x);

Необходимо
In.Int(i);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 09:34 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Да, конечно же.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 09:44 

Зарегистрирован: Понедельник, 04 Июнь, 2007 22:19
Сообщения: 3
Данные от пользователя я хочу просто ввести в текстовом окне... по типу 2 ok.. 56 ok.. 34 ok и т.д.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 09:47 

Зарегистрирован: Понедельник, 04 Июнь, 2007 22:19
Сообщения: 3
Огромное Вам спасибо, вы мне очень сильно помогли.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 10:19 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Никита писал(а):
Данные от пользователя я хочу просто ввести в текстовом окне... по типу 2 ok.. 56 ok.. 34 ok и т.д.

Тогда читайте хелп ББ (надеюсь, Вы русскую версию скачали?) - учебник "Компоненты ББ шаг за шагом" (средняя часть в окне хелпа), главу 4 "Формы".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 18:25 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Желательно добавить проверку на то, что поток открылся. Для большей ясности.
Код:
...
BEGIN
   n := 0;
   In.Open;
   IF In.Done THEN
   (* Считаем количество элементов в выделенном фрагменте *)
   ...
   END


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 13 Июнь, 2007 22:59 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Поток может и открыться, но в нем не быть чисел...

Лучше уж после
Код:
  In.Int(i);
  WHILE In.Done DO (* Пока считывается успешно *)
    INC(n);   
    In.Int(x)
  END;

добавить:
ASSERT(n > 0, 20) - предусловие на то, что вводится хотя бы одно число.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 08:27 

Зарегистрирован: Суббота, 09 Декабрь, 2006 08:56
Сообщения: 35
Откуда: Беларусь
А вот так:
Код:
In.Open;
  (* Считаем количество элементов в выделенном фрагменте *)
   n := -1;
   REPEAT
      In.Int(i);  INC(n);
   UNTIL ~In.Done  ;
  (* создаем массив на посчитанное количество элементов *)
  IF  n>0  THEN NEW(a, n);
  (* Повторно считываем фрагмент - теперь уже запоминая в массиве *)
  In.Open;
  FOR i := 0 TO LEN(a)-1 DO In.Int(a[i]); END;
      ELSE   StdLog.String("Данные где?")
END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 10:27 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Pavel писал(а):
А вот так:
Код:
REPEAT
   In.Int(i);  INC(n);
UNTIL ~In.Done  ;

Цикл построен неверно. n будет на единицу больше, чем чисел.
Между выполнением In.Int(i) и INC(n) должна быть проверка условия In.Done, что и обеспечивал WHILE с вынесенным действием.
Схема чтения из потока:
Код:
Берем_след_элемент;
WHILE Взят_успешно() DO
   Используем элемент - например, считаем
   Берем_след_элемент
END;

Это цикл с вынесенным действием, т.к. чтений выполняется на одно больше, чем выполнений тела цикла с полезным действием - чтобы понять, что поток закончился, нужно попробовать прочитать.

WHILE с вынесенным действием можно реализовать и через UNTIL, но не так, как Вы написали, а вот так:
Код:
REPEAT
  Берем_след_элемент;
  IF Взят_успешно() THEN
      Используем_элемент
  END
UNTIL ~ Взят_успешно();

Здесь тело цикла выполняется на один раз больше, чем у предыдущего WHILE. Но чтобы полезное действие не выполнялось лишний раз на последнем "холостом" витке, нужно поставить IF.
В данном случае WHILE короче и удобнее. Однако бывают ситуации, код код взятия следующего элемента весьма громоздок, и удобнее поставить лишний IF, чем дублировать код перед циклом.


Последний раз редактировалось Илья Ермаков Четверг, 14 Июнь, 2007 10:32, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 10:30 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
А, пардон, Вы перед циклом сделали n := -1. Можно, но не красиво - шаманство. n - количество элементов, и инвариант на него - n >= 0 по определению. К тому же, если бы мы выполняли не подсчет, а какое-то другое более сложное действие с данными из потока, то такой номер бы не прошел.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:11 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Без повторения кода и без лишних вызовов функции. Да и понять проще...
Код:
LOOP
  Берем_след_элемент;
  IF ~Взят_успешно() THEN EXIT END;
  Используем элемент;
END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:18 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Ни в коем случае! Вот, елки-палки, даже в КП люди GOTO себе найдут... :-)
Без лишних вызовов функций и легко понимабельный - первый вариант с WHILE. Это типовая схема, которая используется всегда. Практически. Иногда - альтернативный вариант REPEAT.

LOOP-END - это не цикл для повседневного использования. Его ввели в КП как в промышленном языке для некоторых навороченных кусков вроде циклов обработки сообщений и т.п. Не более.

Почему "нельзя"? Потому что вариант с WHILE - это частный случай универсальной базовой схемы "полный проход по последовательности" которая просто формально приспосабливается к текущей ситуации Ее надо знать - и наоборот, уметь узнавать в чужом коде как единое целое. Тогда не будет казаться, что "склепанное на коленках" частное решение с GOTO "понять проще".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:43 

Зарегистрирован: Понедельник, 29 Январь, 2007 19:00
Сообщения: 370
Откуда: Украина, Запорожье
Почему GOTO? У этого цикла LOOP одна точка входа и одна точка выхода.


Последний раз редактировалось PGR Четверг, 14 Июнь, 2007 11:52, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:47 

Зарегистрирован: Суббота, 09 Декабрь, 2006 08:56
Сообщения: 35
Откуда: Беларусь
Илья Ермаков писал(а):
Вы перед циклом сделали n := -1. Можно, но не красиво - шаманство.

Все программирование ШАМАНСТВО. :wink:
n- в данном варианте это количество элементов, если оно получилось равно нулю, то элементов нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:52 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
PGR писал(а):
Почему GOTO? У цикла LOOP одна точка входа и одна точка выхода.

Ну, в данном случае да. Но вообще цикл LOOP позволяет делать сколько угодно точек выхода. Не стоит его использовать. Если конструкция позволяет делать много выходов, то тут же начнут делать - просто в силу правила "насыщения степеней свободы инструмента".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 11:56 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Все программирование ШАМАНСТВО. :wink:
n- в данном варианте это количество элементов, если оно получилось равно нулю, то элементов нет.

См. выше - ну зачем строить неверные циклы, затем изобретать велосипеды для их объезда, а потом еще искать теоретическое обоснование? :-)
Есть понятие инварианта - условия, которое должно соблюдаться на протяжении выполнения некоторого блока - в его начале, в середине и в конце. Если n - число элементов, то при грамотном построении алгоритма на всем его протяжении должен выполняться инвариант n >= 0. Если же инвариант приходится нарушать (n := -1), то это признак неграмотно построенного алгоритма...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:00 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
PGR писал(а):
Почему GOTO? У этого цикла LOOP одна точка входа и одна точка выхода.


Сейчас тебя пошлют читать Дейкстру :) Забей. Типичный случай, когда break (в твоем случае EXIT) удобнее/нагляденее/эффективнее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 14 Июнь, 2007 12:01 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Вообще, полезно почитать книжку Бейбера "Программное обеспечение без ошибок".
viewtopic.php?t=411


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 53 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB