algorytm.org

Implementacja w Delphi/Pascal

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Ciąg Sturma - Implementacja w Delphi/Pascal
Ocena użytkownikóww: *****  / 2
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 08 sierpnia 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

sturm_d/Ciag.pas:
//www.algorytm.org
//Tomasz Lubiński (c)2001
//Algorytmy numeryczne - Ciąg Sturma
//Oblicza ilość miejsc zerowych wielomianu w danym przedziale

unit Ciag;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, Grids, Buttons, Math;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    StringGrid1: TStringGrid;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    BitBtn3: TBitBtn;
    Edit2: TEdit;
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label3: TLabel;
    Edit3: TEdit;
    Label4: TLabel;
    Label5: TLabel;
    Edit4: TEdit;
    Label8: TLabel;
    procedure Edit1Change(Sender: TObject);
    procedure w_lewo(Sender: TObject);
    procedure w_prawo(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  n: Integer;
  prawo: Integer=1;
  A,tmp1,tmp2: Array of real;
  CS: Array of Array of extended;  //tablica zawierająca kolejne wielomiany ciągu Sturma

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.ColCount:=1;
StringGrid1.RowCount:=2;
Edit1Change(Form1);
end;

//Zrobienie siatki i ustawienie tablic dynamicznych
procedure TForm1.Edit1Change(Sender: TObject);
var i:Integer;
begin
n:=StrToInt(Edit1.Text);
if n<1 then begin ShowMessage('Wielomian musi być conajmniej pierwszego stopnia'); exit; end;
StringGrid1.ColCount:=n+1;
SetLength(A, n+1);
SetLength(CS, n+1, n+1); //część tablicy będzie nie wykorzystana, ale to ułatwi zapis
for i:=0 to n+1 do StringGrid1.Cells[i,1]:='';
for i:=0 to n do StringGrid1.Cells[i,0]:='x^'+IntToStr(n-i);
end;

//Nawigacja
procedure TForm1.w_lewo(Sender: TObject);
begin
if prawo>0 then
 begin
 prawo:=prawo-1;
 StringGrid1.Col:=prawo;
 end;
end;
procedure TForm1.w_prawo(Sender: TObject);
begin
if prawo<n then
 begin
  prawo:=prawo+1;
  StringGrid1.Col:=prawo;
 end;
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
  prawo:=ACol;
end;

//wpis
procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
begin
Val(Edit2.Text,A[n-prawo],i);
if i<>0 then ShowMessage('Blad podczas wpisu') Else StringGrid1.Cells[prawo,1]:=Edit2.Text;
end;

procedure Dziel(i: Integer);
var a,b:Integer;
    tmp: Extended;
begin
SetLength(tmp1, n+3-i);
for a:=0 to n-i+2 do tmp1[a]:=CS[i-2,a];
for a:=0 to 1 do
 begin
  if CS[i-1,n-i+1]=0 then begin ShowMessage('Podany przez Ciebie wielomian ma wielokrotne miejsca zerowe'); exit; end;
  tmp:=tmp1[n-i+2-a]/CS[i-1,n-i+1];                                //odnalezienie ilorazu
  for b:=n-i+2-a downto 1-a do tmp1[b]:=tmp1[b]-tmp*CS[i-1,b-1+a]; //przemnożenie przez iloraz i dodanie do dzilonego wielomianu
 end;
for a:=0 to n-i+1 do CS[i,a]:=-(CS[i-1,n-i+1]*CS[i-1,n-i+1])*tmp1[a]; //Wpisanie wyniku do tablicy zawierającej ciąg Sturma po uprzednim przemnożeniu przez stałą mniejszą od zera
Finalize(tmp1);
end;

function w(k,i:Integer; x:Real):Real;  //algorytm Hornera - obliczanie wartości wielomianu
begin
if k=n then w:=CS[i,k] else w:=w(k+1,i,x)*x+CS[i,k]
end;

procedure TForm1.Button2Click(Sender: TObject);
var i,zm1,zm2: Integer;
    p,k: Real;
begin
Val(Edit3.Text,p,i);
if i<>0 then begin ShowMessage('Źle wpisany początek przedziału'); exit; end;
Val(Edit4.Text,k,i);
if i<>0 then begin ShowMessage('Źle wpisany koniec przedziału'); exit; end;
if k<p then begin ShowMessage('Koniec przedziału jest mniejszy od początku!'); exit; end;
for i:=0 to n do CS[0,i]:=A[i];           //P0(x)=p(x)
for i:=n downto 2 do CS[1,i-1]:=-A[i]*i;  //P1(x)=-p'(x)
CS[1,0]:=-A[1];
for i:=2 to n do Dziel(i);                //pozostałe
SetLength(tmp1, n+1);  zm1:=0;
SetLength(tmp2, n+1);  zm2:=0;
for i:=0 to n do tmp1[i]:=w(0,i,p);     //wartości c.Struma w początku przedziału
for i:=0 to n do tmp2[i]:=w(0,i,k);     //wartości c.Struma w końcu przedziału
for i:=0 to n-1 do if tmp1[i]*tmp1[i+1]<0 then zm1:=zm1+1; //liczba zmian znaku c.Struma w początku przedziału
for i:=0 to n-1 do if tmp2[i]*tmp2[i+1]<0 then zm2:=zm2+1; //liczba zmian znaku c.Struma w końcu przedziału
Label8.Caption:='Liczba zer wielomianu w przedziale <'+FloatToStr(p)+';'+FloatToStr(k)+') wynosi '+IntToStr(zm2-zm1);
end;
end.
Dodaj komentarz