Помощь - Поиск - Пользователи - Календарь
Полная версия: Улучшить функцию улучшил я
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
maksimla
Первичные данные целых чисел массив, элементы в массиве упорядочены возрастающем порядке. Функция Daug читает элементы и определяет число который больше всех в этом массиве находится. Если есть числа которые одинаковое число раз повторяются то в ответе любое должно быть.
Задание простое и логичное.
Код
const m = ...;
      n = ...;
type masyvas = array [m..n] of integer;
function Daug (a : masyvas) : integer;
var i, r,        
    k,          
    sk : integer;
begin
  r := a[m];
  sk := 1; k := 1;
  for i := m + 1 to n do
    begin
      if a[i] = a[i – 1]
        then begin
               k := k + 1;
               if k > sk
                 then begin
                        r := a[i];
                        sk := k
                      end
             end
        else k := 1
    end;
  daug := r
end;

Henry Ledgard писал что этот алгоритм пробовали улучшить сто людей но некто лучше нечего не придумал.
Но вы сто первый.
Попробуйте написать решение одной переменной, и одной управляемой структурой меньше.
Что это за структура управляемой?
Я вот изменил не много не знаю правильно или нет.
Код
const m = ...;
      n = ...;
type masyvas = array [m..n] of integer;
function Daug (a : masyvas) : integer;
var i,        
    k,          
    sk : integer;
begin
  Daug := a[m];
  sk := 1; k := 1;
  for i := m + 1 to n do
      if a[i] = a[i – 1]
        then begin
               k := k + 1;
               if k > sk
                 then begin
                        Daug := a[i];
                        sk := k
                      end
             end
        else k := 1
end;
maksimla
а я даже тут в данной мне функции нашел ошибку введите такие числа
9
0
2
3
0
и ответ будит 9
или у меня ошибка не так данные написал
const m = 1;
n = 5;
type masyvas = array [m..n] of integer;
function Daug (a : masyvas) : integer;
var i, r, {elementas ir jo reik?m?}
k, {kelintas vienodas}
sk : integer; {vienod? skai?ius}
begin
r := a[m];
sk := 1; k := 1;
for i := m + 1 to n do
begin
if a[i] = a[i - 1]
then begin
k := k + 1;
if k > sk
then begin
r := a[i];
sk := k
end
end
else k := 1
end;
daug := r
end;


var x:masyvas;
i :byte;
begin
writeln('k');
for i:=m to n do
readln(x[i]);
writeln('больше чисел = ',daug(x));
readln
end.
volvo
Цитата
а я даже тут в данной мне функции нашел ошибку
Ты задание внимательно читал?
Цитата
элементы в массиве упорядочены возрастающем порядке
У тебя
Цитата
9
0
2
3
0
- НЕ возрастающий порядок... Так какую, говоришь, ошибку ты нашел?
maksimla
ой совсем забыл про возрастающий порядок
maksimla
А может можно сделать так чтобы сама функция к себе обращалась с daug=1 и так далее до n ?

Добавлено через 2 мин.
или может быть взять первое число с массива и ему делать всегда большей и с этим числом смотреть
volvo
Рекурсия? Я не думаю, что ты этим улучшишь функцию... Быстрее от этого она точно не станет.
maksimla
а мне надо избавится от одной управляемой структурой меньше.
а от одной переменной я уже избавился.
так если не рекурсией то тогда чем если надо одной управляемой структурой меньше у меня идей нету уже больше.
И мне уже кажется что функцию эту нельзя улучшить
volvo
Цитата
И мне уже кажется что функцию эту нельзя улучшить
А ты не делай поспешных выводов smile.gif Вот в этой функции, например, всего 2 управляющие структуры (for и один if), а в оригинальной было 3 (for и два if-а):
function Daug (a : masyvas) : integer;
var i, k, sk: integer;
begin
Daug := a[m];
sk := 1; k := 1;
for i := m + 1 to n do
begin

k := (k div (1 + ((a[i] - a[i - 1]) * k))) + 1;
if k > sk then
begin
Daug := a[i];
sk := k
end;

end;
end;
maksimla
спасибо все понятно.
Я даже так и не думал что так можно решить. Вам наверное пришлось пару часов повозится с этим заданием. Можете сказать как вы до такого додумались?
volvo
Да какие пару часов? Тут все прозрачно: сначала переписываем функцию в виде
function Daug (a : masyvas) : integer;
var i, r,
k,
sk : integer;
begin
r := a[m];
sk := 1; k := 1;
for i := m + 1 to n do
begin
if a[ i ] = a[i - 1]
then begin
k := k + 1;
end
else k := 1;

if k > sk then begin
r := a[ i ];
sk := k
end
end;
daug := r
end;
(выносим проверку k > sk из первого if-а наружу), потом думаем, какую из этих двух уже независимых друг от друга проверок можно представить собственно БЕЗ if... Получается, что первую, потому что по результатам первой проверки выполняется одно действие (k := k + 1), а по результатам второй - целых 2: изменение R и изменение sk. Поэтому вторую проверку оставляем в покое, и более внимательно смотрим, что же нам надо сделать в первом if-е... А вот что:
if a[ i ] = a[i - 1] then 
k := k + 1
else
k := 1;

, или по-другому:
if a[ i ] = a[i - 1] then
{ k не изменяется }
else
k := 0;

k := k + 1;
Что получили? Получили if с пустой веткой then... Меня учили, что это неправильно, и так делать не надо. Надо "перевернуть" условие, чтобы пустой стала ветка else, и избавиться от нее:
if a[ i ] <> a[i - 1] then { меняем знак = на противоположный: <> }
k := 0; { то, что было в else переходит в then, а пустой бывший then убираем }

k := k + 1;

Ну, а теперь - дело техники добиться того, чтобы при разных значениях a[ i ] и a[i - 1] переменная K становилась равной 0, а при одинаковых - не изменялась. Это можно сделать по-разному, я выбрал способ: "поделить K нацело на число ЗАВЕДОМО большее K (если элементы разные) или на 1 (если элементы одинаковые)"... Вот и вся логика.
maksimla
спасибо за объяснения
maksimla
мне сказали что так нельзя использоватьпеременную функции и решение есть более простое и елигантное но несказали какое может ктото напишит? ужас поставили 4 из 10 балов оценку мне
volvo
Цитата
мне сказали что так нельзя использоватьпеременную функции
Это проблема того, кто тебе это сказал. Не надо превращать Паскаль в какой-то НЕДО-Си (оттуда ветер дует, оттуда. Это там нельзя использовать имя функции внутри самой функции, ибо возврат осуществляется через return; это как раз там необходимо ввести доп. переменную для того, чтобы хранить там результат, так что это явно Си-шные замашки), ибо Паскаль МОЩНЕЕ чем Си без всех этих выдуманных ограничений. Похоже на Холивар? Да, похоже. Ибо наболело... Учат школьников и студентов неизвестно чему (комментарии - мои): "Типы свои не описывать!!! (ну как же, ведь тогда Си будет нервно курить в стороне, а не "лидировать") Имя функции внутри нее самой не использовать!!! (аналогично, ведь в Сях нельзя этого сделать, так какое право имеют другие языки разрешать? Запретить!!!) Вложенные подпрограммы не использовать!!! (ага, причину назвать, или сами догадаетесь, почему?) Индексы массивов должны начмнаться с нуля (в крайнем случае - с единицы)!!! (А как же иначе, если Си-подобное убожество только с нуля и умеет? А мне удобнее
type
charset = set of 'a' .. 'z';
arrType = array[-20 .. 20] of charset;
, почему мне нельзя так сделать? Потому что Си не умеет? Так я НА ПАСКАЛЕ ПИШУ!!! Плевать я хотел, что кто-то там что-то не умеет. Вот когда я буду писать на Си, тогда буду думать, как обойти ограничения, а пока - я использую то, что есть в языке)"

Что имеем в итоге? Кастрированный язык, после которого очень просто подсадить того же студента на Си. Спасибо за внимание, это был крик души. Сравнение языков окончено.

Цитата
решение есть более простое и елигантное
Я тебе тоже могу сказать, что для любой задачи есть более простое и элегантное решение. Тем более, если его не показывать. Пускай покажут, тогда посмотрим. Пока что-то не видно никакого решения.
maksimla
Написал что эта программа неелегантная .
  const m = ...;
n = ...;
type masyvas = array [m..n] of integer;

function Daug(a : masyvas): integer;
var
i, j, sk : Integer;
begin
j := 1;
sk := 0;
Doug := a[m];
for i := m + 1 to n do
if (a[i] <> a[i-1]) and (i-j > sk) then begin
sk := i-j;
Daug := a[i-1];
j := i;
end;
end;

а за эту другой так сделал поставил 8 балов.

И написал что надобыло сравнивать i элимент с i-sk элиментам.
Lapp
Цитата(maksimla @ 6.11.2009 16:32) *

Написал что эта программа неелегантная .
  const m = ...;
n = ...;
type masyvas = array [m..n] of integer;

function Daug(a : masyvas): integer;
var
i, j, sk : Integer;
begin
j := 1;
sk := 0;
Doug := a[m];
for i := m + 1 to n do
if (a[i] <> a[i-1]) and (i-j > sk) then begin
sk := i-j;
Daug := a[i-1];
j := i;
end;
end;

Я не знаю насчет элегантности (не спец я в этом, не обучен), но эта программа неправильная - это я могу утверждать (на это моей квалификации хватает)).

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

maksimla, если ты отходишь от данных тебе советов, то по крайней мере сообщай об этом. Нечестно так: тебе пишут правильно, потом ты делаешь по-своему - и приходишь с претензиями! mad.gif
Lapp
А функция твоя выглядит примерно вот так:
function Daug(a: tArr): integer;
var
i,l: Integer;
begin
l:=0;
for i:= m to n do if a[i-l]=a[i] then begin
Inc(l);
Daug:=a[i]
end;
end;
maksimla
Цитата(maksimla @ 6.11.2009 15:32) *

Написал что эта программа неелегантная .
  const m = ...;
n = ...;
type masyvas = array [m..n] of integer;

function Daug(a : masyvas): integer;
var
i, j, sk : Integer;
begin
j := 1;
sk := 0;
Doug := a[m];
for i := m + 1 to n do
if (a[i] <> a[i-1]) and (i-j > sk) then begin
sk := i-j;
Daug := a[i-1];
j := i;
end;
end;

а за эту другой так сделал поставил 8 балов.

И написал что надобыло сравнивать i элимент с i-sk элиментам.


я нетак написал эта программа друга который тамже учится в школе юного програмиста ему за эту программу поставили 8 баллов.

А мне что volvo сделал поставили 4 бала и написали что функция неелегантная и мне сказали что так нельзя использоватьпеременную функции и есть более элегантное решение.

Хоть мне и и моиму другу написали что что так нельзя использоватьпеременную функции. обсурд ему 8 а мне 4 балла
Lapp
Цитата(maksimla @ 7.11.2009 9:38) *
обсурд ему 8 а мне 4 балла
Да уж, за неправильную программу 8 - это точно абсурд blink.gif .

Короче, если у тебя еще есть возможность пересдать - разбирайся с вариантом в моем предыдущем посте. Это то, что тебе нужно - с двумя управляющими структурами и без дополнительных вычислений.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.