IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Задачка на массив
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Есть такая задача:
Дано вещественное число R и массив размера N. Найти два элемента массива, сумма которых наиболее|наименее близка к данному числу.
Подскажите как решать, а то я даже не знаю как начать... blink.gif

Сообщение отредактировано: kent -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата(kent @ 12.07.05 14:23)
Есть такая задача:

Подскажите как решать, а то я даже не знаю как начать...  blink.gif


Перебираешь все пары элементов, находишь разницу (R- сумма) по модулю, запоминаещь индексы обоих если ок. Все просто.

Ps 2 Volvo: как скажешь smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Цитата(mlc @ 12.07.05 17:32)
Перебираешь все пары элементов, находишь разницу (R- сумма) по модулю, запоминаещь индексы обоих если ок.


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

Сообщение отредактировано: kent -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Вот тут есть хорошее объяснение алгоритма генерации сочетаний (в присоединенном документе). Для твоего примера будет N оно и есть N, но M = 2, то есть будут генерироваться индексы всех возможных сочетании по 2 элемента из N: Генерация всех перестановок элементов
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


volvo, спасибо за ссылку... :thanks:
Вот вроде решил: :p1:

Program Array18;
{Дано вещественное число R и массив размера N. Найти два элемента массива,
сумма которых наиболее|наименее близка к данному числа.}
uses crt;
var a:array [1..1000] of Integer;
sum:array [1..1000] of Real;
buf:array [1..1000] of Real;
dif:array [1..1000] of Real;
id_1:array [1..1000] of Integer;
id_2:array [1..1000] of Integer;
N,i,m,j:Integer;
k,all:Integer;
r:Real;
min,max:Real;
min_id,max_id:Integer;
short_sum_a_1,short_sum_a_2:Integer;
long_sum_a_1,long_sum_a_2:Integer;
begin
Clrscr;
min:=maxint; max:=-maxint;
Write('Введите вещественное число R:');
ReadLn®;
Write('Введите целое число N:');
ReadLn(N);
Write('Введите массив размера N:');
for i:=1 to N do begin
Read(a[i]);
buf[i]:=a[i];
end;
m:=2;
for i:=1 to m do a[i]:=i;
k:=0;
repeat
k:=k+1;
for i:=1 to m do begin
if (i>1) then begin
id_1[k]:=a[i-1];
id_2[k]:=a[i];
end;
end;
sum[k]:=buf[(id_1[k])]+buf[(id_2[k])];
i:=m;
while a[i]=N-m+i do dec(i);
inc(a[i]);
for j:=i+1 to m do a[j]:=a[j-1]+1;
until i=0;
all:=k;
for k:=1 to all do begin
if ((sum[k]>0) and (r>0)) or ((sum[k]<0) and (r<0)) then
dif[k]:=abs(sum[k]-r)
else if ((sum[k]>0) and (r<0)) or ((sum[k]<0) and (r>0)) then
dif[k]:=abs(sum[k]+r);
if (dif[k]<min) then begin
min:=dif[k];
min_id:=k;
end;
if (dif[k]>max) then begin
max:=dif[k];
max_id:=k;
end;
end;
short_sum_a_1:=id_1[min_id]; short_sum_a_2:=id_2[min_id];
long_sum_a_1:=id_1[max_id]; long_sum_a_2:=id_2[max_id];
WriteLn('Наиболее приближенные:',short_sum_a_1,' ',short_sum_a_2);
WriteLn('Наиболее удаленные:',long_sum_a_1,' ',long_sum_a_2);
Readkey;
end.


Только у меня в TP 7.0 после вывода результата выдает еще какую то лабуду похожую на нотный знак...???

Сообщение отредактировано: kent -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Ай-яй-яй... Нехорошо компилировать программы без ключа {$R+} smile.gif
Попробуй поставить его в 1-ю строку программы, и ты увидишь, что в строке
while a[i]=N-m+i do dec(i);
происходит выход за пределы массива (Range-Check Error)... А это значит, что ни на что больше полагаться нельзя... Любые данные могут оказаться запорченными...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


Выход за пределы нужно всегда проверять!
смотрим код:
     repeat

k:=k+1;
for i:=1 to m do begin
if (i>1) then begin
write (k:4); { вставил здесь для отладки, потому что был выход за пределы. Индекс K был 1001 ...}

id_1[k]:=a[i-1];
id_2[k]:=a[i];
end;
end;
Т.е. нужно добавить проверку (K<=1000)

Далее...
while a[i]=N-m+i do dec(i);
Где проверка (i > 1) ?
Должно быть так:
while (i>1) and (a[i]=N-m+i) do dec(i);


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


Проверку на K нужно добавлять на строке until:
until (i=0) or (k = 1000);


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Цитата(volvo @ 13.07.05 13:14)
Ай-яй-яй... Нехорошо компилировать программы без ключа {$R+} smile.gif

А что это за ключ и для чего он нужен?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Romtek, поставил проверку как ты сказал, вроде больше этот знак не вылезает...
Спасибо что поправил!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Знаток
****

Группа: Пользователи
Сообщений: 303
Пол: Мужской
Реальное имя: Роман

Репутация: -  2  +


Нужен для проверки выхода за пределы границ массива. Тогда программа прервётся с ошибкой 201.

Можно выставить в опциях IDE: Options -> Compiler -> [X] Range checking
И сохранить установки.

Сообщение отредактировано: Romtek -


--------------------
Romiras HomeLab- материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и прочее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Пионер
**

Группа: Пользователи
Сообщений: 50
Пол: Мужской
Реальное имя: Андрей

Репутация: -  1  +


Теперь понял...
Еще раз спасибо всем кто помогал. :thanks:
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 25.04.2024 2:14
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name