Пошук 2 однакових елементів в масиві
Пошук 2 однакових елементів в масиві.
Дан масив - Mas: array [1..10] of Integer;
У ньому 2 числа однакові. Як максимально швидко знайти їх.
Я знаю 1 метод:
var
# XA0; mas: array [1..10] of Integer;
# XA0; i, j, index1, index2: Integer;
begin
# XA0; index1: = 0;
# XA0; index2: = 0;
// заповнимо масив випадковими значеннями
# XA0; Randomize;
# XA0; for i: = 1 to 10 do mas [i]: = Random (100);
# XA0; i: = Random (9) + 1;
# XA0; mas [i]: = 8;
# XA0; i: = Random (9) + 1;
# XA0; mas [i]: = 8;
// власне пошук
# XA0; for i: = 1 to 9 do
# XA0; # XA0; for j: = i + 1 to 10 do
# XA0; # XA0; # XA0; if mas [i] = mas [j] then
# XA0; # XA0; # XA0; begin
# XA0; # XA0; # XA0; # XA0; index1: = i;
# XA0; # XA0; # XA0; # XA0; index2: = j;
# XA0; # XA0; # XA0; end;
end;
Є інші методи?
якщо згідно умови два однакових елемента є точно, тоді може швидше використовувати два while. Буде менше операцій в загальному випадку.
Якщо потрібно шукати тільки одну пару однакових чисел, то після того, як їх знайдете, не забудьте поставити break, щоб цикл не продовжився даремно.
> Не забудьте поставити break
Скажіть, а як ви вважаєте використовувати break, exit - ето нормальний тон програмування? (Ето не докір, ето нічого поганого сказати вам не хочу. Просто так, для загального розвитку. Я наприклад завжди намагаюся обходітсься без етіх двох команд)
Зауваження прийняті.
А щодо алгоритму - чи існують інші алгоритми, швидше цього?
(Написати на assembler "e - НЕ предлогать).
> А щодо алгоритму - чи існують інші алгоритми, швидше
> Цього?
Ну я так не згадаю. потрібно більш детально знати умову задачі. Якщо ето в програмі тільки один раз робити (пошук) - тоді напевно ето і буде набагато ефективного.
до чого я веду. ну наприклад, розглянемо задачу пошуку елемента в масиві. За кількістю операцій для мене самий ефективного спосіб є послідовне порівняння елементів. Але коли в одному і тому ж масиві (великому) # XA0; нам треба буде знаходити багато разів різні елементи - тоді я віддаю перевагу спочатку його швидким методом впорядкувати і використати наприклад бінарний пошук. Як на мене при такому варіанті прога працює швидше.
для відсортованих бінарний пошук не потрібен, під таку задачу. досить зрушувати один відносного іншого, порівнюючи елементи.
> Завжди намагаюся обходітсься без етіх двох команд
Ось якраз без них-то часто складно обійтися, якщо потрібно люгкій в розумінні, красивий і одночасно ефективний код.
> От саме без них-то часто складно обійтися
а я че то звик тільки умовами обходиться (ну наприклад для виходу з циклу).
Якщо масив спочатку впорядкувати, то завдання вирішується за максимум один повний прохід.
> Oleg_teacher # XA0; (03.03.11 21:11) [3] Скажіть, а як ви вважаєте використовувати break, exit - ето нормальний тон програмування?
Goto, Break, Exit, Continue, While-Do, Repeat-Until - моветон. Всякі Pascal, C, C ++ по суті - моветон. Я навіть не згадую C #, Basic і Java. Справжні джедаї пишуть тільки на Assembler. І навіть там намагаються уникати будь-яких Loop "ов. Є тільки сім справжніх мнемонік: Mov, Add, Or, And, Shr, Shl і JmpX. Все інше суть підступи нечестивців.
> # XA0; бінарний пошук - ж і призначений виключно для відсортованих
> Даних.
я в курсі.
> Ми напевно про різні завдання думаємо
мабуть. для єдиної пари - так. якщо знайти всі пари - тільки бінарний пошук буде повільніше.
> Oleg_teacher # XA0; (03.03.11 21:11) [3]
Звичайно, break, exit і raise суперечать принципам структурного програмування, але без них, ІМХО, іноді код може стати набагато складніше для сприйняття, ніж з ними. Наприклад, якщо перевіряється багато умов, мені здається, що код виглядає зрозуміліше, якщо при невиконанні умови робити exit, а не створювати ланцюжок else if. А цикл for в Delphi взагалі не дозволяє додавати умови виходу, так що, щоб перервати його, без break не обійтися. # XA0; Ну а без raise обробка помилок перетворюється в кошмар :)
> Че то звик тільки умовами обходиться (ну наприклад для
> Виходу з циклу).
Це як ?)
if Вираз then Вийті_із_цікла?
А Вийті_із_цікла - це, треба розуміти, що не Break. а goto куда_то_за_предели_тела_цікла?)
> # XA0; а не створювати ланцюжок else if
реально так і робив, коли нада була така необхідність.
> # XA0; А цикл for в Delphi взагалі не дозволяє додавати умови
> виходу
а навіщо тільки до for бути прихильність?
хоча я так зрозумів ето все на любителя. ось на одному з сайтів знайшов опис:
опис
Процедура Exit негайно завершує виконання поточної функції або процедури.
При виході з функції, результат містить останнє значення.
Попередження: використовуйте із застереженням - це робить обслуговування коду важким.
> While використовую тоді коли нада
Було б дивним якби його можна було використовувати тоді коли "Ненада"
Але я взагалі-то про інше.
Припустимо "алгоритмічна диспозиція" у тебе склалася така що немає ні ніякої можливості умова виходу з циклу визначити перед- або пост-умовою відповідно циклу while або repeat.
І що будеш робити ?)
> Це робить обслуговування коду важким
Кому і наречена кобила)
непонимаю тоді куди то в цикл нада буде вставити exit? Всерівно що б його використовувати. потрібно буде досягти якийсь умова, так чому б ето умова і не вибрати умовою виходу з циклу while або repeat.
Exit - це не вихід із циклу, причому він тут?
Йдеться про Break - операторі переривання виконання циклу, передавальному управління оператору, наступного за "закриває дужкою" циклу.
> Чому б ето умова і не вибрати умовою виходу з циклу
> While або repeat.
Тому що нерідко трапляються ситуації. коли цикл повинен бути перерваний під час ВЖЕ виконується його черговий ітерації
Ось простий приклад:
> While True do
> try
> # XA0; DoSomething;
> except
> # XA0; Break;
> End;
Перепиши його без використання Break - і отримаєш громіздкий і потворний код.
> Мова йде про Break
угу, вибачте неправильно висловився.
> Бути перерваний під час ВЖЕ виконується його черговий ітерації
ну не можу уявити навіть як ето повинно бути і де застосовується. Ну в загальному зрозуміло, що дані команди використовувати можна, і нічого поганого в літку немає. Головне самому не заплутатися.
> Перепиши його без використання Break - і отримаєш громіздкий
> І потворний код.
несоглашусь:
f: = True;
while f do
try
DoSomething;
except
f: = False;
end;
А як на мене, так дуже навіть нічого:
function # XA0; DoSomething: boolean;
begin
# XA0; try
# XA0; # XA0;<.>
# XA0; except
# XA0; # XA0; Result: = false;
# XA0; end;
end;
while DoSomethig do;
А якщо ще try-except-end прибрати всередині DoComething (), так і зовсім суцільний кошер.
Ну і не погоджуйся)
Але тоді не скаржся на те що цей "замінник":
1. Більше в розмірі ісх.текста (+ ще і змінну треба оголошувати)
2. Виконує мінімум на одну "зайву" перевірку більше, тобто мінімально але поступається оригіналу в продуктивності.
> Oleg_teacher # XA0; (03.03.11 23:28) [26] несоглашусь:
Имхо, прапорці ще більше убозтво, ніж Goto. Простіше вже в коді Goto візуально знайти, ніж проаналізувати умова виходу з циклу, а потім відшукувати, в якому місці коду встановлюється те чи інше значення прапорця. А якщо прапорців кілька, так і зовсім всесвітня печаль.
Погоджуся з листа (С) - ох сумно дивитися на код, тим більше чужий, з купою аби як розкиданих перевіряються прапорців.
Прапорці гарні і потрібні там, де без них просто не можна обійтися "малою кров'ю", тобто без шкоди Новомосковскбельності коду і наскрізний продуктивності алгоритму.
[30] Чи не громіздко, але потворно. про (
> Огидний # XA0; (03.03.11 21:31) [12]
> Goto, Break, Exit, Continue, While-Do, Repeat-Until - моветон.
> Всякі Pascal, C, C ++ по суті - моветон. Я навіть не згадую
> C #, Basic і Java. Справжні джедаї пишуть тільки на Assembler.
> І навіть там намагаються уникати будь-яких Loop "ов. Є тільки
> Сім справжніх мнемонік: Mov, Add, Or, And, Shr, Shl і JmpX.
> Все інше суть підступи нечестивців.
Істину глаголишь, син мій, бо від лукавого інше фсе.
Вбивати треба за такий код. Повільно і з насолодою.
Фаберже-то вони ті ж, але ми тут за брейк тлумачимо начебто)
противний # XA0; [29] - таки напевно так! Але може і без них і не обійтися. Я все таки goto вважаю великим злиденністю пограммірованія.
P.S. Так що, коли собірешься вбивати - скористайся кодом з 24. Тільки Break прибери. Тоді буде повільно. Тобто, вічно.
> # XA0; Суперечить Торі - так. Але прав, як завжди, замовник,
> А не Святе Письмо. Як ТЗ поставить - так і буде.
Так він не тільки Торі суперечить, але і Корану, Шаріату і тарікат разом узятим.
Невже є замовники, які в ТЗ деталі бидлокод обумовлюють?
Break, Continue, Exit - рулять.
Goto і сурогатні прапорці - відстій.
P. P. S. Цікаво це обговорення виглядає з точки зору програміста C співтовариші.
Ага, є такі)
Надись розрахувався з Замовником за один такий приклад.
Портував йому в Delphi чийсь там BCB-проект, з незначними функціональними # XA0; доповненнями.
Так ось там, в портіруемость оригіналі, таке було понахреноверчено - волосся дибки стає)
Я чесно запитав Замовника - ти, мовляв, як потім все це розгрібати-то будеш. І, мовляв, навіщо його двічі розгрібати - мені а потім тобі, якщо досить мені одному один раз помучитися, щоб тобі потім було спокійно і легко орієнтуватися в проекті. Давай, мовляв, малясь грошенят ще підкинь - і я наведу цей кошмар в божеський вид)
Замовник, не заперечуючи що портіруемость проект виглядає потворно, заявив. бабла, мовляв, більше не дам, мовляв, самому мало, якщо берешся за роботу, то роби чого говорять і не міркуй про високі матерії)
Випадку, вони, звичайно, завжди різні бувають :)
> Я все таки goto вважаю великим злиденністю пограммірованія.
Вважай, але про себе.
P.S.
Випадки різні бувають, буквально вчора перекидав з Фортрана на Pascal.
Там штук 50 було goto. Навіщо мені алгоритм ламати, який працює, та ще й помилки свої відловлювати?
Зробив з goto і нічого, Бог Кару не надіслав.
>> Випадки різні бувають, буквально вчора перекидав з Фортрана на Pascal.
Одна справа - рутинний переклад великих обсягів коду з мови, в якому goto є реально необхідною командою. А інша справа - перенесення звичок програмування з однієї мови програмування в інший.
"Справжній програміст може писати фортрановскіе програми на будь-якій мові програмування" (С)
Значок хочеш? Блакитний? Або червоний? Чи ні, краще. коричневий. Зі статусом "Майстер Фортрана".
P.S. Ти б ще Бейсік згадав.
Саме так, при правильній технології це можна робити швидше, ніж на
вказаних мовах, але доведеться багато попрацювати над розробкою макросів
> Огидний # XA0; (04.03.11 9:43) [44]
>
> P.S. Ти б ще Бейсік згадав.
За мене вирішувати не треба, що я хочу.
Що хочу, те й роблю по ситуації, але при цьому не даю поради, що це шлях до щастя.
> З мови, в якому goto є реально необхідною командою.
Ну ти ще Fortran 66 згадай.
Зараз goto не є необхідною, але користується.
Повторюся: "Справжній програміст може писати фортрановскіе програми на будь-якій мові програмування" (С)
Колупання в носі теж не є необхідним.
Але колупаються адже.
З тієї простої причини, що ніс є.
Не було б носа - НЕ копирсалися б.
Така ж ситуація і з goto.
P.S. Хай вибачать мене аматори колупатися в носі, якщо я мимоволі ущіміл їх права.
> Зараз goto не є необхідною, але користується.
гени