Jak wyznaczyć drugi co do wielkości element z ciągu?

0
for(int i=0 ; i<n ; i++)
{
if(i!=maxi)
{i=tablica(i)
}
}
0

Nie wiem co podesłałeś, ale z całą pewnością nie jest to poprawny kod C++.

0

chyba zostaje mi się tylko poddanie dziękuję za pomoc

1

A nie wystarczy tak?

int find_2nd_largest( int[] tab, size_t size )
{
  int largest = 0, second = 1;
  for ( auto i = 0; i < size; ++i ) {
    if ( tab[ i ] > tab[ largest ] ) {
      second = largest;
      largest = i;
    }
  }
  return tab[ second ];
}

Edit: Poprawka:

int find_2nd_largest( int[] tab, size_t size )
{
  int largest = 0, second = 0;
  for ( auto i = 0; i < size; ++i ) {
    if ( tab[ i ] > tab[ largest ] ) {
      second = largest;
      largest = i;
    }
    else if ( tab[ i ] > tab[ second ] ) {
      second = i;
    }
  }
  return tab[ second ];
}
0
tajny_agent napisał(a):

A nie wystarczy tak?

int find_2nd_largest( int[] tab, size_t size )
{
  int largest = 0, second = 1;
  for ( auto i = 0; i < size; ++i ) {
    if ( tab[ i ] > tab[ largest ] ) {
      second = largest;
      largest = i;
    }
  }
  return tab[ second ];
}

nie. zly wynik bedzie np. dla {1, 3, 2}. moze sie wysypac np. dla {1}.

0

A może coś takiego? W pythonie "popełniłem" żeby za łatwo nie było:

def znajdz(tab):
    najw = tab[0]
    szuk = tab[0]
    for liczba in tab:
        if liczba > najw:
            szuk = najw
            najw = liczba
        else:
             if liczba > szuk:
                szuk = liczba
    return szuk

Zamiast tab można oczywiście wczytywać i porównywać od razu, bo w tym przypadku jest tylko jeden "przebieg". Więc tablica zbędna

0

Też w pythonie :-)

def second_max(arr):
    if len(arr) < 2:
        raise Exception('Array should have at least 2 elements to be eligible for finding second max')

    max1 = max(arr[0:2])
    max2 = min(arr[0:2])

    if max2 == max1:
        max2 = None

    for current in arr:
        if current > max1:
            old_max = max1
            max1 = current
            max2 = max(old_max, max2)
        elif current < max1:
            max2 = max(current if max2 is None else max2, current)

    return max2
0

Przebijam, przykład w Pascalu:

function SecondLargest(const AVector: array of Integer): Integer;
var
  Second: Integer absolute Result;
  Largest, Value: Integer;
begin
  Second := 0;
  Largest := 0;

  for Value in AVector do
    if Value > Largest then
    begin
      Second := Largest;
      Largest := Value;
    end
    else
      if Value > Second then
        Second := Value;
end;

https://ideone.com/DI8RgJ

Łatwo go przeportować na C++. ;)

0

To powinno rozwiązać problem

if liczba > szuk or szuk == najw:
0

czemu 2 wersja pythonowa czasami zwraca None a czasami rzuca wyjatkiem?
czemu wersja w pascalu czasami zwraca 0 mimo ze na wejsciu ma mnostwo (>2) unikalnych liczb roznych od 0?

0

Czemu zwraca none? nie mam pojęcia, daj tablicę która tak robi
A to wersja c++

#include <iostream>

using namespace std;

int main()
{
    int liczba = 0, ile = 0;
    cin >> ile;
    cin >> liczba;
    int najw = liczba, szuk = liczba;
    ile--;
    while (ile --)
    {
        cin >> liczba;
        if (liczba > najw)
		{
			szuk = najw;
			najw = liczba;
		}
		else if (liczba > szuk || szuk == najw) szuk = liczba;
    }
	cout << szuk;
    return 0;
}
0

Masz tu w C#

public int DrugaNajwieksza(int[] tab)
 => tab.Length == 0 ? throw new Exception("Empty array") : tab.Length == 1 ? tab[0] : tab.OrderByDescending(o => o).ToArray()[1];
0
Trzeźwy Kaczor napisał(a):

czemu 2 wersja pythonowa czasami zwraca None a czasami rzuca wyjatkiem?

Ja zinterpretowałem problem tak, że należy wyszukać drugi co do wielkości element z ciągu ;) np. 3,3,5,5 -> pierwszym co do wielkości jest 5, a drugim 3.

  1. Jak tablica ma mniej niż 2 elementy, to traktuję to jak sytuację nietypową (~ bez sensu szukać drugiego co do wielkości elementu w pustej tablicy, albo jednoelementowej tablicy)
  2. Jak elementy w tablicy są równe, to drugiego co do wielkości nie ma -> None
  3. 1,2,3,4,4,5,5 -> 4

Można też podejść do tego tak, że dla [1,2,3,4,4,5,5] -> 5, albo dla [1] -> [1], ale wtedy masz inną implementację. Wybierz sobie właściwą wersję :-)

0
Trzeźwy Kaczor napisał(a):

czemu wersja w pascalu czasami zwraca 0 mimo ze na wejsciu ma mnostwo (>2) unikalnych liczb roznych od 0?

Nie ma prawa zwracać 0, jeśli macierz wejściowa zawiera co najmniej dwie różne liczby większe od 0, tym bardziej „czasami” – to nie loteria. Ale podaj przykładowy zbiór (dla którego funkcja zwraca złą wartość), z chęcią sprawdzę pod IDE.

Przykład takiego wejścia masz na ideone (link w poprzednim poście) i wcale nie zwraca 0.


Przydałyby się też konkretne wymagania co do zwracanej liczby, bo nie wiadomo co funkcja ma zwrócić gdy:

  • wektor jest pusty,
  • wektor zawiera jedną liczbę,
  • wektor zawiera takie same liczby,
  • największa liczba występuje w wektorze więcej niż raz,
  • wszystko powyższe tyle że dla liczb ujemnych.

Będą konkrety to podam odpowiedni kod. ;)

1

Dobra, dałem się namówić :) Liniowy algorytm w Scali:

    val seq = Seq(3, 5, 3, 8)
    val secondMaxOpt = (List[Int]() /: seq)(_.:+(_).sortBy(-_).take(2)).lift(1)
    println(secondMaxOpt.fold("too few elements")(_.toString))

https://www.ideone.com/Euy0KS

Uwaga: to nie jest typowy kod Scalowy, nie ma się czego bać :)

0

Nie ma prawa zwracać 0, jeśli macierz wejściowa zawiera co najmniej dwie różne liczby większe od 0, tym bardziej „czasami” – to nie loteria. Ale podaj przykładowy zbiór (dla którego funkcja zwraca złą wartość), z chęcią sprawdzę pod IDE.

"czasami" czyli w zaleznosic od danych wejsciowych.
np. {-1, -2, -3}
moze cos pozniej przeoczylem ale w tresci w pierwszego postu nie widze ograniczenia na wartosci liczb, wiec naturalnym wydaje sie zalozenie ze 17 nie jest w niczym lepsze od -8.
natomiast brak specyfikacji dotyczacej co zwrocic jak nie ma 2 elementu jest to ewidentny bug popelniony przez autora zadania.

0

A no to trzeba było pisać, że dla liczb ujemnych. Za taki stan rzeczy odpowiada inicjalizacja zmiennych lokalnych:

Second := 0;
Largest := 0;

Wystarczy tu użyć liczby innej niż 0, np. umownie oznaczającej wartość niezdefiniowaną. Może to być najmniejsza wartość typu całkowitoliczbowego. Poprawiony kod niżej:

function SecondLargest(const AVector: array of Integer): Integer;
var
  Second: Integer absolute Result;
  Largest, Value: Integer;
begin
  Second := Low(Second);
  Largest := Low(Second);
 
  for Value in AVector do
    if Value > Largest then
    begin
      Second := Largest;
      Largest := Value;
    end
    else
      if Value > Second then
        Second := Value;
end;

https://ideone.com/ryRa61

Wartością określaną jako niezdefiniowana będzie Low(Integer), czyli -2147483648. Aby było czytelniej, można ją wydzielić do stałej i użyć do inicjalizacji lokalsów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1