Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на языке Pascal


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

lamed
Статус: Профессионал
Рейтинг: 2785
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2484
∙ повысить рейтинг »
star9491
Статус: Профессионал
Рейтинг: 2322
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / Pascal (Паскаль)

Номер выпуска:1117
Дата выхода:04.07.2010, 12:30
Администратор рассылки:Boriss, Академик
Подписчиков / экспертов:200 / 183
Вопросов / ответов:1 / 2

Вопрос № 179346: Здравствуйте уважаемые эксперты. Помогите пожалуйста написать программу на Pascal в среде Turbo. Задание: Дано k>0 и набор ai(i=1,..,k). Сумма по всем a = 0. Числа записаны по кругу . Вычислить максимальное значение суммы стоящих подряд чисе...



Вопрос № 179346:

Здравствуйте уважаемые эксперты. Помогите пожалуйста написать программу на Pascal в среде Turbo.
Задание: Дано k>0 и набор ai(i=1,..,k). Сумма по всем a = 0. Числа записаны по кругу . Вычислить максимальное значение суммы стоящих подряд чисел. Программу составить с использованием списков.

Требования к программе
Программа должна:
- состоять как минимум из 2-х программных модулей,
- содержать динамические структуры данных

заранее спасибо

Отправлен: 29.06.2010, 12:29
Вопрос задал: Саурин Роман, Посетитель
Всего ответов: 2
Страница вопроса »


Отвечает Andrew Kovalchuk, Студент :
Здравствуйте, Саурин Роман.
На мой взгляд решение этой задачи вполне может обойтись и без списков (достаточно динамического массива с "условием закольцованности" - так даже удобнее выбирать данные).
Прикрепленный архив содержит:
- исходник решения (179346.pas)
- исходник модуля с реализацией закольцованного списка (ringlist.pas)
- скомпилированный модуль (ringlist.tpu)
Предлагаемое решение соответствует условию и требованиям к задаче. Прикрепленный файл: загрузить »

-----
Временная неудача лучше временной удачи

Ответ отправил: Andrew Kovalchuk, Студент
Ответ отправлен: 29.06.2010, 19:24
Номер ответа: 262334

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 262334 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Отвечает amnick, Профессионал :
    Здравствуйте, Саурин Роман.

    Ниже приведен мой вариант решения Вашей задачи. (Решение несколько избыточно — меню, 2 метода создания списков.)

    Модуль RingList предоставляет объект кольцевого списка. Вы создаете объект и затем оперируете с ним, использую предоставляемые им методы. В отличие от варианта решения, представленного экспертом Andrew Kovalchuk, можно создавать любое кол-во кольцевых списков. Головная программа работает со списком, не вникая в его внутреннюю структуру.

    Головная программа 179346.PAS:
    Код:
    {
    Дано k > 0 и набор ai(i=1,..,k). Сумма по всем a = 0.
    Числа записаны по кругу.
    Вычислить максимальное значение суммы стоящих подря д чисел.
    Программу составить с использованием списков.
    }
    Uses Crt, RingList;

    { нахождение максимальной суммы стоящих подряд чисел
    с учетом "закольцованности" }
    procedure find_max_sum( pRingList: PTRingList );
    var p: PRLItem;
    max, sum, i1, i2, count: integer;
    iStart, iEnd: integer;
    begin
    if pRingList = nil then begin
    writeln( 'Нет данных' );
    exit;
    end;

    max := 0; { текущая максимальная сумма }
    count := pRingList^.getSize - 1;
    { внутри программы индексы от 0 }
    for i1:=0 to count do begin
    { поочередно берем каждый элемент в качестве
    первого элемента подпоследовательности }

    sum := 0; { текущая сумма }
    { вычисляем сумму стоящих подряд чисел с учетом закольцованности }
    for i2 := i1 to count+i1 do begin
    p := pRingList^.getr( i2 );
    sum := sum + p^.value;
    if sum > max then begin
    max := sum; { новый максимум }
    iStart := i1;
    iEnd := i2;
    end
    else if sum < 0 then
    { если в какой-то момент сумма стала отрицательной,
    то максимума уже не достичь }
    break;
    end;
    end;

    writeln('Максимальная сумма подпоследовательности = ', max );
    { при выводе индексы отсчитываем от 1 }
    writeln('a[', iStart+1, '] .. a[', (iEnd mod (count+1))+1, '] :' );
    pRingList^.printSeq( iStart, iEnd-iStart+1 );
    end;

    { ручной ввод массива }
    function manual_input: PTRingList;
    var sum, value, code, count: integer;
    s: string;
    pList: PTRingList;
    begin
    new( pList, init ); { создаем список }
    writeln( 'Введите значения элементов массива.'#13#10'Для окончания введите пустую строку.' );
    count := 0;
    sum := 0;
    while true do begin
    while true do begin
    write( 'a[', count+1, '] = ' );
    readln(s);
    if s = '' then break;
    val( s, value, code ) ;
    if code = 0 then break;
    writeln( 'Недопустимый ввод. Повторите.' );
    end;
    if s = '' then break;

    inc(count);
    pList^.add( value );
    sum := sum + value;
    end;
    if sum <> 0 then begin
    inc( count );
    pList^.add( -sum ); { коррекция для получения нулевой суммы }
    end;
    if count = 0 then begin
    dispose( pList, done );
    pList := nil;
    end;
    manual_input := pList;
    end;

    { генерация псевдослучайного массива }
    function gen_random: PTRingList;
    var sum, value, n: integer;
    pList: PTRingList;
    begin
    pList := nil;
    writeln( 'Введите кол-во элементов: ' );
    readln( n );
    if n < 2 then
    writeln( 'Слишком мало элементов. ' )
    else begin
    new( pList, init ); { создаем список }
    sum := 0;
    randomize; { инициализаци генератора псевдослучайных чисел }
    while n > 1 do begin
    value := integer(random( 100 )) - 50; { чис ло в диапазоне -50..49 }
    inc( sum, value );
    pList^.add( value );
    dec( n );
    end;
    pList^.add( -sum ); { коррекци я суммы }
    end;
    gen_random := pList;
    end;

    { вывод массива на экран }
    procedure print_list( pRingList: PTRingList );
    begin
    if pRingList <> nil then
    pRingList^.print
    else
    writeln( 'Нет данных' );
    end;

    Var pRingList: PTRingList; { указатель на закольцованный массив }
    ch: char;

    begin
    pRingList := nil;
    repeat
    writeln(
    '-------------------------------'#13#10+
    '1. Ручной ввод'#13#10+
    '2. Генерация случайного массива'#13#10+
    '3. Вывод массива'#13#10+
    '4. Поиск максимальной суммы'#13#10+
    '-------------------------------'#13#10+
    '0. Выход'#13#10+
    '-------------------------------'
    );

    { этот цикл позволяет исключить повторный вывод меню при
    нажатии неверной клавиши }
    repeat ch := readkey; until (ch >= '0') and (ch <= '4');

    case ch of '1':
    begin
    if pRingList <> nil then dispose( pRingList, done );
    pRingList := manual_input;
    end;
    '2':
    begin
    if pRingList <> nil then dispose( pRingList, done );
    pRingList := gen_random;
    end;
    '3': print_list( pRingList );
    '4': find_max_sum( pRingList );
    end;
    until ch = '0';

    if pRingList <> nil then
    dispose( pRingList, done );
    end.


    Модуль кольцевого списка RINGLIST.PAS:
    Код:
    Unit RingList;

    Interface

    type
    PRLItem = ^TRLItem;
    TRLItem = Record { элемент списка }
    next: PRLItem; { указател ь на следующий элемент }
    value: integer; { данные }
    end;

    { кольцевой список целых чисел }
    PTRingList = ^TRingList;
    TRingList = object
    pHead, pTail: PRLItem; { указатели на первый и последний элементы }
    count: word; { кол-во элементов в списке }

    constructor init;
    destructor done;

    procedure add( value: integer );
    function get( index: integer ): PRLItem;
    function getr( index: integer ): PRLItem;
    function getSize: word;
    procedure print;
    procedure printSeq( i, n: integer );
    procedure release;
    end;

    Implementation

    { инициализация списка }
    constructor TRingList.init;
    begin
    pHead := nil;
    pTail := nil;
    count := 0;
    end;

    { уничножение списка }
    destructor TRingList.done;
    begin
    release;
    end;

    { добавление элемента в список }
    procedure TRingList.add( value: integer );
    var p: PRLItem;
    begin
    new( p );
    p^.value := value;
    if pHead = nil then
    pHead := p
    else { pTail <> nil }
    pTail^.next := p;

    p^.next := pHead;
    pTail := p;
    inc( count );
    end;

    { удаление всех элементов и освобождение памяти }
    procedure TRingList.release;
    var next: PRLItem;
    begin
    if pTail <> nil then begin
    pTail^.next := nil; { разрываем кольцо - так проще будет определить конец }
    while pHead <> nil do begin
    next := pHead^.next;
    dispose( pHead );
    pHead := next;
    end;
    pTail := nil;
    count := 0;
    end;
    end;

    { Возвращает указатель на элемент по индексу.
    Индекс должен быть в диапазоне 0..(count-1) }
    function TRingList.get( index: integer ): PRLItem;
    var p: PRLItem;
    begin
    p := pHead;
    if p <> nil then
    while index > 0 do begin
    p := p^.next;
    if p = pHead then begin
    { слишком большой индекс - прошли весь список }
    get := nil;
    exit;
    end; dec( index );
    end;

    get := p;
    end;

    { Возвращает указатель на элемент по индексу.
    Если индекс больше числа элементов в списке, то он "закручивается",
    т.е. a[count] = a[0]; a[count+1] = a[1] ...
    }
    function TRingList.getr( index: integer ): PRLItem;
    begin
    if count > 0 then
    getr := get( index mod count )
    else
    getr := nil;
    end;

    { возвращает кол-во элементов в списке }
    function TRingList.getSize: word;
    begin
    getSize := count;
    end;

    { выводит на экран последовательность из n элементов
    (но не больше числа элементов в списке),
    начиная с индекса i (отсчет от 0) }
    procedure TRingList.printSeq( i, n: integer );
    var p: PRLItem;
    begin
    p := getr( i );
    if p <> nil then begin
    if n > count then n := count;
    while n > 0 do begin
    write( p^.value:5 );
    p := p^.next;
    dec( n );
    end;
    writeln;
    end;
    end;

    { выводит список на экран }
    procedure TRingList.print;
    begin
    printSeq( 0, count );
    end;
    { можно печатать список и так:
    var p : PRLItem;
    begin
    p := pHead;
    if p <> nil then begin
    repeat
    write( p^.value:5 );
    p := p^.next;
    until p = pHead;
    writeln;
    end;
    end;
    }

    end.


    Программа протестирована в Borland Pascal 7.0.
    Запускать в DOSBOX (иначе — runtime error 200 из-за модуля CRT).

    Успехов!

    Ответ отправил: amnick, Профессионал
    Ответ отправлен: 01.07.2010, 23:48
    Номер ответа: 262374

    Оценка ответа: 5
    Комментарий к оценке:
    спасибо огромное)))

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 262374 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.16 от 26.05.2010

    В избранное