Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Вниз

Самое эффективное решение   Найти похожие ветки 

 
Rwer   (2006-10-16 16:28) [0]

Как решить такую простую задачку самым эффективным способом:
Дан массив чисел, выбрать 3 наибольших.
1 самый тупой способ: осортировать массив вывести 3 последних элемента.
2 способ: три раза проходить по массиву и вычислять минимальное значение.

А как можно это реализовать самым лучшим способом?


 
Alien1769 ©   (2006-10-16 16:33) [1]

функция екселя тебе поможет :))


 
Johnmen ©   (2006-10-16 16:35) [2]


>  выбрать 3 наибольших.


> вычислять минимальное значение.

>

Те.е минимальное значение называется "наибольшее"? :)))

3 один раз пройти по массиву, определяя святую троицу чисел...


 
Sandman29 ©   (2006-10-16 16:35) [3]

3) решить задачу в лоб. то есть пройтись один раз и запоминать 3 наибольших.


 
Alien1769 ©   (2006-10-16 16:38) [4]


> и запоминать 3 наибольших.

чисел без знака.


 
palva ©   (2006-10-16 16:39) [5]

Начать с того, что запомнить три первых элемента массива вместе с их индексами в качестве кандидатов. Далее просматривать оставшиеся элементы массива, и если очередной элемент больше какого-нибудь кандидата, то заменить этот кандидат текущим элементом.


 
Jeer ©   (2006-10-16 16:41) [6]

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

Для второго случая ориентировочно "цена" == 3*K*N, т.е. линейная зависимость.


 
TUser ©   (2006-10-16 17:44) [7]

Сотворить стек из трех элементов и пихать туда. Пример
procedure Up (var S: TStack; N: integer);
begin
 with S do begin
   if N < length (Vects) - 1 then
   with Vects[N] do
     SetInStack (S, N+1, FileName, Atom, VLen);
   end;
end;

procedure Push (var Stack: TStack; Name, Atm: string; Len: cardinal);
var i: integer;
   f: boolean;
begin
 with Stack do begin
   i := Count-1;
   if Count < MaxCount then
     GrowStack (Stack);
   f := true;
   while f and (i >= 0) do
     if Vects[i].VLen > Len then begin
       Up (Stack, i);
       dec (i);
       end else f := false;
   if (not f) or (i < 0) then
   if i < MaxCount - 1 then
     SetInStack (Stack, i+1, Name, Atm, Len);
   end;
end;

procedure PushStruct (S: TStructure);
var i: integer;
begin
 with S do
   for i := 0 to MolCount-1 do
     with Molecules[i] do
     Push (MyStack, FileName, Line, Sums[NVector-1]);
end;


 
Ketmar ©   (2006-10-16 18:06) [8]

сделать SQL-таблицу, всё занести, потом выбрать %-)


 
oldman ©   (2006-10-16 18:57) [9]

а почему способ 1 "самый тупой", если задача сводится к поиску 3 максимумов???
или это я "самый тупой"?


 
TUser ©   (2006-10-16 19:01) [10]

> oldman ©   (16.10.06 18:57) [9]

Ясно, что [7] быстрее.


 
oldman ©   (2006-10-16 19:04) [11]


> TUser ©   (16.10.06 19:01) [10]


Писать дольше.
И думать больше.


 
default ©   (2006-10-16 19:33) [12]

2 способ вполне и вполне
по крайней мере для немалых массивов я пути лучше не вижу


 
default ©   (2006-10-16 20:23) [13]

возможный способ реализации 2 способа

public static int[] GetThreeMaxInt(int[] arr)
       {
           if (arr == null) throw new ArgumentNullException();
           if (arr.Length < 3) throw new ArgumentOutOfRangeException("argument must be >= 3");
           int max;
           int[] res = new int[3];
           int[] ind = new int[3];
           for (int i = 0; i < 3; i++)
           {
               ind[2-i] = i;
               max = arr[i];
               for (int j = i+1; j < arr.Length; j++) {
                   if (arr[j] > max)
                   {
                       ind[2-i] = j;
                       max = arr[j];
                   }
               }
               res[2-i] = max;
               arr[ind[2-i]] = Int32.MinValue;
           }
           for (int i = 0; i < 3; i++) arr[ind[i]] = res[i];
           return res;
       }
       
       static void Main(string[] args)
       {
           foreach (int el in GetThreeMaxInt(new int[] {4, 8, 10, 2, 1, 16, 19}))
               Console.WriteLine(el);
       }


 
Rwer   (2006-10-16 22:12) [14]


> procedure Up (var S: TStack; N: integer);begin  with S do
> begin    if N < length (Vects) - 1 then    with Vects[N]
> do      SetInStack (S, N+1, FileName, Atom, VLen);    end;
> end;procedure Push (var Stack: TStack; Name, Atm: string;
>  Len: cardinal);var i: integer;    f: boolean;begin  with
> Stack do begin    i := Count-1;    if Count < MaxCount then
>      GrowStack (Stack);    f := true;    while f and (i
> >= 0) do      if Vects[i].VLen > Len then begin        Up
> (Stack, i);        dec (i);        end else f := false;
>    if (not f) or (i < 0) then    if i < MaxCount - 1 then
>      SetInStack (Stack, i+1, Name, Atm, Len);    end;end;
> procedure PushStruct (S: TStructure);var i: integer;begin
>  with S do    for i := 0 to MolCount-1 do      with Molecules[i]
> do      Push (MyStack, FileName, Line, Sums[NVector-1]);
> end;


А покороче нельзя 3 числа найти никак??
Я вот подумал... что лучший способ это пройти один раз по массиву и выбрать эти три числа. А как реализовать?
может, например так:

max1:=-MaxInt;  max2:=max1; max3:=max;
for i:=1 to n do begin
 if a[i]>max1 then max1:=a[i];
 if (a[i]>max2) and (a[i]<max1) then max2:=a[i];
 if (a[i]>max3) and (a[i]<max2) then max3:=a[i];
end;

Ну что скажете? Предложите свои варианты!


 
Rwer   (2006-10-16 22:15) [15]

Вот мудрость:
Настоящий программист никогда не делает всё хорошо с первого раза, он понимает важность патчей


 
homm ©   (2006-10-16 22:35) [16]


>
> max1:=-MaxInt;  max2:=max1; max3:=max;
> for i:=1 to n do begin
>  if a[i]>max1 then max1:=a[i];
>  if (a[i]>max2) and (a[i]<max1) then max2:=a[i];
>  if (a[i]>max3) and (a[i]<max2) then max3:=a[i];
> end;


на вскидку: из последовательности
182838 вернет 832


 
default ©   (2006-10-16 22:45) [17]

я же дал код

       public static int[] GetThreeMaxInt(int[] arr)
       {
           if (arr == null) throw new ArgumentNullException();
           if (arr.Length < 3) throw new ArgumentOutOfRangeException("argument must be >= 3");
           int[] max = new int[3];
           int[] ind = new int[3];
           for (int i = 0; i < 3; i++)
           {
               max[2-i] = arr[0];
               ind[2-i] = 0;
               for (int j = 1; j < arr.Length; j++) {
                   if (arr[j] > max[2-i])
                   {
                       ind[2-i] = j;
                       max[2-i] = arr[j];
                   }
               }
               arr[ind[2-i]] = Int32.MinValue;
           }
           for (int i = 0; i < 3; i++) arr[ind[i]] = max[i];
           return max;
       }

p.s. в предыдущем была ошибка писал на скорую руку


 
homm ©   (2006-10-16 22:49) [18]


> Rwer   (16.10.06 16:28)


> Как решить такую простую задачку самым эффективным способом:



> [17] default ©   (16.10.06 22:45)


> for (int i = 0; i < 3; i++)
>            {
>                max[2-i] = arr[0];
>                ind[2-i] = 0;
>                for (int j = 1; j < arr.Length; j++) {
>                    if (arr[j] > max[2-i])
>                    {
>                        ind[2-i] = j;
>                        max[2-i] = arr[j];
>                    }
>                }
>                arr[ind[2-i]] = Int32.MinValue;
>            }


что-то мне не кажется что одно с другим карелирует.


 
default ©   (2006-10-16 23:10) [19]

homm ©   (16.10.06 22:49) [18]
найди способ эффективнее
если делять за один проход, то быстрее не будет только мороки больше


 
Sandman29 ©   (2006-10-17 09:15) [20]

default ©   (16.10.06 23:10) [19]

Если значение меньше третьего, то получится всего одно сравнение. То есть для трехпроходного метода K=3, а для третьего метода K чуть больше 1.


 
evvcom ©   (2006-10-17 10:51) [21]

var a,b,c,i: Integer;
begin
 a := -MaxInt;
 b := -MaxInt;
 c := -MaxInt;
 for i := 0 to High(Arr) do
   if Arr[i] > с then
     if Arr[i] > b then begin
       c := b;
       if Arr[i] > a then begin
         b := a;
         a := Arr[i];
       end
       else
         b := Arr[i];
     end
     else
       c := Arr[i];
end;

Ну плюс проверки разные, если охота. :)


 
default ©   (2006-10-17 13:00) [22]

Sandman29 ©   (17.10.06 09:15) [20]
да, таки побыстрее будет
я почему-то на сравнения только ориентировался(присваивания не брал)
а по сравнениям способ 2 чуть получше чем [21] в его худшем случае
поэтому я и подумал что игра не стоит свеч:)


 
TUser ©   (2006-10-17 13:03) [23]

> 2 способ вполне и вполне по крайней мере для немалых массивов я пути лучше не вижу

Опять же см. [7]. Там требуется один проход по массиву + n проходов по вспомогательному массиму длины 3.

Ну, впрочем, не нравится, - ходите три раза.


 
Jeer ©   (2006-10-17 13:54) [24]

default ©   (17.10.06 13:00) [22]

Способ [21] пасует только перед отсортированным в "нехорошем" порядке массивом.


 
default ©   (2006-10-17 13:59) [25]

Jeer ©   (17.10.06 13:54) [24]
да, для него такой массив не подарок
но он и при таком не пасует за счёт меньшего числа присваиваний


 
Jeer ©   (2006-10-17 14:04) [26]

Пасует перед стеком в простейшей его форме:

procedure Search_02;
var i: integer;
begin
for i := 0 to High(Arr) do begin
 if (Arr[i] > a) then begin
    c := b;
    b := a;
    a := Arr[i];
  end
 else
  if (Arr[i] > b) then begin
      c := b;
      b := Arr[i];
    end
  else
    if Arr[i] > c then c := Arr[i];
end;
end;



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

Форум: "Прочее";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.039 c
1-1159166924
aKirill.INFO
2006-09-25 10:48
2006.11.05
Формат фала msm и msi


11-1136123221
Аид
2006-01-01 16:47
2006.11.05
Контрол для чата


2-1161258865
Dr. Genius
2006-10-19 15:54
2006.11.05
Строковое $-представление числа


2-1161350547
Dib@zol
2006-10-20 17:22
2006.11.05
Ворох вопросов по API


15-1160935733
Palladin
2006-10-15 22:08
2006.11.05
Are you dead yet!?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский