Sortowanie poprzez scalanie.

0

Mam oto takie zadanie do wykonania :
Wczytaj z klawiatury długość tablicy (N) i N liczb całkowitych do tablicy.

Następnie wczytaj z klawiatury liczbę K. Dla danej liczby K wypisz 3 różne liczby "bezpośrednio" mniejsze od niej (od największej). Gdy nie ma takich liczb, wypisz stosowny komunikat. Powtarzaj operacje związane z liczbą K aż K=0 (dla którego też wykonaj wyszukiwanie).

Liczby "bezpośrednio" mniejsze, są to liczby, dla których nie istnieje liczba większa, która jest mniejsza od liczby K i nie jest w tym zbiorze.

Przykład:

N = 7
T = 1 2 3 3 5 6 7

K = 6
5 3 2

K = 4
3 2 1

K = 3
2 1

K = 0
brak

Jestem poczatkujacym jesli chodzi o programowanie, wiec licze z waszej strony na wyrozumialosc. Ponizej przedstawiam Wam kod jaki dotychczas udalo mi sie wklepac:

program merge_sort;
	uses crt;
//Wstepna deklaracja.
var	N:integer;
	T,A:array [1..100] of integer;
	i:integer;
	K:integer;
//START: Procedura wczytania liczby N.
	procedure wczytaj(var N:integer);
	begin
		write('Podaj liczbe N: ');
		read(N);
		writeln('N = ',N);
		writeln('Podaj ', N, ' liczb(y) do tablicy: ');
		for i:=1 to N do 
			begin
				T[N]:=i;
				write('Podaj liczbe ',i,': ');
				read(T[i]);
			end;
	end;
//KONIEC.

//START: Procedura wczytania liczby K.
	procedure wczytaj1 (var K:integer);
		begin
			write('Podaj liczbe K: ');
			readln(K);
			writeln('K = ', K);
		end;
//KONIEC.

//START: Procedura jesli K=0.
		procedure warunek(var K:integer);
			begin
				if K=0 then 
					begin
						writeln('Brak.');
					end;
			end;
//KONIEC.

//START: Procedura sortujaca.
		procedure MergeSort(poczatek,koniec : integer);
				var srodek,i1,i2,i : integer;
					begin
								srodek := (poczatek + koniec + 1) div 2;
							if srodek - poczatek > 1 then MergeSort(poczatek, srodek - 1);
							if koniec - srodek > 0 then MergeSort(srodek, koniec);
								i1 := poczatek; 
								i2 := srodek;
							for i := poczatek to koniec do
							if (i1 = srodek) or ((i2 <= koniec) and (A[i1] > A[i2])) then
					begin
							T[i] := A[i2];
							inc(i2);
					end
					else
					begin
							T[i] := A[i1];
							inc(i1);
					end;
							for i := poczatek to koniec do A[i] := T[i];
					end;
//KONIEC.

//START: Procedura liczb bezposrednio mniejszych.
		procedure mniejsze (var K:integer);
			begin
				if A[i]<K then
					begin
						for i:=K downto 1 do write(A[i],' ');
					end;
			end;
//KONIEC.

//PROGRAM GLOWNY.
	begin
		wczytaj(N);
//Wypisujemy T=...
	write(' T = '); 
	for i := 1 to N do 
	begin 
			A[i]:=T[i];
	end;
  for i := 1 to N do write(A[i],' ');
					 writeln;
//Sortujemy.
		MergeSort(1,N);
//Wynik sortowania.
		write('Posortowane liczby wpisane z tablicy: ');
		for i := 1 to N do write(A[i],' '); 
		writeln;
//Petla do K.
	repeat
		wczytaj1(K);
		warunek(K);
		mniejsze(K);
	until K=0;
	end.
//KONIEC PROGRAMU. 

Zrobilem tu dodatkowo sort przez scalanie, gdyz chcialem pozniej wypisac liczby bezposrednio mniejsze od K. Ma wypisywac to tak jak podano w przykladzie zadania. Jednak po dlugich rozmyslaniach doszedlem do wniosku, ze nie mam pojecia jak dalej z tym ruszyc. Moglbym liczyc na jakas podpowiedz z Waszej strony? Z gory dzieki za wszystkie pozytywne komentarze. (Mam nadzieje, ze za bardzo mnie tu nie zwyzywacie, ale staram sie czegos nauczyc).

0

Nie bardzo wiem czy dobrze zrozumiałem treść zadania, ale jeżeli tak to ten kod poniżej powinien być w miarę OK. Wiadomo, ze pewnie da się inaczej. Ja z matematyki i algorytmów jestem słaby, bo nigdy się tego dostatecznie dużo nie uczyłem. Z matmy byłem, jestem i pozostanę "nogą". Anyway, chyba źle podałeś przykład zamiast K = 4, powinno być chyba K = 5. I raz piszesz, że liczby mają być w jakimś zbiorze, przez co chyba rozumiesz tę tablicę. A później, że liczba ma nie być w tym zbiorze, to jakim cudem podałeś przykład dla liczby 5, która w tej przykładowej tablicy już jest dopisana. A i w kodzie możesz zmodyfikować wartość stałej Manual_Input i kiedy wynosi ona True - wprowadzasz liczby ręcznie do tablicy, tak jak chciałeś. A jeżeli ta zmienna wynosi False, to na szybko masz wypełnioną tablicę, jak w Twoim przykładzie. Twojego kodu nie analizowałem, bo jest nie czytelny i wstaiowny w zbyt ogółny tag. Następnym razem formatuj go po ludzku używając choćby JEDI Code Formater. Nie będę tego poprawiał za Ciebie, bo się tak ludzie nauczyli. A to dać formatowanie z "d**y". A to brak prawidłowych tagów itp. Zadanie zrobiłem i wkleiłem kod, bo mnie zaciekawiło czy dam radę. Jeżeli nie o to chodziło to sprecyzuj moze ciut dokładniej przykłady. Wtedy ktoś bardziej doświadczony ode mnie na pewno Tobie pomoże z tym problemem.

program zales69;

{$APPTYPE CONSOLE}

const
  Manual_Input = False;

function IsNumberInArray(Arr : array of integer; Number : integer) : boolean;
var
  I : integer;
  Res : boolean;
begin
  Res := False;
  for I := High(Arr) downto Low(Arr) do
  begin
    Res := Arr[I] = Number;
    if Res then
    begin
      Break;
    end;
  end;
  IsNumberInArray := Res;
end;

const
  Max_Count = 3;
var
  S : string;
  DigitsArr : array of integer;
  I, N, K, Cnt, Code : integer;
begin
  if Manual_Input then
  begin
    repeat
      Write('Podaj N: ');
      Readln(S);
      Val(S, N, Code);
    until (Code = 0) and (N > 0);
    SetLength(DigitsArr, N);
    for I := Low(DigitsArr) to High(DigitsArr) do
    begin
      repeat
        Write('Podaj liczbe ', I + 1, ' z ', N, ': ');
        Readln(S);
        Val(S, DigitsArr[I], Code);
      until (Code = 0) and (DigitsArr[I] > 0);
    end;
  end
  else
  begin
    N := 7;
    SetLength(DigitsArr, N);
    DigitsArr[0] := 1;
    DigitsArr[1] := 2;
    DigitsArr[2] := 3;
    DigitsArr[3] := 3;
    DigitsArr[4] := 5;
    DigitsArr[5] := 6;
    DigitsArr[6] := 7;
  end;
  Writeln('N = ', N);
  Write('T = ');
  for I := Low(DigitsArr) to High(DigitsArr) do
  begin
    if I < N then
    begin
      Write(DigitsArr[I], ' ')
    end
    else
    begin
      Write(DigitsArr[I]);
    end;
  end;
  Writeln;
  repeat
    Write('Podaj K: ');
    Readln(S);
    Val(S, K, Code);
  until (Code = 0) and (K > -1);
  repeat
    Cnt := 0;
    for I := K downto 0 do
    begin
      if Cnt < Max_Count then
      begin
        if (K = 0)
          or ((I < K) and (IsNumberInArray(DigitsArr, I)) and (IsNumberInArray(DigitsArr, K))) then
        begin
          if Cnt = 0 then
          begin
            writeln;
            writeln('K = ', K);
          end;
          if K = 0 then
          begin
            Writeln('Brak');
          end
          else
          begin
            if (Cnt < Max_Count - 1) and (K > 2) then
            begin
              Write(I, ' ');
            end
            else
            begin
              Write(I);
            end;
            Cnt := Cnt + 1;
          end;
        end;
      end;
    end;
    K := K - 1;
  until K < 0;
  Readln;
end.
0

@zales69, z kodu który podałeś widać, że procedura Mniejsze nie robi tego, co powinna i dlatego wynik jest niepoprawny. Do reszty kodu, a zwłaszcza jego formatowania, też można by mieć zastrzeżenia, ale mniejsza o to.

Moja wersja tej procedury:

procedure Mniejsze(K: Integer);
var i, Ile, Temp: Integer;
begin
  Ile:= 0;
  Temp:= K;
  Write('Liczby mniejsze od ', K, ': ');
  for i:= N downto 1 do begin
    if (A[i] < Temp) and (Ile < 3) then begin
      Write(A[i], ' ');
      Temp:= A[i];
      Inc(Ile);
    end;
  end;
  if Ile = 0 then Writeln('Brak')
  else Writeln;
end;

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