Lógica: Pegar segundo menor valor

Delphi

29/05/2005

Ae galera, não tô conseguindo achar uma lógica bacana para pegar o segundo menor valor... de um array de inteiros, por exemplo.

Fiz um algoritimo usando 3 loops, mas não fiquei satisfeito!

Idéias?

Vamos exercitar a lógica! :)

Valew!!

Caninha51


Caninha51

Caninha51

Curtidas 0

Respostas

Marco Salles

Marco Salles

29/05/2005

Mais ou menos tente isto:
procedure TForm1.Button1Click(Sender: TObject);
var
 i,nunMaior,nunMenor:Integer;
begin
 i:=0;
 nunMaior:=0;
 while i<=tamanhodoarray do
   begin
     if A[i] > nunMaior then
       begin
         nunMenor:=nunMaior;
         nunMaior:=A[i]
       end
     else
       if A[i] > nunMenor Then
         nunMenor:= A[i];
     i:=i+1;
   end;
 Showmessage(inttostr(nunmenor));
end;



GOSTEI 0
Carlosrm

Carlosrm

29/05/2005

caninha51,

saúde!

procedure TForm1.Button1Click(Sender: TObject);
var
MeuArray : array[0..5] of integer;
pri, seg, I : Integer;
begin
// preenchi o array aqui só para facilitar a visualização
MeuArray[0] := 5;
MeuArray[1] := 9;
MeuArray[2] := -7;
MeuArray[3] := 3;
MeuArray[4] := -7;
MeuArray[5] := 6;

pri := MeuArray[0];
seg := MeuArray[0];
For I := Low(MeuArray) to High(MeuArray) do begin
if (MeuArray[I] < pri) then begin
if (pri < seg) then
seg := pri;
pri := MeuArray[I];
continue;
end;

if (MeuArray[I] < seg) and (MeuArray[I] <> pri) then
seg := MeuArray[I];
end;
showmessage(´O segundo menor número é: ´+inttostr(seg));
end;


1) Do jeito que está, este código considera apenas os conteúdos não repetidos dos items do array.
(5; 9; -7; 3; -7; 6) => o segundo menor número é 3. (O valor repetido -7 foi considerado uma vez.)

2) Para considerar inclusive os valores repetidos, basta remover (ou comentar) o trecho (no segundo IF) ´and (MeuArray[I] <> pri)´.
Neste caso, (5; 9; -7; 3; -7; 6) => o segundo menor número é -7

Espero ter ajudado.

carlosrm


GOSTEI 0
Caninha51

Caninha51

29/05/2005

Marco, o seu não funcionou de cara, o do Carlos sim, funcionou blz!

Agradeço aos dois! :o

Valew!

Caninha51


GOSTEI 0
Marco Salles

Marco Salles

29/05/2005

Marco, o seu não funcionou de cara


[b:d70e683368]O Código que lhe passei , não funciona nen de cara e nen sem Cara[/b:d70e683368]

:cry: :cry:
Na verdade cometi um Lapso , na interpretação Do enunciado:

uma lógica bacana para pegar o segundo menor valor


:arrow: Fiz uma lógica Para Pegar o Segundo Maior Valor :cry: :cry:

:lol: :lol:
Logo , para o código lhe atender , sera necessário somente umas Pequenas modificações no mesmo...

:wink: :wink: se por ventura ainda... estiver precisando , apesar deu achar que o Codigo que o amigo carlosrm lhe passou deve lhe [b:d70e683368]atender plenamente[/b:d70e683368] , e so postar,


GOSTEI 0
Caninha51

Caninha51

29/05/2005

Esquenta não Marco, o código do carlos já resolveu meu pró!

De qualquer forma valeu ae!

caninha51


GOSTEI 0
Carlosrm

Carlosrm

29/05/2005

Atenção, erro no código!

Peço desculpas aos amigos, mas o código que eu cometi não funciona em todas as situações. Erro do programador (nunca do programa!). Agradeço mais uma vez ao Marco Salles por ter me alertado. Assim que tiver consertado meu erro, posto novamente. Não foi por má intenção, foi por má dedução...

carlosrm :oops:


GOSTEI 0
Caninha51

Caninha51

29/05/2005

Quem disse que teu código naum funciona Carlos?

Aki funcionou sim! :)


GOSTEI 0
Marco Salles

Marco Salles

29/05/2005

Quem disse que teu código naum funciona Carlos? Aki funcionou sim!


Eu enviei uma Mp para o Carlosrm , igualmente o fiz para voce , levantando algumas situaçoes onde o cogido passado , tem um comportamneto diferente do sugerido ... Quem quiser que faça o teste com a seguinte inicialização do array

procedure TForm1.Button1Click(Sender: TObject); 
var 
MeuArray : array[0..5] of integer; 
pri, seg, I : Integer; 
begin 
// preenchi o array aqui só para facilitar a visualização 
MeuArray[0] := 33; 
MeuArray[1] := 79; 
MeuArray[2] := 41; 
MeuArray[3] := 80; 
MeuArray[4] := 55; 
MeuArray[5] := 77; 

pri := MeuArray[0]; 
seg := MeuArray[0]; 
For I := Low(MeuArray) to High(MeuArray) do begin 
if (MeuArray[I] < pri) then begin 
if (pri < seg) then 
seg := pri; 
pri := MeuArray[I]; 
continue; 
end; 

if (MeuArray[I] < seg) and (MeuArray[I] <> pri) then 
seg := MeuArray[I]; 
end; 
showmessage(´O segundo menor número é: ´+inttostr(seg)); 
end; 


[b:377549757a]To obtendo como resposta o 33 , Quando o correto seria o 41

O Que pode estar errado [/b:377549757a]

:?: :?: :?: :?:


GOSTEI 0
Caninha51

Caninha51

29/05/2005

É, realmente quando se preenche o array com esses valores ele retorna o 33 em vez do 41.

Fiz umas modificações e acho q agora deu certo!
Testa ai...

procedure TForm1.Button1Click(Sender: TObject);
var
MeuArray : array[0..5] of integer;
seg, menor, maior, I : Integer;
begin
// preenchi o array aqui só para facilitar a visualização
MeuArray[0] := 33;
MeuArray[1] := 79;
MeuArray[2] := 41;
MeuArray[3] := 80;
MeuArray[4] := 55;
MeuArray[5] := 77;

menor := MeuArray[0];
maior := MeuArray[0];

For I := Low(MeuArray) to High(MeuArray) do
  if (MeuArray[I] < menor) then
    menor := MeuArray[I]
  else
    if (MeuArray[I] > maior) then
      maior := MeuArray[I];

seg := maior;

For I := Low(MeuArray) to High(MeuArray) do
  if (MeuArray[I] > menor) and (MeuArray[I] < seg) then
    seg := MeuArray[I];

  showmessage(´O segundo menor número é: ´+inttostr(seg));

end;



GOSTEI 0
Carlosrm

Carlosrm

29/05/2005

Caninha51,

Salve! Eu tinha feito um código quase igual ao que vc fez, com pequena
diferença.
Provavelmente isso não acontece numa situação real, mas eu verifiquei também a possibilidade de todos os elementos do array serem iguais.
Fora isso, acabamos pensando mais ou menos igual. Desculpe, novamente pelo primeiro código estar furado (mal programado).
Agradeço também ao Marco Salles por ter testado e informado os furos encontrados.

carlosrm :)


procedure TForm1.Button1Click(Sender: TObject);
var
  MeuArray : array[0..5] of integer;
  pri, seg, H, I : Integer;
begin
  MeuArray[0] := 33; // 4  75;//
  MeuArray[1] := 33; // 9  9;//
  MeuArray[2] := 33; //-7  63;//
  MeuArray[3] := 33; // 3  57;//
  MeuArray[4] := 33; //-7  54;//
  MeuArray[5] := 33; // 6   6;//

//  listbox1.Clear;
//  for H := low(MeuArray) to High(MeuArray) do
//      listbox1.items.add(format(´¬3.3d´,[MeuArray[h]]));

  pri := MeuArray[0];
  seg := MeuArray[1];
  For I := Low(MeuArray)+2 to High(MeuArray) do begin
    if (MeuArray[I] = seg) or (MeuArray[I] = pri) then
       continue;

    if (MeuArray[I] < pri)  then begin
      if (pri < seg) then
         seg := pri;
      pri := MeuArray[I];
      continue;
    end;

    if (seg = pri) then
       seg := MeuArray[I];

    if (MeuArray[I] < seg)  then
        seg := MeuArray[I];
  end;

  if (pri = seg) then
     showmessage(´Todos os elementos do array são iguais: ´+inttostr(pri))
  else if (pri < seg) then
    showmessage(´O segundo menor número é: ´+inttostr(seg))
  else
    showmessage(´O segundo menor número é: ´+inttostr(pri));
end;



GOSTEI 0
Beppe

Beppe

29/05/2005

Elementos repetidos não estão sendo levados em conta, e acredito que o problema necessite deles. Por exemplo, o 2º menor elemento do array (31, 31, 33, 33, 33, 33) é 31. O código do carlosrm só trata os distintos, por isso retorna 33. Quem precisar da primeira solução, fiz este código:
// ensure Length(A) >= 2
function SegundoMenorInteiro(const A: array of Integer): Integer;
var
  I, Min, Sec: Integer;
begin
  Min := A[0];
  Sec := High(Integer);
  for I := 1 to High(A) do
    if A[I] < Sec then
    begin
      if A[I] <= Min then
      begin
        Sec := Min;
        Min := A[I];
      end
      else
        Sec := A[I];
    end;
  Result := Sec;
end;

Entretanto, o problema não está bem resolvido. E se for preciso o 3º, ou o 4º, ou ainda o 284473º menor elemento? Criar tantas variáveis conforme necessário!

Quem cursa CC sabe que este método se torna [i:538ee23f5c]O[/i:538ee23f5c](n²), o que significa lentidão. Resolver o problema primeiro ordenando o array é [i:538ee23f5c]O[/i:538ee23f5c](n lg n). Pra isso se usa a lógica de particionamento do QuickSort.

Claro que para o caso específico do colega que postou a questão, o algoritmo SegundoMenorInteiro dá conta do recado perfeitamente.


GOSTEI 0
Carlosrm

Carlosrm

29/05/2005

Beppe,

Valeu!. Obrigado pelos esclarecimentos.

carlosrm :)


GOSTEI 0
POSTAR