最近比较烦,关于链表和计算表达式! (200分)

  • 主题发起人 主题发起人 SuperJS
  • 开始时间 开始时间
S

SuperJS

Unregistered / Unconfirmed
GUEST, unregistred user!
第一个问题:
我有一个记录型的List,在每次新建的时候都需要new这个List,然后把他放到TList中去,
但是如果我要修改某过List中的值,我还要new一个List,然后再把指针付过来,感觉这样
好象不太对,最后Dispose的时候也要先new,然后再把指针付过来,一个一个的Dispose。
如:
代码:
type 
 PType=^mType;
 mType = Record
       iCur:integer;
       sCon:string;
 end;
var 
  mList:TList;
  CfgCom:PType;
.............
begin
 mList:=TList.Create;
//添加
 New(CfgCom);
 CfgCom^.iCur:=1;
 CfgCom^.sCon:='abc';

 mList.add(CfgCom);
 //Dispose(CfgCom) 这一句如果不加注释的话,大家都知道是什么后果了!
//修改
 New(CfgCom);
 CfgCom:=mList.Items[0];
 CfgCom^.iCur:=2;
 CfgCom^.sCon:='cba';
 //mList.Items[0]:=CfgCom 这里一块如果不赋值回去的话,
 //CfgCom就不能Dispose否则就没有值了,赋值回去如果Dispose的话也有问题!
 //内容会乱了,谁能帮我解释一下
//删除
 for iCur:=0 to mList.Count-1 do
       begin
          //New(CfgCom)
这里如果不加New的话也会有问题
          CfgCom:=mList.Items[iCur];
          Dispose(CfgCom);
       end;
       mList.clear;
       FreeAndNil(mList);
end;
[red]谁能告诉我一个比较完整的关于链表的添加,删除,修改的操作啊!
帮助中的我试了一下好像有问题![/red]
第二个问题:
谁能告诉我如何计算表达式啊!我查过以前的帖子回答也没有解决!
举例如:
我有3个文本框txtA,txtB,txtC其中txtA和txtB 让用户输入值,
在txtC中输入由txtA,txtB组成的表达式。可能是txtA+txtB或txtA*txtB/2等
注意表达式的运算规则由用户输入!请问又何办法解决吗?
期待高手中......
 
运算表达式找SParser这个控件,看看别人如何作的
 
to 郭玉梁:
先谢了,我看了一下这个SParser控件,他只是分析pas文件,而不是得到运行的结果。
我需要的是“用户输入表达式运算后的值”
 
看看这几个帖子吧,都是有关资源动态建立、动态释放的,希望对你有所帮助
http://www.delphibbs.com/delphibbs/dispq.asp?lid=330289
http://www.delphibbs.com/delphibbs/dispq.asp?lid=321838
http://www.delphibbs.com/delphibbs/dispq.asp?lid=99609
http://www.delphibbs.com/delphibbs/dispq.asp?lid=338813
 
http://www.2001soft.com/cal/
 
先谢了,那位再说说[red]第一个问题[/red]
 
//修改
New(CfgCom)
//这里有问题,你把原来的指针丢了
CfgCom:=mList.Items[0];
CfgCom^.iCur:=2;
CfgCom^.sCon:='cba';
//mList.Items[0]:=CfgCom 这里一块如果不赋值回去的话,
//CfgCom就不能Dispose否则就没有值了,赋值回去如果Dispose的话也有问题!
//内容会乱了,谁能帮我解释一下

修改为:
oldCfgCom := mList.Items[0]
//先删除
Dispose(oldCfgCom);
New(CfgCom)
//再创建
CfgCom^.iCur:=2;
CfgCom^.sCon:='cba';
mList.Items[0]:=CfgCom;
 
谢谢tseug!
再请问一下,除了TList和数组以外还有什么比较好的可以解决这个问题的方法吗?
个人感觉TList用着不太放心,内存是不是没有释放啊!
再者,第一次创建后如何保留这个指针呢!
最后,如果我用数组有什么方法可以比较快速的删除其中的一个元素呢!
 
如果没有复杂的操作,我一般自己写链表

PType=^mType;
mType = Record
iCur:integer;
sCon:string;
next:PType
//增加的,指向下一个
end;

var
head : PType
//链表头
tail : PType
//链表尾
 
To tseug!
能按你自己写的链表举一个完整的例子吗?
谢谢
 
好吧,不过现在手头有工作,等晚上贴上来吧。
 
谢谢!期待中......
 
代码:
type 
 PType=^mType;
 mType = Record
       iCur:integer;
       sCon:string;
 end;
var 
  mList:TList;
  CfgCom:PType;
.............
begin
 mList:=TList.Create;
//添加
 New(CfgCom);
 CfgCom^.iCur:=1;
 CfgCom^.sCon:='abc';

 mList.add(CfgCom);
 //Dispose(CfgCom) 这一句如果不加注释的话,大家都知道是什么后果了!

[b]正确![/b]


 //修改 
  New(CfgCom);
  CfgCom:=mList.Items[0];
  CfgCom^.iCur:=2;
  CfgCom^.sCon:='cba';
  //mList.Items[0]:=CfgCom 这里一块如果不赋值回去的话,
  //CfgCom就不能Dispose否则就没有值了,赋值回去如果Dispose的话也有问题!
  //内容会乱了,谁能帮我解释一下

[b]
 CfgCom:=mList.Items[0];
 CfgCom^.iCur:=2;
 CfgCom^.sCon:='cba';
 即可,不用new也不用dispose
[/b]


//删除
 for iCur:=0 to mList.Count-1 do
       begin
          //New(CfgCom)
这里如果不加New的话也会有问题
          CfgCom:=mList.Items[iCur];
          Dispose(CfgCom);
       end;
       mList.clear;
       FreeAndNil(mList);
end;



while mlist.count>=1 do
begin
dispose(ptype(mlist.items[0]));
mlist.delete(0);


其实用指针不一定要新申请内存,也可以把它指向已申请的内存。

仔细体会一下。
 
临时写的代码,没有经过严格测试。

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
uses unit2;
{$R *.dfm}
var
l : TMyList;
procedure output;
var
i : integer;
begin
form1.Memo1.Clear;
for i := 1 to l.Length do
begin
form1.Memo1.Lines.Add(l.Items(i))
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
l := TMyList.Create;
output
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
l.Free;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
i : integer;
begin
for i := 1 to 10 do
l.Append(IntToStr(i));
output
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
if l.IndexOf('5') > 0 then ShowMessage('Found');
output
end;


procedure TForm1.Button5Click(Sender: TObject);
begin
l.Modify(l.IndexOf('10'), 'hello');
if l.IndexOf('hello') > 0 then ShowMessage('OK');
output
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
l.Insert(3, 'world');
if l.IndexOf('world')>0 then ShowMessage('OK');
output
end;

end.



unit Unit2;

interface

type
TData = string;

PDataList = ^TDataList;
TDataList = record
data : TData;
next : PDataList
end;

TMyList = class(TObject)
private
FCount : Integer;
FHead : PDataList;
public
constructor Create;
destructor Destroy
override;

procedure Clear;
function First: PDataList;
function Last: PDataList;

function Append(Item: TData): Integer;
procedure Delete(Index: Integer);
procedure Insert(Index: Integer
Item: TData);
procedure Modify(index: Integer
Item: TData);
function Items(Index: Integer) : TData;
function IndexOf(Item: TData): Integer;
function Length : Integer;
end;

implementation

constructor TMyList.Create;
begin
new(FHead);
FHead^.next := nil;

FCount := 0;
end;

destructor TMyList.Destroy;
begin
Clear;
Dispose(FHead);
end;

procedure TMyList.Clear;
var
p : PDataList;
begin
FCount := 0;
p := FHead^.next;
while p <> nil do
begin
FHead^.next := p^.next;
Dispose(p);
p := FHead^.next;
end;
end;

function TMyList.First: PDataList;
begin
result := FHead^.next;
end;

function TMyList.Last: PDataList;
begin
result := FHead^.next;
if result <> nil then
begin
while result^.next <> nil do
begin
result := result^.next;
end;
end;
end;


function TMyList.Append(Item: TData): Integer;
var
p : PDataList;
begin
result := 0;
new(p);
try
p.data := Item;
p.next := nil;

if FCount = 0 then
begin
FHead^.next := p;
end
else
begin
Last^.next := p;
end;

Inc(FCount);
result := FCount;
except

end;
end;

procedure TMyList.Delete(Index: Integer);
var
p,q : PDataList;
i : Integer;
begin
if (FCount > 0) and (Index > 0) and (Index <= FCount) then
begin
p := First;
for i := 1 to Index-2 do
begin
p := p^.next;
end;

q := p^.next;
if Index = FCount then
begin
p^.next := nil;
end
else
begin
p^.next := q^.next;
end;

Dispose(q);
Dec(FCount);
end;
end;

procedure TMyList.Insert(Index: Integer
Item: TData);
var
p,q : PDataList;
i : Integer;
begin
if (Index > 0) and (index <= FCount+1) then
begin
new(q);
q^.data := Item;
q^.next := nil;

if (FCount = 0) and (Index = 1) then
begin
FHead.next := q;
end
else if FCount+1 = Index then
begin
Last^.next := q;
end
else
begin
p := First;
for i := 1 to Index-1 do
begin
p := p^.next;
end;

q^.next := p^.next;
p^.next := q;
end;

Inc(FCount);
end;
end;

procedure TMyList.Modify(index: Integer
Item: TData);
begin
if (Index > 0) and (Index <= FCount) then
begin
Delete(Index);
Insert(Index, Item);
end;
end;

function TMyList.Items(index: Integer): TData;
var
i : Integer;
p : PDataList;
begin
if(index > 0) and (index <= FCount) then
begin
p := First;
for i := 1 to index-1 do
p := p^.next;

result := p^.data;
end;
end;

function TMyList.IndexOf(Item: TData): Integer;
var
p : PDataList;
bFound : Boolean;
begin
result := 0;

p := First;
bFound := False;
while (p <> nil) and (not bFound) do
begin
if p^.data = Item then bFound := true;
Inc(result);
p := p^.next;
end;

if not bFound then result := 0;
end;

function TMyList.Length : Integer;
begin
result := FCount;
end;

end.
 
to firemeteor:
//修改
代码:
  New(CfgCom);
  CfgCom:=mList.Items[0];
  CfgCom^.iCur:=2;
  CfgCom^.sCon:='cba';
  //mList.Items[0]:=CfgCom 这里一块如果不赋值回去的话,
  //CfgCom就不能Dispose否则就没有值了,赋值回去如果Dispose的话也有问题!
  //内容会乱了,谁能帮我解释一下

 CfgCom:=mList.Items[0];
 CfgCom^.iCur:=2;
 CfgCom^.sCon:='cba';
即可,不用new也不用dispose
如果我前面不只增加了一个节点,而我要修改第一个节点,
如果修改的时候不New,会不会把上一个增加的节点给冲掉啊!
对不对呢!


to tseug:
万分感谢!等第二个问题结束了一起给分!
你说的http://www.2001soft.com/cal/这个程序,我安装不成功啊,
又没有源文件。他报“Lines too long”编译通不过!
 
还有一个非技术问题:
我订阅的邮件通知中有jps_exp给我的答复,但是在帖子里怎么没有呢!奇怪!
内容如下:
关于:"最近比较烦,关于链表和计算表达式! "

[green]jps_exp 在 2001-11-12 18:52:59 提供了如下回答, 请您查阅和评估:
--------------------------------------------------------------------------
---
可以这样自己写个链表

type
PType=^mType;
mType = Record
iCur:integer;
sCon:string;
end;

TMlist = class
private
First: PType;
FLength: integer;
public
constructor Create;
destructor Destroy;override;
function IsEmpty:boolean;
function Length:integer;
function InsertList(Node: mType;Pos:integer):boolean;
function DeleteList(var Node: mType;Pos:integer):boolean;
function AppendList(Node: mType;):boolean;
function GetNode(var Node: mType;Pos:integer):boolean;
end;[/green]
 
>>SuperJS
>>第二个问题:[/b]
>>谁能告诉我如何计算表达式啊!我查过以前的帖子回答也没有解决!

function GetNewValue(v1, v2: variant
s1: string): variant;
var vv: variant;
begin
Result := '';
if trim(s1) = '*' then vv := v1 * v2
else if trim(s1) = '+' then vv := v1 + v2
else if trim(s1) = '+' then vv := v1 - v2
else if trim(s1) = '/' then
begin
if (v2 = '') or (v1 = '') or (v2 = 0) then exit;
vv := v1 div v2;
end;
result := vv;
end;

不是很详细,仅抛砖引玉。
 
to Tense:
不好意思,把你和tseug搞混了!
也谢谢你了!
 
>>SuperJS
>>to Tense:
>>不好意思,把你和tseug搞混了!
没关系,只要你把问题解决了,大家都很高兴的。

 
后退
顶部