Kritika programu - výroky – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kritika programu - výroky – Delphi – Fórum – Programujte.comKritika programu - výroky – Delphi – Fórum – Programujte.com

 

Danstahr0
Newbie
21. 11. 2007   #1
-
0
-

Ještě to není hotové, zatím je to hodně user-nonfriendly. A sry že tam nejsou komentáře :)

unit unita;


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;

type
TArr = array ['a'..'o',1..32768] of boolean;
TForm1 = class(TForm)
Button2: TButton;
Edit1: TEdit;
Memo1: TMemo;
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
function cistupis(i:longint):char;
function kulata(t:string):boolean;
function hranata(t:string):boolean;
function slozena(t:string):boolean;
function odzavorkuj(t:string):string;
procedure tokenizer;
function nenizav(t:string):boolean;
function konjunkce(a,b:boolean):boolean;
function disjunkce(a,b:boolean):boolean;
function implikace(a,b:boolean):boolean;
function ekvivalence(a,b:boolean):boolean;
function pocetpismen(t:string):longint;
procedure vyhodnotto;
function nmocnina(zaklad:longint;exponent:longint):longint;
function mistoznamenka(t:string):longint;
function strtobool(t:string):boolean;
public
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
function tform1.strtobool(t: string):boolean;
begin
if t='1' then result:=true else result:=false;
end;

function tform1.cistupis(i: longint):char;
begin
case i of
1:result:='a';
2:result:='b';
3:result:='c';
4:result:='d';
5:result:='e';
6:result:='f';
7:result:='g';
8:result:='h';
9:result:='i';
10:result:='j';
11:result:='k';
12:result:='l';
13:result:='m';
14:result:='n';
15:result:='o';
end;
end;

function tform1.nmocnina(zaklad: longint; exponent: longint):longint;
var i:longint;
begin
result:=zaklad;
for I := 2 to exponent do result:=result*zaklad;
end;

function tform1.kulata(t: string):boolean;
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='(' then result:=true;
end;

procedure TForm1.vyhodnotto;
var a,k,o,krok,x,pozice,i,komb:longint;
arr:Tarr;
b,vyrok1,vyrok2:boolean;
t,res:string;
c:char;
begin
a:=pocetpismen(Edit1.Text);
k:=nmocnina(2,a);
memo1.lines.add('--------Začíná vyhodnotto--------');
memo1.lines.add(inttostr(a));
memo1.lines.add(inttostr(k));
stringgrid1.colcount:=2+k;
stringgrid1.defaultcolwidth:=(stringgrid1.width-10) div stringgrid1.colcount;
for o := 1 to a do
begin
krok:=nmocnina(2,o-1);
if o=1 then krok:=1;
memo1.lines.add('krok' + inttostr(krok));
for x:=1 to k do if (((x-1)div krok)mod 2)=0 then
begin
arr[cistupis(o),x]:=true;
stringgrid2.cells[0,o-1]:=cistupis(o);
stringgrid2.cells[x,o-1]:='1';
end
else
begin
arr[cistupis(o),x]:=false;
stringgrid2.cells[0,o-1]:=cistupis(o);
stringgrid2.cells[x,o-1]:='0';
end;
end;
for komb := 1 to k do
begin
for x:=1 to stringgrid1.rowcount do
begin
res:='';
t:=stringgrid1.cells[1,x-1];
memo1.lines.add(t);
pozice:=mistoznamenka(t);
memo1.lines.add('pozice znamenka :' +inttostr(pozice));
if pozice=2 then
begin
c:=t[1];
memo1.lines.add('jednopísmenná proměnná ' +c);
vyrok1:=arr[c,komb];
if vyrok1=true then memo1.lines.add('!!!TRUE!!!');
end
else
begin
for i:=1 to pozice do if t[i]='"' then break;
i:=i+1;
while not (t[i]='"') do
begin
if t[i]<>'"' then res:=res+t[i];
i:=i+1;
end;
memo1.lines.add('výsledek :' +res);
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]
then break;
vyrok1:=strtobool(stringgrid1.Cells[1+komb,i-1]);
end;
res:='';
if length(t)=pozice+1 then
begin
c:=t[pozice+1];
memo1.lines.add('jednopísmenná proměnná2:'+c);
vyrok2:=arr[c,komb];
if vyrok1=true then memo1.lines.add('!!!TRUE!!!');
end
else
begin
for i:=pozice+1 to length(t) do if t[i]='"' then break;
i:=i+1;
while not (t[i]='"') do
begin
if t[i]<>'"' then res:=res+t[i];
i:=i+1;
end;
memo1.lines.add('výsledek2 :' +res);
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]
then break;
vyrok2:=strtobool(stringgrid1.Cells[1+komb,i-1]);
end;
case t[pozice] of
'&':b:=konjunkce(vyrok1,vyrok2);
'D':b:=disjunkce(vyrok1,vyrok2);
'I':b:=implikace(vyrok1,vyrok2);
'E':b:=ekvivalence(vyrok1,vyrok2);
end;
if b=true then stringgrid1.cells[1+komb,x-1]:='1';
if b=false then stringgrid1.Cells[1+komb,x-1]:='0';
end;
end;
end;

function tform1.mistoznamenka(t:string):longint;
var i:longint;
begin
for i:=1 to length(t) do if (t[i]='&') or (t[i]='D')
or (t[i]='I') or (t[i]='E') then
begin
result:=i;
exit;
end;
end;

function TForm1.konjunkce(a: Boolean; b: Boolean):boolean;
begin
if a and b then result:=true else result:=false;

end;

function TForm1.hranata(t: string):boolean;
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='[' then result:=true;
end;

function TForm1.slozena(t: string):boolean;
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='{' then result:=true;
end;





procedure TForm1.Button2Click(Sender: TObject);
begin
tokenizer;
vyhodnotto;
Button2.enabled:=false;
Button1.enabled:=true;
end;

function TForm1.disjunkce(a: Boolean; b: Boolean):boolean;
begin
if a or b then result:=true else result:=false;
end;

function TForm1.implikace(a: Boolean; b: Boolean):boolean;
begin
if (a=true) and (b=false) then result:=false else result:=true;
end;

function TForm1.ekvivalence(a: Boolean; b: Boolean):boolean;
begin
if a=b then result:=true else result:=false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.lines.Clear;
end;

function TForm1.pocetpismen(t:string):longint;
var c:char;
i,a:longint;
ar:array['a'..'z'] of boolean;
begin
t:=edit1.text;
a:=0;
for c:='a' to 'z' do ar[c]:=true;
for i:=1 to length(t) do
begin
for c := 'a' to 'z' do if t[i]=c then
begin
if ar[c]=true then
begin
ar[c]:=false;
a:=a+1;
end;
end;
end;
result:=a;
end;

function tform1.nenizav(t:string):boolean;
begin
result:=true;
if kulata(t) or hranata(t) or slozena(t) then result:=false;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
FullProgPath: PChar;
begin
FullProgPath := PChar(Application.ExeName);
WinExec(FullProgPath, SW_SHOW);
Application.Terminate;
end;

function tform1.odzavorkuj(t: string):string;
var i:longint;
puv,res:string;
begin
puv:=t;
result:='';
if hranata(t) then
begin
for I := 1 to length(t) do
begin
if (t[i]<>'[') and (t[i]<>']')then res:=res+t[i];
if t[i]='[' then res:=res+'(';
if t[i]=']' then res:=res+')';
end;
end;
t:=res;
if slozena(t) then
begin
res:='';
for I := 1 to length(t) do
begin
if (t[i]<>'{') and (t[i]<>'}')then res:=res+t[i];
if t[i]='{' then res:=res+'[';
if t[i]='}' then res:=res+']';
end;
end;
if kulata(puv)=true then result:=puv else result:=res;
memo1.lines.add(result);
end;

procedure tform1.tokenizer;
var t, res:string;
i,x,y,z:longint;
c:char;
nalezeno:boolean;
begin
z:=0;
t:=edit1.text;
repeat
begin
for i:=1 to length(t) do
begin
nalezeno:=false;
c:=t[i];
if c='(' then
begin
nalezeno:=true;
z:=z+1;
x:=i+1;
res:='';
c:='0';
while not (c=')') do
begin
c:=t[x];
if c<>')' then res:=res+c;
x:=x+1;
end;
end;
if nalezeno then break;
end;
if nalezeno then
begin
memo1.lines.add('VK' + inttostr(z) + ' : ' + res);
stringgrid1.cells[0,z-1]:='VK'+inttostr(z);
stringgrid1.cells[1,z-1]:=res;
stringgrid1.RowCount:=stringgrid1.RowCount+1;
res:='';
for y:=1 to i-1 do res:=res+t[y];
res:=res+ ('"VK' + inttostr(z)+'"');
for y:=x to length(t) do res:=res+t[y];
t:=res;
end;
memo1.lines.add(res);
if nenizav(t)=false then t:=odzavorkuj(t);
end
until nenizav(t)=true;
stringgrid1.cells[0,z]:='Result';
stringgrid1.cells[1,z]:=t;
end;

end.

Nahlásit jako SPAM
IP: 83.69.32.–
LiborBes
~ Anonymní uživatel
47 příspěvků
27. 11. 2007   #2
-
0
-

Chlape, ak by som nemenil zamestnávateľa a holka mi nechľastala na kamkovici, asi by som nerobil tento altruistický krok, ale nedá sa mi neodpovedať :) Ten tvoj kód je hrozný bordel! Neber to osobne. Keď som začínal v profy oblasti, tiež som tým prešiel a to som vyhrával celoštátne súťaže - šéf sa usmial so slovami "humus".

Takže:

1. Netuším ako to má fungovať, stále mi to hádže výnimky.
2. Netuším čo to má robiť, preto nehodnotím tvoj kód podľa logických častí (ako si ho rozdelil na metódy), ale len podotnem ku každému niečo - týmto chcem, aby si sa niečomu naučil, keďže predpokladám, že s programovaním začínaš:

Dobré rady:

1. Píš komentáre, aj keby to malo byť posledné, čo si v živote napísal.
2. Keď bacáš komponenty na form, snaž sa im dať relevantný názov s prefixom ich triedy, teda napr. ButtonOK, LabelOtazka, SplitterGrid apod. Rovnako aj pomenuvaj premenne, napr. namiesto I pouzivaj Index, namiesto Pom: TFormField zadaj FormField: TFormFiel, takto bude jednoduchšie čítať kód aj pri rozsiahlejších kódoch.
3. Ak pracuješ s metódami, zoradzuj ich podľa toho, ako si ich definoval v triede (prehliadnejšie a môžeš rýchlo chodiť po kóde klávesami CTRL+SHIT+šípka hore / dole):



type
TMojaTrieda = class
private
procedure Jeden;
procedure Dva;
protected
function Kuko: Boolean;
end; // TMojaTrieda

procedure TMojaTrieda.Jeden;
...
procedure TMojaTrieda.Dva;
...
function TMojaTrieda.Kuko: Boolean;
...


4. Boolové fcie sa dajú písať aj elegantnejšie:



function JePrvyZnakCislo(const Retazec: String): Boolean;
begin
Result := ((Length(Retazec) > 0) and (Retazec[1] in ['0'..'9'])); // Staci jeden riadok

{ NIE - i ked to nie je spatne
if (Length(Retazec) > 0) and (Retazec[1] in ['0'..'9']) then
Result := True
else
Result := False;
}
end;


5. Uvažuj keď kódiš! Skús rozmýšľat (netreba veľa rozumu a hneď poznať smernikovú aritmetiku, stačí logika) optimálne aj v cykloch, napr. tvoja haluz:



{ TVOJE:
result:=false;
for I := 1 to length(t) do if t[i]='{' then result:=true;
}
{
// pr. 1: Ukoncit po najdeni prvej zatvorky
Result := (Length(T) = 0);
if (not Result) then
begin
for Index := 1 to Length(Retazec) do
begin
if Retazec[Index] = '{' then
begin
Result := True;
Exit; // Ukonci FOR
end; // IF
end; // FOR
end; // IF
}

// Relevantnejsie riesenie
Result := (Pos('{', Retazec) > 0);


Prechádza sa celá dĺžka reťazca! Ak sa narazí na prvú zátvorku, výsledok fcie bude TRUE. Potom sa už nikde nemení na iný!!! Načo dôjsť do konca? A za ďalšie, hľadanie sub-reťazca je fcia známa už Turbo Pascalu (pr. 2)

6. Fcia odzátvrokuj je pekný bordel. Keďže si nedal komentár, dá sa len z kódu vyčítať čo robí:
- Prepíše všetky iné zátvorky za guľaté
- Zistí, či sa nachádzajú guľaté zátvorky ak nie vráti pôvodný reťazec.

Ak si to myslel takto, tak si mal najprv zistiť, či sa nachádzajú guľaté zátvorky a až potom, ak nie, odstráňovať tie druhé! Ak sa totiž v reťazci nenachádzajú, zbytočne sa odstránia, aj keď pre túto vetvu programu to nie je podstatné.

Ale i tak pochybujem, že tá fcia má robiť to, ako je napísaná... Skús naštudovať toto (fcia na prepísanie textu je z Delphi, nie je najrýchlejšia pri malých reťazcoch, ale skús si to s 1GB a budeš prekvapený :)



// *****************************************************************************
function TFormMain.Odzavorkuj(const Retazec: String): String;
// ---------------------------------------------------------------------------
procedure NahradZatvorky(var Vystup: String; const SadaZatvoriek: String;
const ZaZatvorku: Char);
var
Index: Integer;
begin
if Length(SadaZatvoriek) > 0 then
begin
for Index := 1 to Length(SadaZatvoriek) do
Vystup := AnsiReplaceText(Vystup, SadaZatvoriek[Index], ZaZatvorku);
end; // IF
end;
// ---------------------------------------------------------------------------
const
LaveZatvorky = '[{</';
PraveZatvorky = ']}>\';
begin
Result := Retazec;
NahradZatvorky(Result, LaveZatvorky, '('); // Nahradime lave zatvorky
NahradZatvorky(Result, PraveZatvorky, ')'); // Nahradime lave zatvorky
Memo1.Lines.Add(Result);
end;


7. V Delphi existuje fcia StrToBool, nemusíš ju písať.

8. Pri výpočte mocniny si nemyslel na všetky možnosti. Okrem toho, snaž sa aj argumenty prispôsobiť realite. Ak maš LONGINT^LONGINT, tak určite pri brutálnom čísle RESULT pretečie, preto sa to dá napísať aj napr. takto:



function TFormMain.NMocnina(const Zaklad: Integer; Exponent: Byte): Longint;
begin
if Exponent < 0 then
raise Exception.Create('Interná chyba: Záporný exponent!');

Result := 1;
if Exponent > 0 then
begin
while Exponent > 0 do
begin
Result := Result * Zaklad;
Dec(Exponent);
end; // WHILE
end; // IF
end;


9. Asi by som pokračoval, ale keďže ma volali na pivo, tak sa na to vybodnem :) Dúfam, že som ťa neodplašil - zapamätaj, kritika nie je zlá, len sa treba prekúsať svojim egom a ťažiť z nej. Mne to chvíľku trvalo, ale bola to tá najlepšia škola!

Nahlásit jako SPAM
IP: 88.212.20.–
Danstahr
~ Anonymní uživatel
17 příspěvků
30. 11. 2007   #3
-
0
-

jasně, chápu, řikám že je to zatím hodně user nonfriendly, z čehož plynou ty vyjímky, uživ. prostředí kompletně předělám ještě, tohle je jen kostra... má to určovat pravdivostní hodnotu výroků zadaných s logickými spojkami &,D,I,E (konjunkce, disjunkce, implikace, ekvivalence) a výroky a až o.

ke kritice :

1) komentáře - já tomu rozumím a to, že tam nejsou, jsem se omluvil, a dopíšu je tam až to bude komplet :)
2) a 3) jo, já vim že mám v kódu bordel :)
4) nevim na co narážíš
5) ten příkaz na hledání subřetězce jsem neznal, tak díky :) jo a přidat break snad neni problém :)
6) o té kulaté závorce vim, moje blbost, že nevim jak ukončit proceduru, nějak mi to zlobilo tak jsem to ošetřil vyjímkou na konci řetězce.

má to fungovat asi takhle :
pokud najde kulatou závorku, nedělej nic
pokud najde hranaté, předělej je na kulaté
pokud najde složené, přepiš je na hranaté

spoustu procedur v Delphi neznám, proto občas takovéhle řešení "nadlouho"...

7) další věc, o které jsem nevěděl...
8) jo vim, že tam mám chybu, ale tu už jsem opravil...



Nahlásit jako SPAM
IP: 83.69.32.–
Danstahr0
Newbie
30. 11. 2007   #4
-
0
-

Tak jsem trochu něco předělal a hlavně přidal komentáře, tak snad se v tom líp vyznáš :



unit unita;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;

type
TArr = array ['a'..'o',1..32768] of boolean;
TForm1 = class(TForm)
Button2: TButton;
Edit1: TEdit;
Memo1: TMemo;
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
function cistupis(i:longint):char;
function kulata(t:string):boolean;
function hranata(t:string):boolean;
function slozena(t:string):boolean;
function odzavorkuj(t:string):string;
procedure tokenizer;
function nenizav(t:string):boolean;
function konjunkce(a,b:boolean):boolean;
function disjunkce(a,b:boolean):boolean;
function implikace(a,b:boolean):boolean;
function ekvivalence(a,b:boolean):boolean;
function pocetpismen(t:string):longint;
procedure vyhodnotto;
function nmocnina(zaklad:longint;exponent:longint):longint;
function mistoznamenka(t:string):longint;
public
end;

var
Form1: TForm1;

implementation

function tform1.cistupis(i: longint):char;//jednoduše přiřadí dané číslici písmeno
begin
case i of
1:result:='a';
2:result:='b';
3:result:='c';
4:result:='d';
5:result:='e';
6:result:='f';
7:result:='g';
8:result:='h';
9:result:='i';
10:result:='j';
11:result:='k';
12:result:='l';
13:result:='m';
14:result:='n';
15:result:='o';
end;
end;

function tform1.kulata(t: string):boolean; //zjistí, zda je v řetězci kulatá závorka
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='(' then
begin
result:=true;
exit;
end;
end;

function TForm1.hranata(t: string):boolean; //zjistí, jestli je hranatá závorka
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='[' then
begin
result:=true;
exit;
end;
end;

function TForm1.slozena(t: string):boolean; //zjistí, zda je složená závorka
var i:longint;
begin
result:=false;
for I := 1 to length(t) do if t[i]='{' then
begin
result:=true;
exit;
end;
end;

function tform1.odzavorkuj(t: string):string; //převede všechny závorky o stupeň níž, pokud je v řetězci kulatá závorka, vrátí původní řetězec
var i:longint;
res:string;
begin
if kulata(t) then
begin
result:=t;
memo1.lines.add('Breakovano');
exit;
end;
result:='';
if hranata(t) then
begin
for I := 1 to length(t) do
begin
if (t[i]<>'[') and (t[i]<>']')then res:=res+t[i];
if t[i]='[' then res:=res+'(';
if t[i]=']' then res:=res+')';
end;
end;
t:=res;
if slozena(t) then
begin
res:='';
for I := 1 to length(t) do
begin
if (t[i]<>'{') and (t[i]<>'}')then res:=res+t[i];
if t[i]='{' then res:=res+'[';
if t[i]='}' then res:=res+']';
end;
end;
result:=res;
memo1.lines.add(result);
end;

procedure tform1.tokenizer;//celá procedura dělí řetězec do částí po závorkách - na konci je výstup bez závorek
var t, res:string;
i,x,y,z:longint;
c:char;
nalezeno:boolean;
begin
z:=0;//proměnná Z určuje celkový počet podvýroků
t:=edit1.text;
repeat
begin
for i:=1 to length(t) do //hledáme kulatou závorku
begin
nalezeno:=false; //standartně je nenalezena
c:=t[i];
if c='(' then //pokud to najde závorku, pak
begin
nalezeno:=true; //je nalezena
z:=z+1; //počet podvýroků se zvyšuje o 1
x:=i+1; //když i je pozice závorky, x je o 1 větší než pozice závorky - budeme začínat za závorkou
res:=''; //výsledek je nic, zatím...
while not (c=')') do //dokud nenajde konec závorky, tak
begin
c:=t[x]; //čti po znacích řetězec za závorkou
if c<>')' then res:=res+c; //a ukládej ho do proměnné res
x:=x+1;
end;
end;
if nalezeno then break; //a pokud nalezlo tak ukonči "hledací" cyklus
end;
if nalezeno then //a pokračuj tímto :
begin
memo1.lines.add('VK' + inttostr(z) + ' : ' + res); //jen kontrolní výpis do mema
stringgrid1.cells[0,z-1]:='VK'+inttostr(z);//do prvního sloupečku stringgridu zapiš VK a číslo výroku... výrazem VK se posléze nahradí závorka
stringgrid1.cells[1,z-1]:=res; //do druhého sloupečku StringGridu zapiš původní obsah závorky
stringgrid1.RowCount:=stringgrid1.RowCount+1;//přidej řádek do StringGridu
res:='';//vynuluj výstupní řetězec
for y:=1 to i-1 do res:=res+t[y];//všechno, co bylo před závorkou, zkopíruj do výstupu res
res:=res+ ('"VK' + inttostr(z)+'"');//místo závorky napiš "VKx", x je číslo podvýroku
for y:=x to length(t) do res:=res+t[y];//a zbytek opiš
t:=res;//a ulož upravený řetězec do var t, se kterou se pracuje...
end;
memo1.lines.add(res);//zas jen kontrola...
if nenizav(t)=false then t:=odzavorkuj(t);//pokud je v řetězci závorka tak proveď funkci odzavorkuj
end
until nenizav(t)=true;//a celé to opakuj dokud řetězec nebude bez závorek
stringgrid1.cells[0,z]:='Result';//a na poslední řádek do StringGridu připiš RESULT
stringgrid1.cells[1,z]:=t; //a to, co z původního řetězce zbylo
end;

function tform1.nenizav(t:string):boolean;//zjistí, jestli je v řetězci závorky
begin
result:=true;
if kulata(t) or hranata(t) or slozena(t) then result:=false;
end;

function TForm1.konjunkce(a: Boolean; b: Boolean):boolean; //logické operace...
begin
if a and b then result:=true else result:=false;
end;

function TForm1.disjunkce(a: Boolean; b: Boolean):boolean;
begin
if a or b then result:=true else result:=false;
end;

function TForm1.implikace(a: Boolean; b: Boolean):boolean;
begin
if (a=true) and (b=false) then result:=false else result:=true;
end;

function TForm1.ekvivalence(a: Boolean; b: Boolean):boolean;
begin
if a=b then result:=true else result:=false;
end;

function TForm1.pocetpismen(t:string):longint;//zjistí počet písmen v řetězci
var c:char;
i,a:longint;
ar:array['a'..'z'] of boolean;
begin
t:=edit1.text;
a:=0; //začátek - 0 písmen
for c:='a' to 'z' do ar[c]:=true; //zatím žádné písmeno nebylo nalezeno
for i:=1 to length(t) do //pro celý řetězec udělej
begin
for c := 'a' to 'z' do if t[i]=c then //otestuj to na každé písmeno
begin
if ar[c]=true then //pokud to písmeno ještě nebylo nalezeno pak
begin
ar[c]:=false;//to písmeno označ za nalezené
a:=a+1; //a přičti k počtu písmen 1
end;
break;//nemá smysl dál testovat
end;
end;
result:=a;//a jako výstupní hodnotu uveď a=počet písmen
end;

procedure TForm1.vyhodnotto;
var pismen,kombinaci,o,krok,x,pozice,i,komb:longint;
arr:Tarr;
b,vyrok1,vyrok2:boolean;
t,res:string;
c:char;
begin
pismen:=pocetpismen(Edit1.Text);//zjistíme počet písmen = počet výroků zadaných na začátku
kombinaci:=nmocnina(2,pismen); //počet kombinací je 2 na počet výroků
memo1.lines.add('--------Začíná vyhodnotto--------'); //kontrola do mema
memo1.lines.add(inttostr(pismen));
memo1.lines.add(inttostr(kombinaci));
stringgrid1.colcount:=2+kombinaci; //sloupečky jsou standartně 2 + počet kombinací, pro každou 1 sloupec
stringgrid1.defaultcolwidth:=(stringgrid1.width-10) div stringgrid1.colcount; //nastav šířku sloupců tak, aby se to vešlo
for o := 1 to pismen do //vyplní tabulku hodnot - a : 1010, b : 1100...
begin
krok:=nmocnina(2,o-1);//krok - určuje, po kolika vyplněných polích se střídá 1 a 0, např. pro krok 2 bude řetězec 1100...
memo1.lines.add('krok' + inttostr(krok)); //kontrola
for x:=1 to kombinaci do if (((x-1)div krok)mod 2)=0 then
{tohle se mi moc líbí - funguje to takhle :

pokud x celočíselně dělím krokem, dostanu vždy řadu číslic za sebou, číslice se změní právě po
počtu číslic, které udává krok. Např. pro krok=4 a pro x=1-16 dostanu 0001111222233334.
protože se mi však nehodí to, že začínám pouze třemi a ne 4 číslicemi. proto od x odečtu 1.
pak už dostanu x z intervalu 0-15 a řetězec bude vypadat 0000111122223333. Pokud tyto čísla zbytkově
dělím dvěma, pak výsledkem celé operace nahoře je 0000111100001111. Jelikož se ale většinou začíná
jedničkou a ne nulou, proto pro nulu nastavuji true a pro 1 false.}
begin
arr[cistupis(o),x]:=true;//příslušné políčko bool pole true
stringgrid2.cells[0,o-1]:=cistupis(o);//a zapiš do 2. stringgridu proměnnou
stringgrid2.cells[x,o-1]:='1'; //a její hodnotu
end
else
begin
arr[cistupis(o),x]:=false; //totéž, akorát s fasle
stringgrid2.cells[0,o-1]:=cistupis(o);
stringgrid2.cells[x,o-1]:='0';
end;
end;
for komb := 1 to kombinaci do //pro každou z kombinací proveď
begin
for x:=1 to stringgrid1.rowcount do //pro všechny sloupce SG proveď
begin
res:='';
t:=stringgrid1.cells[1,x-1]; //načte do t řetězec ze SG - výrok
memo1.lines.add(t); //kontrola
pozice:=mistoznamenka(t); //zjistíme polohu logické spojky v řetězci
memo1.lines.add('pozice znamenka :' +inttostr(pozice));//kontrola
if pozice=2 then//pokud je pozice znaménka 2, pak to znamená, že před
begin//znaménkem se nachází pouze jednopísmenná proměnná, kterou je třeba hledat v původní tabulce jednoduchých výroků
c:=t[1];//tak si zjistíme, co je to za výrok
memo1.lines.add('jednopísmenná proměnná ' +c);//ověření
vyrok1:=arr[c,komb];//najdeme si v poli pravd. hodnotu pro příslušnou kombinaci
if vyrok1=true then memo1.lines.add('!!!TRUE!!!'); //zkouška
end
else //jinak to znamená, že se před tím nachází nějaký výrok typu "VKx"
begin
for i:=1 to pozice do if t[i]='"' then break;//až najdeš uvozovky, ukonči hledání
i:=i+1;//nastaví pozici za uvozovkami
while not (t[i]='"') do //dokud nenajdeš další uvozovky, tak
begin
if t[i]<>'"' then res:=res+t[i]; //do res zapisuj to, co je mezi nimi
i:=i+1;
end;
memo1.lines.add('výsledek :' +res); //zkouška
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]//a hledej to, co je mezi uvozovkami ve SG...
then break;//pokud najdeš, ukonči hledání
vyrok1:=strtobool(stringgrid1.Cells[1+komb,i-1]);//ve SG je uspořádáno následovně : název výroku (VK2) vyjádření výroku pomocí předem známých
//"VK1"Db a pak hodnoty pro dané kombinace (1 nebo 0), tuhle hodnotu si vezme
end;
res:='';
if length(t)=pozice+1 then //to samé co před spojkou provede s částí za spojkou
begin
c:=t[pozice+1];
memo1.lines.add('jednopísmenná proměnná2:'+c);
vyrok2:=arr[c,komb];
if vyrok1=true then memo1.lines.add('!!!TRUE!!!');
end
else
begin
for i:=pozice+1 to length(t) do if t[i]='"' then break;
i:=i+1;
while not (t[i]='"') do
begin
if t[i]<>'"' then res:=res+t[i];
i:=i+1;
end;
memo1.lines.add('výsledek2 :' +res);
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]
then break;
vyrok2:=strtobool(stringgrid1.Cells[1+komb,i-1]);
end;
case t[pozice] of //a pošle to na vyhodnocení do podprocedury
'&':b:=konjunkce(vyrok1,vyrok2);
'D':b:=disjunkce(vyrok1,vyrok2);
'I':b:=implikace(vyrok1,vyrok2);
'E':b:=ekvivalence(vyrok1,vyrok2);
end;
if b=true then stringgrid1.cells[1+komb,x-1]:='1'; //a zapíše do SG
if b=false then stringgrid1.Cells[1+komb,x-1]:='0';
end;
end;
end;

function tform1.nmocnina(zaklad: longint; exponent: longint):longint; //vrátí entou mocninu čísla, pro moje potřeby to takhle naprosto stačí...
var i:longint;
begin
result:=1;
for I := 1 to exponent do result:=result*zaklad;
end;

function tform1.mistoznamenka(t:string):longint; //určí pozici log. spojky
var i:longint;
begin
for i:=1 to length(t) do if (t[i]='&') or (t[i]='D')
or (t[i]='I') or (t[i]='E') then
begin
result:=i;
exit;
end;
end;

procedure TForm1.Button2Click(Sender: TObject); //spouštěcí čudlík
begin
tokenizer;
vyhodnotto;
Button2.enabled:=false;
Button1.enabled:=true;
end;

procedure TForm1.FormCreate(Sender: TObject); //vymaže memo při startu
begin
memo1.lines.Clear;
end;

procedure TForm1.Button1Click(Sender: TObject); //restart programu
var
FullProgPath: PChar;
begin
FullProgPath := PChar(Application.ExeName);
WinExec(FullProgPath, SW_SHOW);
Application.Terminate;
end;

end.


Nahlásit jako SPAM
IP: 83.69.32.–
LiborBes
~ Anonymní uživatel
47 příspěvků
1. 12. 2007   #5
-
0
-

Jasné, už viem čo to robí!!! Klobúk dole, že ti to ako tak chodí a vôbec, že si sa do toho dal!!! Ale :)

0. Som rád, že si to usporiadal :)
1. To zisťovanie, či sa nachádza XYZ zátvorka urob cez ten POS.
2. Snaž sa dodržiavať veľké a malé písmená, podľa toho, ako majú byť (ako sú fcie definované apod.). To docielíš jednoducho, že nebudeš písať celý reťazec, ale len zadáš napr. prvé tri písmená, stlačíš CTRL+Medzerník a máš zoznam vyhovujúcich možností. Ak vyberieš z neho, zmení sa ti aj písmo. Keď sa to naučíš používať, celkom šikovne sa dá písať kód.
3. Memo nemaš co FormCreate, ale v design-time móde komponenty. Vieš, čo nemusíš, nepchaj do kódu, aby to bolo prehliadnejšie.
4. Keď už vieme, čo má robiť odvzátvorkuj, tak využi tú fciu na prepísanie textu:



// *****************************************************************************
// Pøevede všechny závorky o stupeò níž, pokud je v øetìzci kulatá závorka, vrátí
// pùvodní øetìzec
function TForm1.Odzavorkuj(Retazec: String): String;
begin
Result := Retazec;
if Kulata(Retazec) then
Memo1.Lines.Add('Breakovano')
else
begin
// Nezistujeme, ci sa nachadza, tak ci tak by sa presiel aspon raz linearne
// vstupny retazec
Result := AnsiReplaceText(Retazec, '[', '(');
Result := AnsiReplaceText(Retazec, ']', ')');
Result := AnsiReplaceText(Retazec, '{', '[');
Result := AnsiReplaceText(Retazec, '}', ']');
Memo1.Lines.Add(Result);
end; // ELSE
end;


5. Neviem kto ťa učí matiku, ale choď mu poriadne vynadať. Rôzne druhy zátvoriek sa nemajú používať na označovanie "stupňa vnorenia". Každý typ, má svoj význam (tak ako v Delphi). Mal by si rátať len s guľatými zátvorkami.

6. Využívaj konštanty. Napr. som presne nevedel, že horná definícia TArr s horným extrémom (ó) koreluje s CisTuPis. Ak zmeniš na jednom mieste, musíš pamätať, kde všade. Kód sa preto zvykne písať dosť obecne, ak by niekto do toho pozeral (či už z týmu, alebo ako Open-Source) a nevedel, ako to presne funguje, zmenena definície, aby sa aplikovala aj v kóde.

Ale tiež sa dá zistiť písmeno jednoduchšie cez ASCII poradie (tam ale samozrejme "A" nie je na prvom mieste, takže treba odratávať v tabuľke):



// *****************************************************************************
// jednoduše pøiøadí dané èíslici písmeno
function TForm1.CisTuPis(const Poradie: Byte): Char;
begin
// ---> Vratime podla ordinalneho cisla - existuje nieco ako zakladna ASCII
// tabulka, tak preco nevyuzit uz nieco, co existuje, ze? Poziciu znaku
// zistime napr. takto: ShowMessage(IntToStr(Ord('a'))); - vysledok je 97
// CHR zasa z cisla vrati znak, teda ShowMessage(Chr(97));
if Poradie in [1..15] then
Result := Chr(Poradie + Pred(97))
else
raise Exception.Create('Interna chyba: Neocakavam znak s index vacsim ako 15!'); // Osetrime extremy
end;

Nahlásit jako SPAM
IP: 88.212.20.–
Danstahr0
Newbie
1. 12. 2007   #6
-
0
-

0) ti chci poděkovat, že se se mnou vůbec zabýváš :))
1) předěláno + upravený Tokenizer (na zbytek kódu nebyl čas) :) fakt moc díky za ty tipy na jeden řádek řikám když něco nevim (v prvotní fázi, když si to pak rozebírám ke konci, už to třeba vygooglim :) ) , tak se to místo googlení snažim vyřešit tim, co vim. Sice se nenaučim nový příkazy , ale snažim si rozvíjet logický myšlení tim, že přemejšlim jak to vyřešit pomocí toho co vim.
2) nevím, jaký má konkrétně tohle význam, ale budiž...
3) jo, už jsem si všimnul že ten podělanej text Memo1 je ve v Object Inspectoru ve Strings :)
4) předěláno
5) nevim, jsem v prváku na střední a jen dělám to co umim, vždycky byla kulatá - hranatá - složená...
6) hmm... dobře no s těmi konstantami...

a ta fce cistupis je náramně zajímavá, díky za tip... předpokládám, že slovíčko "in" znamená "z intervalu"... akorát nechápu kousíček Chr(Poradie + Pred(97)) - co je to to pred?

trochu bordelu nakonec :

unit unita;


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls,StrUtils;
const
maxvyrok='o';

type
TArr = array ['a'..maxvyrok,1..32768] of boolean;
TForm1 = class(TForm)
Go: TButton;
Edit1: TEdit;
Memo1: TMemo;
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Restart: TButton;
procedure RestartClick(Sender: TObject);
procedure GoClick(Sender: TObject);
private
function cistupis(i:longint):char;
function kulata(t:string):boolean;
function hranata(t:string):boolean;
function slozena(t:string):boolean;
function odzavorkuj(t:string):string;
procedure tokenizer;
function nenizav(t:string):boolean;
function konjunkce(a,b:boolean):boolean;
function disjunkce(a,b:boolean):boolean;
function implikace(a,b:boolean):boolean;
function ekvivalence(a,b:boolean):boolean;
function pocetpismen(t:string):longint;
procedure vyhodnotto;
function nmocnina(zaklad:longint;exponent:longint):longint;
function mistoznamenka(t:string):longint;
public
end;



var
Form1: TForm1;

implementation
{$R *.dfm}

function tform1.cistupis(i: longint):char;//jednoduše přiřadí dané číslici písmeno
begin
Result := Chr(i + 96)
end;

function tform1.kulata(t: string):boolean; //zjistí, zda je v řetězci kulatá závorka
begin
result:=(Pos('(', t) > 0)
end;

function tform1.hranata(t: string):boolean; //zjistí, zda je v řetězci hranatá závorka
begin
result:=(Pos('[', t) > 0)
end;

function TForm1.slozena(t: string):boolean;
begin
result:=(Pos('{',t)>0);
end;

function tform1.odzavorkuj(t: string):string; //převede všechny závorky o stupeň níž, pokud je v řetězci kulatá závorka, vrátí původní řetězec
begin
if kulata(t) then result:=t
else
begin
t := AnsiReplaceText(t, '[', '(');
t := AnsiReplaceText(t, ']', ')');
t := AnsiReplaceText(t, '{', '[');
t := AnsiReplaceText(t, '}', ']');
result:=t;
end;
end;

procedure tform1.tokenizer;//celá procedura dělí řetězec do částí po závorkách - na konci je výstup bez závorek
var t, res:string;
i,x,y,z:longint;
c:char;
nalezeno:boolean;
begin
z:=0;//proměnná Z určuje celkový počet podvýroků
t:=edit1.text;
repeat
begin
if kulata (t) then
begin
res:='';
z:=z+1;
i:=pos('(',t);//najdeme první kulatou závorku;
x:=pos(')',t);//v řetězci najdeme konečnou závorku
stringgrid1.cells[0,z-1]:='VK'+inttostr(z);//do prvního sloupečku stringgridu zapiš VK a číslo výroku... výrazem VK se posléze nahradí závorka
for y := i+1 to x-1 do res:=res+t[y];
stringgrid1.cells[1,z-1]:=res; //do druhého sloupečku StringGridu zapiš původní obsah závorky
stringgrid1.RowCount:=stringgrid1.RowCount+1;//přidej řádek do StringGridu
res:='';
for y:=1 to i-1 do res:=res+t[y];//všechno, co bylo před závorkou, zkopíruj do výstupu res
res:=res+ ('"VK' + inttostr(z)+'"');//místo závorky napiš "VKx", x je číslo podvýroku
for y:=x+1 to length(t) do res:=res+t[y];//a zbytek opiš
t:=res;//a ulož upravený řetězec do var t, se kterou se pracuje...
end;
if nenizav(t)=false then t:=odzavorkuj(t);//pokud je v řetězci závorka tak proveď funkci odzavorkuj
end
until nenizav(t)=true;//a celé to opakuj dokud řetězec nebude bez závorek
stringgrid1.cells[0,z]:='Result';//a na poslední řádek do StringGridu připiš RESULT
stringgrid1.cells[1,z]:=t; //a to, co z původního řetězce zbylo
showmessage('');
end;

function tform1.nenizav(t:string):boolean;//zjistí, jestli je v řetězci závorky
begin
result:=true;
if kulata(t) or hranata(t) or slozena(t) then result:=false;
end;

function TForm1.konjunkce(a: Boolean; b: Boolean):boolean; //logické operace...
begin
if a and b then result:=true else result:=false;
end;

function TForm1.disjunkce(a: Boolean; b: Boolean):boolean;
begin
if a or b then result:=true else result:=false;
end;

function TForm1.implikace(a: Boolean; b: Boolean):boolean;
begin
if (a=true) and (b=false) then result:=false else result:=true;
end;

function TForm1.ekvivalence(a: Boolean; b: Boolean):boolean;
begin
if a=b then result:=true else result:=false;
end;

procedure TForm1.GoClick(Sender: TObject);
begin
tokenizer;
vyhodnotto;
Go.Enabled:=false;
Restart.Enabled:=true;
end;

function TForm1.pocetpismen(t:string):longint;//zjistí počet písmen v řetězci
var c:char;
i,a:longint;
ar:array['a'..'z'] of boolean;
begin
t:=Edit1.text;
a:=0; //začátek - 0 písmen
for c:='a' to 'z' do ar[c]:=true; //zatím žádné písmeno nebylo nalezeno
for i:=1 to length(t) do //pro celý řetězec udělej
begin
for c := 'a' to 'z' do if t[i]=c then //otestuj to na každé písmeno
begin
if ar[c]=true then //pokud to písmeno ještě nebylo nalezeno pak
begin
ar[c]:=false;//to písmeno označ za nalezené
a:=a+1; //a přičti k počtu písmen 1
end;
break;//nemá smysl dál testovat
end;
end;
result:=a;//a jako výstupní hodnotu uveď a=počet písmen
end;

procedure TForm1.RestartClick(Sender: TObject);
var FullProgPath: PChar;
begin
FullProgPath := PChar(Application.ExeName);
WinExec(FullProgPath, SW_SHOW);
Application.Terminate;
end;

procedure TForm1.vyhodnotto;
var pismen,kombinaci,o,krok,x,pozice,i,komb:longint;
arr:Tarr;
b,vyrok1,vyrok2:boolean;
t,res:string;
c:char;
begin
pismen:=pocetpismen(Edit1.Text);//zjistíme počet písmen = počet výroků zadaných na začátku
kombinaci:=nmocnina(2,pismen); //počet kombinací je 2 na počet výroků
memo1.lines.add('--------Začíná vyhodnotto--------'); //kontrola do mema
memo1.lines.add(inttostr(pismen));
memo1.lines.add(inttostr(kombinaci));
stringgrid1.colcount:=2+kombinaci; //sloupečky jsou standartně 2 + počet kombinací, pro každou 1 sloupec
stringgrid1.defaultcolwidth:=(stringgrid1.width-10) div stringgrid1.colcount; //nastav šířku sloupců tak, aby se to vešlo
for o := 1 to pismen do //vyplní tabulku hodnot - a : 1010, b : 1100...
begin
krok:=nmocnina(2,o-1);//krok - určuje, po kolika vyplněných polích se střídá 1 a 0, např. pro krok 2 bude řetězec 1100...
memo1.lines.add('krok' + inttostr(krok)); //kontrola
for x:=1 to kombinaci do if (((x-1)div krok)mod 2)=0 then
{tohle se mi moc líbí - funguje to takhle :

pokud x celočíselně dělím krokem, dostanu vždy řadu číslic za sebou, číslice se změní právě po
počtu číslic, které udává krok. Např. pro krok=4 a pro x=1-16 dostanu 0001111222233334.
protože se mi však nehodí to, že začínám pouze třemi a ne 4 číslicemi. proto od x odečtu 1.
pak už dostanu x z intervalu 0-15 a řetězec bude vypadat 0000111122223333. Pokud tyto čísla zbytkově
dělím dvěma, pak výsledkem celé operace nahoře je 0000111100001111. Jelikož se ale většinou začíná
jedničkou a ne nulou, proto pro nulu nastavuji true a pro 1 false.}
begin
arr[cistupis(o),x]:=true;//příslušné políčko bool pole true
stringgrid2.cells[0,o-1]:=cistupis(o);//a zapiš do 2. stringgridu proměnnou
stringgrid2.cells[x,o-1]:='1'; //a její hodnotu
end
else
begin
arr[cistupis(o),x]:=false; //totéž, akorát s fasle
stringgrid2.cells[0,o-1]:=cistupis(o);
stringgrid2.cells[x,o-1]:='0';
end;
end;
for komb := 1 to kombinaci do //pro každou z kombinací proveď
begin
for x:=1 to stringgrid1.rowcount do //pro všechny sloupce SG proveď
begin
res:='';
t:=stringgrid1.cells[1,x-1]; //načte do t řetězec ze SG - výrok
memo1.lines.add(t); //kontrola
pozice:=mistoznamenka(t); //zjistíme polohu logické spojky v řetězci
memo1.lines.add('pozice znamenka :' +inttostr(pozice));//kontrola
if pozice=2 then//pokud je pozice znaménka 2, pak to znamená, že před
begin//znaménkem se nachází pouze jednopísmenná proměnná, kterou je třeba hledat v původní tabulce jednoduchých výroků
c:=t[1];//tak si zjistíme, co je to za výrok
memo1.lines.add('jednopísmenná proměnná ' +c);//ověření
vyrok1:=arr[c,komb];//najdeme si v poli pravd. hodnotu pro příslušnou kombinaci
if vyrok1=true then memo1.lines.add('!!!TRUE!!!'); //zkouška
end
else //jinak to znamená, že se před tím nachází nějaký výrok typu "VKx"
begin
for i:=1 to pozice do if t[i]='"' then break;//až najdeš uvozovky, ukonči hledání
i:=i+1;//nastaví pozici za uvozovkami
while not (t[i]='"') do //dokud nenajdeš další uvozovky, tak
begin
if t[i]<>'"' then res:=res+t[i]; //do res zapisuj to, co je mezi nimi
i:=i+1;
end;
memo1.lines.add('výsledek :' +res); //zkouška
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]//a hledej to, co je mezi uvozovkami ve SG...
then break;//pokud najdeš, ukonči hledání
vyrok1:=strtobool(stringgrid1.Cells[1+komb,i-1]);//ve SG je uspořádáno následovně : název výroku (VK2) vyjádření výroku pomocí předem známých
//"VK1"Db a pak hodnoty pro dané kombinace (1 nebo 0), tuhle hodnotu si vezme
end;
res:='';
if length(t)=pozice+1 then //to samé co před spojkou provede s částí za spojkou
begin
c:=t[pozice+1];
memo1.lines.add('jednopísmenná proměnná2:'+c);
vyrok2:=arr[c,komb];
if vyrok1=true then memo1.lines.add('!!!TRUE!!!');
end
else
begin
for i:=pozice+1 to length(t) do if t[i]='"' then break;
i:=i+1;
while not (t[i]='"') do
begin
if t[i]<>'"' then res:=res+t[i];
i:=i+1;
end;
memo1.lines.add('výsledek2 :' +res);
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]
then break;
vyrok2:=strtobool(stringgrid1.Cells[1+komb,i-1]);
end;
case t[pozice] of //a pošle to na vyhodnocení do podprocedury
'&':b:=konjunkce(vyrok1,vyrok2);
'D':b:=disjunkce(vyrok1,vyrok2);
'I':b:=implikace(vyrok1,vyrok2);
'E':b:=ekvivalence(vyrok1,vyrok2);
end;
if b=true then stringgrid1.cells[1+komb,x-1]:='1'; //a zapíše do SG
if b=false then stringgrid1.Cells[1+komb,x-1]:='0';
end;
end;
end;

function tform1.nmocnina(zaklad: longint; exponent: longint):longint; //vrátí entou mocninu čísla, pro moje potřeby to takhle naprosto stačí...
var i:longint;
begin
result:=1;
for I := 1 to exponent do result:=result*zaklad;
end;

function tform1.mistoznamenka(t:string):longint; //určí pozici log. spojky
var i:longint;
begin
for i:=1 to length(t) do if (t[i]='&') or (t[i]='D')
or (t[i]='I') or (t[i]='E') then
begin
result:=i;
exit;
end;
end;
end.



Nahlásit jako SPAM
IP: 83.69.32.–
LiborBes
~ Anonymní uživatel
47 příspěvků
2. 12. 2007   #7
-
0
-

Hm, už to vyzerá lepšie :), kód sa zmenšil a je prehliadnejší. Ešte sa nauč lepšie pomenúvať premenné. Potom nemusíš napr. komentovať a je to lepšie čitateľné!

SUC a POS sú fcie ekvivalentné so zápisom X + 1 a X - 1. Nič extra to nerobí. Používaj ako chceš, ja som si zvykol používať PRED napr. pri prechádzaní cyklov po "COUNT-1" a odvtedy to používam všade :)

Ináč, ešte jeden "tip", existuje fcia COPY, ktorá ti podreťazec od Indexu po počet znakov a teda nemusíš cyklom vyskladávať nový reťazec:



var
Index: Integer;
Vystup: String;
...
Index := Succ(Pos('(', Vystup)); // Zistime, kde sa nachadza zatvorka
ShowMessage(Copy(Vystup, Index, Pos(')', Vystup) - Index));


Tiež by si mal pred spracovaním reťazec naformátovať. Zabúdaš na také veci, ako sú napr. prázdne znaky, nekorektné znaky apod. Ak chceš v reťazci ponechať len konkrétne znaky, vstup najprv preformatuj cez niečo také:



Vstup := Uppercase(Vstup); // Co ak sa pouziju male / velke pismena?
for Index := Length(Vstup) downto 1 do
begin
if (not (Vstup[Index] in ['(', ')', '[', ']', '{', '}', 'a'..KONSTANTA, 'D', 'I', 'E', '&'])) then
Delete(Vstup, Index, 1); // Odstranime kazdy znak, ktory ta nepatri
end; // FOR


Čo sa týka dodržiavania veľkých a malých písmen, kód je prehliadnejší a takéto detailky hovoria o programátorovi, že už nemá problém so samotným kódením, ide mu o "krásu" :) Svojim spôsobom je programátor umelec...

A prečo pomáham? Keby mne niekto v prváku takto pomohol, bol by som úplne inde už v 18tke. Lenže okolo mňa nikto nekódil :( Síce som povyhrával nejaké súťaže aj na úrovni celoštátnych kôl, ale to programovanie bolo skôr "akademické". Keď sa dostaneš do nejakej firmy, potom uvidíš také zázraky, o ktorých sa nesníva ani cvičiacim na VŠ!

BTW: Odporúčam naštudovať OOP (zmení tvoj pohľad na programovanie) a prejsť si knihy ako Algoritmy od pána Wroblevskeho (Computer Press). Keď sa naučíš myslieť "optimálne" a anlyticky, spoznáš pojmy teória grafov apod. (čo sa dá samoštúdiom do roka nadupať), tak odporúčam súťaže - popri nich sa veľa naučíš a s týmito vedomosťami položíš aj porodcov (väčšinou hovno rozumejú programovaniu). Mňa nikto neodkázal na žiadne "grafy" a tak som somár tri mesiace hľadal optimálne riešenie na nájdenie najkratšej cesty v bludisku. Keď som sám vytvoril algoritmus (dosť humus), tak som si myslel, že by som mal dostať nobelovku. Po súťaži mi prišlo vyhodnotenie, len polka bodov za príklad - hoci riešenie bolo. Prečo???? Bol som naštavatý, a odpoveď bola: "Lebo prehľadávanie grafov do hĺbky sa dá napísať aj lepším spôsobom". Vtedy som prvý krát počul pojem graf (matematický) a zistil som, že na nič svetoborné som neprišiel, len som vymyslel to, čo už existovalo. Ak by som o tom vedel, tri mesiace som mohol riešiť iné veci :(

Držím palce v ďalšej tvorbe.

Nahlásit jako SPAM
IP: 88.212.20.–
Danstahr0
Newbie
8. 12. 2007   #8
-
0
-

Tak jsem si s tím ještě trošku pohrál, snad je to poznat... ;) Formátování vstupu tam není, protože k tomu bude GUI které si to bude hlídat samo...

unit unita;


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls,StrUtils;
const
maxvyrok='o';

type
TArr = array ['a'..maxvyrok,1..32768{2 na cistupis(maxvyrok)}] of boolean;
TForm1 = class(TForm)
Go: TButton;
Edit1: TEdit;
Memo1: TMemo;
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Restart: TButton;
procedure RestartClick(Sender: TObject);
procedure GoClick(Sender: TObject);
private
function cistupis(i:longint):char;
function kulata(t:string):boolean;
function hranata(t:string):boolean;
function slozena(t:string):boolean;
function odzavorkuj(t:string):string;
procedure tokenizer;
function nenizav(t:string):boolean;
function konjunkce(a,b:boolean):boolean;
function disjunkce(a,b:boolean):boolean;
function implikace(a,b:boolean):boolean;
function ekvivalence(a,b:boolean):boolean;
function pocetpismen(t:string):longint;
procedure vyhodnotto;
function nmocnina(zaklad:longint;exponent:longint):longint;
function mistoznamenka(t:string):longint;
public
end;

var
Form1: TForm1;

implementation
{$R *.dfm}

function tform1.cistupis(i: longint):char;//jednoduše přiřadí dané číslici písmeno
begin
Result := Chr(i + 96)
end;

function tform1.kulata(t: string):boolean; //zjistí, zda je v řetězci kulatá závorka
begin
result:=(Pos('(', t) > 0)
end;

function tform1.hranata(t: string):boolean; //zjistí, zda je v řetězci hranatá závorka
begin
result:=(Pos('[', t) > 0)
end;

function TForm1.slozena(t: string):boolean;
begin
result:=(Pos('{',t)>0);
end;

function tform1.odzavorkuj(t: string):string; //převede všechny závorky o stupeň níž, pokud je v řetězci kulatá závorka, vrátí původní řetězec
begin
if kulata(t) then result:=t
else
begin
if slozena(t) and not hranata(t) then //ušetří se celý cyklus tím, že rovnou složená ->kulatá
begin //oproti složená -> hranatá -> kulatá
t := AnsiReplaceText(t, '{', '(');
t := AnsiReplaceText(t, '}', ')');
end
else
begin
t := AnsiReplaceText(t, '[', '(');
t := AnsiReplaceText(t, ']', ')');
t := AnsiReplaceText(t, '{', '[');
t := AnsiReplaceText(t, '}', ']');
end;
result:=t;
end;
end;

procedure tform1.tokenizer;//celá procedura dělí řetězec do částí po závorkách - na konci je výstup bez závorek
var t, res:string;
i,x,z:longint;
begin
z:=0;//proměnná Z určuje celkový počet podvýroků
t:=edit1.text;
repeat
begin
if kulata (t) then
begin
z:=z+1;
i:=pos('(',t);//najdeme první kulatou závorku;
x:=pos(')',t);//v řetězci najdeme konečnou závorku
stringgrid1.cells[0,z-1]:='VK'+inttostr(z);//do prvního sloupečku stringgridu zapiš VK a číslo výroku... výrazem VK se posléze nahradí závorka
res:=copy(t,i+1,x-i-1);//zjistí obsah závorky;
stringgrid1.cells[1,z-1]:=res; //do druhého sloupečku StringGridu zapiš původní obsah závorky
stringgrid1.RowCount:=stringgrid1.RowCount+1;//přidej řádek do StringGridu
res:=copy(t,1,i-1);//zjistí co je před závorkou
res:=res+('"VK' + inttostr(z)+'"');//místo závorky napiš "VKx", x je číslo podvýroku
res:=res+copy(t,x+1,length(t));;//a zbytek opiš
t:=res;//a ulož upravený řetězec do var t, se kterou se pracuje...
end;
if nenizav(t)=false then t:=odzavorkuj(t);//pokud je v řetězci závorka tak proveď funkci odzavorkuj
end
until nenizav(t)=true;//a celé to opakuj dokud řetězec nebude bez závorek
stringgrid1.cells[0,z]:='Result';//a na poslední řádek do StringGridu připiš RESULT
stringgrid1.cells[1,z]:=t; //a to, co z původního řetězce zbylo
end;

function tform1.nenizav(t:string):boolean;//zjistí, jestli je v řetězci závorky
begin
result:=true;
if kulata(t) or hranata(t) or slozena(t) then result:=false;
end;

function TForm1.konjunkce(a: Boolean; b: Boolean):boolean; //logické operace...
begin
if a and b then result:=true else result:=false;
end;

function TForm1.disjunkce(a: Boolean; b: Boolean):boolean;
begin
if a or b then result:=true else result:=false;
end;

function TForm1.implikace(a: Boolean; b: Boolean):boolean;
begin
if (a=true) and (b=false) then result:=false else result:=true;
end;

function TForm1.ekvivalence(a: Boolean; b: Boolean):boolean;
begin
if a=b then result:=true else result:=false;
end;

procedure TForm1.GoClick(Sender: TObject);
begin
tokenizer;
vyhodnotto;
Go.Enabled:=false;
Restart.Enabled:=true;
end;

function TForm1.pocetpismen(t:string):longint;//zjistí počet písmen v řetězci
var c:char;
i,a:longint;
ar:array['a'..maxvyrok] of boolean;
begin
t:=Edit1.text;
a:=0; //začátek - 0 písmen
for c:='a' to maxvyrok do ar[c]:=true; //zatím žádné písmeno nebylo nalezeno
for i:=1 to length(t) do if (t[i] in ['a'..maxvyrok]) then//pro celý řetězec udělej
begin
if ar[t[i]]=true then //pokud to písmeno ještě nebylo nalezeno pak
begin
ar[t[i]]:=false;//to písmeno označ za nalezené
a:=a+1; //a přičti k počtu písmen 1
end;
end;
result:=a;//a jako výstupní hodnotu uveď a=počet písmen
end;

procedure TForm1.RestartClick(Sender: TObject);
var FullProgPath: PChar;
begin
FullProgPath := PChar(Application.ExeName);
WinExec(FullProgPath, SW_SHOW);
Application.Terminate;
end;

procedure TForm1.vyhodnotto;
var pismen,kombinaci,o,krok,x,pozice,i,komb,subr:longint;
arr:Tarr;
b,vyrok1,vyrok2:boolean;
t,res:string;
c:char;
begin
pismen:=pocetpismen(Edit1.Text);//zjistíme počet písmen = počet výroků zadaných na začátku
kombinaci:=nmocnina(2,pismen); //počet kombinací je 2 na počet výroků
stringgrid1.colcount:=2+kombinaci; //sloupečky jsou standartně 2 + počet kombinací, pro každou 1 sloupec
stringgrid1.defaultcolwidth:=(stringgrid1.width-10) div stringgrid1.colcount; //nastav šířku sloupců tak, aby se to vešlo
for o := 1 to pismen do //vyplní tabulku hodnot - a : 1010, b : 1100...
begin
krok:=nmocnina(2,o-1);//krok - určuje, po kolika vyplněných polích se střídá 1 a 0, např. pro krok 2 bude řetězec 1100...
for x:=1 to kombinaci do if (((x-1)div krok)mod 2)=0 then
{tohle se mi moc líbí - funguje to takhle :

pokud x celočíselně dělím krokem, dostanu vždy řadu číslic za sebou, číslice se změní právě po
počtu číslic, které udává krok. Např. pro krok=4 a pro x=1-16 dostanu 0001111222233334.
protože se mi však nehodí to, že začínám pouze třemi a ne 4 číslicemi. proto od x odečtu 1.
pak už dostanu x z intervalu 0-15 a řetězec bude vypadat 0000111122223333. Pokud tyto čísla zbytkově
dělím dvěma, pak výsledkem celé operace nahoře je 0000111100001111. Jelikož se ale většinou začíná
jedničkou a ne nulou, proto pro nulu nastavuji true a pro 1 false.}
begin
arr[cistupis(o),x]:=true;//příslušné políčko bool pole true
stringgrid2.cells[0,o-1]:=cistupis(o);//a zapiš do 2. stringgridu proměnnou
stringgrid2.cells[x,o-1]:='1'; //a její hodnotu
end
else
begin
arr[cistupis(o),x]:=false; //totéž, akorát s fasle
stringgrid2.cells[0,o-1]:=cistupis(o);
stringgrid2.cells[x,o-1]:='0';
end;
end;
for komb := 1 to kombinaci do //pro každou z kombinací proveď
begin
for x:=1 to stringgrid1.rowcount do //pro všechny sloupce SG proveď
begin
t:=stringgrid1.cells[1,x-1]; //načte do t řetězec ze SG - výrok
pozice:=mistoznamenka(t); //zjistíme polohu logické spojky v řetězci
if pozice=2 then//pokud je pozice znaménka 2, pak to znamená, že před
begin//znaménkem se nachází pouze jednopísmenná proměnná, kterou je třeba hledat v původní tabulce jednoduchých výroků
c:=t[1];//tak si zjistíme, co je to za výrok
vyrok1:=arr[c,komb];//najdeme si v poli pravd. hodnotu pro příslušnou kombinaci
end
else //jinak to znamená, že se před tím nachází nějaký výrok typu "VKx"
begin
i:=pos('"',t);//poloha prvních uvozovek
subr:=pos('"',copy(t,i+1,pozice-i-1))-1;//určíme délku textu mezi uvozovkami
res:=copy(t,i+1,subr);//do res uložíme to, co je mezi uvozovkami
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]//a hledej to, co je mezi uvozovkami ve SG...
then begin
vyrok1:=strtobool(stringgrid1.Cells[1+komb,i-1]);
break;
end;
end;
if length(t)=pozice+1 then //to samé co před spojkou provede s částí za spojkou
begin
c:=t[pozice+1];
vyrok2:=arr[c,komb];
end
else
begin
i:=pos('"',copy(t,pozice+1,length(t)-pozice-2))+pozice;
subr:=pos('"',copy(t,i+1,length(t)-i))-1;
res:=copy(t,i+1,subr);
for i := 1 to stringgrid1.rowcount do if res=stringgrid1.Cells[0,i-1]
then begin
vyrok2:=strtobool(stringgrid1.Cells[1+komb,i-1]);
break;
end;
end;
case t[pozice] of //a pošle to na vyhodnocení do podprocedury
'&':b:=konjunkce(vyrok1,vyrok2);
'D':b:=disjunkce(vyrok1,vyrok2);
'I':b:=implikace(vyrok1,vyrok2);
'E':b:=ekvivalence(vyrok1,vyrok2);
end;
if b then stringgrid1.cells[1+komb,x-1]:='1' else stringgrid1.Cells[1+komb,x-1]:='0'; //a zapíše do SG
end;
end;
end;

function tform1.nmocnina(zaklad: longint; exponent: longint):longint; //vrátí entou mocninu čísla, pro moje potřeby to takhle naprosto stačí...
var i:longint;
begin
result:=1;
for I := 1 to exponent do result:=result*zaklad;
end;

function tform1.mistoznamenka(t:string):longint; //určí pozici log. spojky
var i:longint;
begin
for i:=1 to length(t) do if t[i] in ['&','I','E','D'] then
begin
result:=i;
exit;
end;
end;
end.

Nahlásit jako SPAM
IP: 83.69.32.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 4 hosté

Podobná vlákna

Kritika programu (kodu) — založil marpit

Gastromania.cz - kritika — založil gastropastor

Kritika webu - 2R.sk — založil Michal93

Kritika webu - 8R.sk — založil zelenac1

Kritika banneru — založil plasmo

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý