Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.04;
Скачать: CL | DM;

Вниз

Мин. и макс. значения   Найти похожие ветки 

 
MaxInside   (2007-01-20 18:37) [0]

У меня есть массив, например  ar1: array [0..1234] of Integer; = 100, 101, 103, 105, 108, ...

И есть некоторое число допустим: 107, как мне быстрее и корректнее всего оперделить либо наличие этого числа в массиве или если его нет в массиве, то найти минимальный и максимальный элемент, между которыми это число должно присутствовать. В моём примере, это 108 и 105.

?


 
Джо ©   (2007-01-20 18:40) [1]

используй for и операторы сравнения.


 
MaxInside   (2007-01-20 18:48) [2]

Нет ну про то, что требуется организовать цикл, я догадался :-) Но моё решение в лоб я думаю будет слишком долго выполняться по времени, поэтому и сперашиваю про оптимальный способ... Просто проверить наличие элемента в массиве -- это понимаю, как реализовать; но вот как найти макс и мин элементы -- увы.


 
Джо ©   (2007-01-20 18:49) [3]

> но вот как найти макс и мин элементы -- увы.

используй операторы сравнения и оператор присваивания.


 
MaxInside   (2007-01-20 19:18) [4]

Хмм.. ну я придумал видимо полный бред.

var
 ar1: array [0..11 - 1] of Integer =
 (100, 101, 102, 104, 105, 108, 111, 112, 114, 119, 121);

procedure TForm1.Button1Click(Sender: TObject);
const
 u1: Integer = 106;
var
 i: Integer;
 MaxAr, MinAr: array of Integer;
begin
 for i := Low(ar1) to High(ar1) do
   if ar1[i] = u1 then Break;

 if i < High(ar1) then
 begin
   ShowMessageFmt("Position: %d", [i]);
   Exit;
 end;

 for i := Low(ar1) to High(ar1) do
   if ar1[i] < u1 then
   begin
     SetLength(MinAr, Length(MinAr) + 1);
     MinAr[Length(MinAr)] := ar1[i];
   end;

 for i := Low(ar1) to High(ar1) do
   if ar1[i] > u1 then
   begin
     SetLength(MaxAr, Length(MaxAr) + 1);
     MaxAr[Length(MaxAr)] := ar1[i];
   end;


И что теперь найти макс и мин элементы в полученных двух массивах соответственно? Хотя это бред полный...


 
Anatoly Podgoretsky ©   (2007-01-20 19:35) [5]

Ипользуй цикл и сравнение.
Цикл нужен один, а не кучу.


 
Virgo_Style ©   (2007-01-20 19:43) [6]

еще не проснулся, если брежу - прошу прощения. Но как будто бы работает.

массив упорядочен? тогда:
var Arr:array[1..10] of integer=(0,7,10,57,84,93,105,120,133,144);

procedure TForm1.Button1Click(Sender: TObject);
var LowBorder, HighBorder, i, SearchFor:Integer;
Found:boolean;
FoundAt:Integer;
S:String;
begin
 found:=false; //"нашли точное значение"
 FoundAt:=-1;  //где нашли
 SearchFor:=StrToInt(Edit1.Text);//кого ищем
 //инициализация границ поиска
 LowBorder:=Low(Arr);
 HighBorder:=High(Arr);
 //находится ли искомое в пределах массива?
 if SearchFor<Arr[LowBorder] then
   raise Exception.Create("Это под землей");
 if SearchFor>Arr[HighBorder] then
   raise Exception.Create("Это в космосе");
 //А может, оно на границах?
 if SearchFor = Arr[ LowBorder ] then begin
   found:=true;
   FoundAt:=LowBorder;
 end else
 if SearchFor = Arr[ HighBorder ] then begin
   found:=true;
   FoundAt:=HighBorder;
 end else
 //вот теперь ищем
 repeat
   //бьем отрезок пополам
   i:=(LowBorder+HighBorder) div 2;
   //и проверяем значение в центре
   if Arr[i]>SearchFor then HighBorder:=i else
   if Arr[i]<SearchFor then LowBorder:=i else
   if Arr[i]=SearchFor then begin
   //проверка на равенство после двух проверок на больше-меньше -
   // - это из разряда "безобразно, зато единообразно".
     found:=true;
     FoundAt:=i;
   end;
   //Границы уперлись друг в друга
   if (HighBorder-LowBorder<=1) then begin
     FoundAt:=HighBorder;
     break;
   end;
 until found;

 // теперь отображаем, что у нас получилось.
 S:="";
 for i:=Low(Arr) to High(Arr) do
   if i=FoundAt then begin
     if found then
       S:=S+" ["+IntToStr(Arr[i])+"] "
     else
       S:=S+" (тут) "+IntToStr(Arr[i])+" "
     end else S:=S+" "+IntToStr(Arr[i])+" ";
 Memo1.Lines.Add(S);
end;


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


 
Palladin ©   (2007-01-20 19:49) [7]


> [6] Virgo_Style ©

ужас


 
Virgo_Style ©   (2007-01-20 20:38) [8]

Palladin ©   (20.01.07 19:49) [7]
заинтригован


 
Palladin ©   (2007-01-20 21:13) [9]

в случае отсортированного массива

var
A:array[0..9] of integer=(0,7,10,57,84,93,105,120,133,144);

Function Find(n:Integer;var rp_nIndex:Integer):Boolean;
Var
L,R,M,C:Integer;
Begin
Result:=False;
L:=0;
R:=Length(A)-1;
While L<=R Do
 Begin
  M:=(L+R) shr 1;
  C:=A[M]-N;
  If C<0 Then L:=M+1 Else
   Begin
    R:=M-1;
    If C=0 Then
     Begin
      Result:=True;
      L:=M;
     End;
  End;
 End;
rp_nIndex:=L;
End;

procedure TForm1.Button1Click(Sender: TObject);
Var
n:Integer;
begin
If Find(95,n) Then ShowMessage("Founded at "+IntToStr(n)) Else
If n=0 Then ShowMessage("Right[0]="+IntToStr(A[0])) Else
If n=(Length(A)-1) Then ShowMessage("Left["+IntToStr(n)+"]="+IntToStr(A[n]))
                   Else ShowMessage("Left["+IntToStr(n-1)+"]="+IntToStr(A[n-1])+" Right["+IntToStr(n)+"]="+IntToStr(A[n]));
end;


проще не правда ли?


 
Virgo_Style ©   (2007-01-20 21:43) [10]

Palladin ©   (20.01.07 21:13) [9]
Проще, полагаю, что и оптимальнее, но насчет понятности я, наверное, позволил бы себе поспорить. Впрочем, дело вкуса.

Так или иначе, спасибо за науку %-)


 
Palladin ©   (2007-01-20 21:44) [11]

Это всего лишь реализация бинарного поиска.



Страницы: 1 вся ветка

Текущий архив: 2007.02.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.032 c
2-1169172887
Lapushka-dochka
2007-01-19 05:14
2007.02.04
Перекачка данных (проблема) По Excel вопрос


15-1168528033
iXT
2007-01-11 18:07
2007.02.04
IIS 6 Win2003 Server


2-1169154005
sinys
2007-01-19 00:00
2007.02.04
drag&amp;drop, Clipboard


2-1168785489
azl
2007-01-14 17:38
2007.02.04
Click по приложению


1-1165740150
Makhanev Alexander
2006-12-10 11:42
2007.02.04
Таскать форму правой кнопкой мыши....