一个排列函数,看不懂,我想改一下,请问怎么改?(0分)

  • 主题发起人 主题发起人 mxq888
  • 开始时间 开始时间
M

mxq888

Unregistered / Unconfirmed
GUEST, unregistred user!
我收藏的一个函数,返回的TstringList中,列出了p(m,n)所有排列.
用个全局变量为:
DataBuf:array[1..22] of char;

function RangeList(const m,n: Integer): TStringList;
type
TNode = record
d: Integer;
Used: array of Boolean;
end;
var
Stack: array of TNode;
Top: Integer;
i,j: Integer;
s: string;

begin
if m>n then
Exit;
SetLength(stack,m);
for i:=1 to m do
SetLength(stack[i-1].Used,n); //setlength(a,n);a下标应该从0..n-1
ZeroMemory(Stack,sizeof(Stack));
Result:=TStringList.Create;
Top:=0;
Stack[0].d:=-1;

while Top>=0 do
begin
while Stack[Top].d<n-1 do
begin
Inc(Stack[Top].d);
if not Stack[Top].Used[Stack[Top].d] then
if Top=m-1 then
begin
s:='';
for i:=0 to Top do
s:=s+DataBuf[Stack.d];
Result.Append(s)
end
else
begin
Inc(Top);
Stack[Top].d:=-1;
for i:=0 to n-1 do
Stack[Top].Used:=Stack[Top-1].Used;
Stack[Top].Used[Stack[Top-1].d]:=True;//#1
end
end;
Dec(Top);
end
end;

比如p(3,10),如果要求组合中,数字可以重复,应该怎么改啊????[:(]
就是可以出现111,122,212,这样的排列。

也就是每取一个数字后,再取数字时,仍然可以取上次取的数字。
我看不懂上面的函数,望高手帮忙,多谢![:D]
 
这个函数根本就产生不了p(3,10)的结果,输出的StringList为空
应该是被你改过了,又没有改对,是不是这样
 
再贴一遍原函数,看不区别吗,我是改过,不过是小改。[:(]肯定有结果的,你要是测试不出结果,估计你也象我一样,改不了,[:D][:D][:D]
function RangeList(const m,n: Integer): TStringList;
type
TNode = record
d: Integer;
Used: array of Boolean;
end;
var
Stack: array of TNode;
Top: Integer;
i,j: Integer;
s: string;
begin
if m>n then
Exit;
SetLength(stack,m);
for i:=1 to m do
SetLength(stack[i-1].Used,n); //setlength(a,n);a下标应该从0..n-1
ZeroMemory(Stack,sizeof(Stack));
Result:=TStringList.Create;
Top:=0;
Stack[0].d:=-1;

while Top>=0 do
begin
while Stack[Top].d<n-1 do
begin
Inc(Stack[Top].d);
if not Stack[Top].Used[Stack[Top].d] then
if Top=m-1 then
begin
s:='';
for i:=0 to Top do
s:=s+DataBuf[Stack.d];
Result.Append(s)
end
else
begin
Inc(Top);
Stack[Top].d:=-1;
for i:=0 to n-1 do
Stack[Top].Used:=Stack[Top-1].Used;
Stack[Top].Used[Stack[Top-1].d]:=True;//#1
end
end;
Dec(Top);
end
end;
 
问题是你这一改,我就没法通过跟踪,来理解作者的思路,这对于接手一段不很了解的程序是极为重要的一种方法。
不能产生结果,我还要去理解你改错了的垃圾,然后再来个垃圾变宝的法术,你以为?
本来你问人问题不散分也没什么,没看见都没人理你?你不虚心还想BS我,真是什么人哪
 
to icc
我是想什么说什么,绝没有什么BS的意思啊,还望指教,谢谢!
 
还是不测不出来,你执行 ShowMessage(RangeList(2, 4).Text)试试,看有没有结果
都是空白呀
 
我不知道怎么做啊,很多地方看不懂[:(]
这是原贴,谢谢你了!
http://www.richsearch.com/search/displ.aspx?lid=1853152
 
将原贴中代码的

//if not Stack[Top].Used[Stack[Top].d] then

注释掉就行了。
 
谢谢娃娃,谢谢娃娃,谢谢娃娃![:D][:D][:D]
 
如下,注释掉后,第一遍得到一组“000”后,再执行到代码中标注的那一行会出错,不知为何?
function RangeList(const m,n: Integer): TStringList;
type
TNode = record
d: Integer;
Used: array of Boolean;
end;
var
Stack: array of TNode;
Top: Integer;
i,j: Integer;
s: string;

begin
if m>n then
Exit;
SetLength(stack,m);
for i:=1 to m do
SetLength(stack[i-1].Used,n); //setlength(a,n);a下标应该从0..n-1
ZeroMemory(Stack,sizeof(Stack));
Result:=TStringList.Create;
Top:=0;
Stack[0].d:=-1;

while Top>=0 do
begin
while Stack[Top].d<n-1 do
begin
Inc(Stack[Top].d);
//if not Stack[Top].Used[Stack[Top].d] then
if Top=m-1 then
begin
s:='';
for i:=0 to Top do
s:=s+DataBuf[Stack.d];
Result.Append(s);
end;
//else
begin
Inc(Top);
Stack[Top].d:=-1;
for i:=0 to n-1 do
Stack[Top].Used:=Stack[Top-1].Used;
Stack[Top].Used[Stack[Top-1].d]:=True;//#1 ==》到这一句会出错。
end
end;
Dec(Top);
end
end;

我的调用方法
procedure TForm_1.BitBtn1Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to 9 do
DataBuf:=Char(i+48);
Memo1.Lines.AddStrings(RangeList(3,10));
end;
谢谢~~
 
说错了,是第二次执行到上面标注的那句的上一句:就是:
Stack[Top].Used := Stack[Top - 1].Used;这一句的时候,出错。
 
其实现在这个算法和你的需求根据有点生拉硬套,如这个算法吧。
要包含math单元。

WordList: array of char;

//其实你现在的问题就是自定义数值进制
function MakeList(const m, n: integer): TStringList;
var
lary_temp: array of string;
s: String;
i, j, k: integer;
begin
Result := TStringList.Create;
k := high(WordList)+1; //进制定位(类似十进制,八进制一样)
if Round(IntPower(k, m)) < n then Exit; //防止数据范围超限
SetLength(lary_temp, m); //设置一个要求数据长度的数组。

for i:=0 to n-1 do
begin
lary_temp[0] := wordList[i mod k]; //最后一位取值
for j:=1 to m-1 do
lary_temp[j] := wordList[(i div Round(IntPower(k, j))) mod k]; //其它位取值

s := '';
for j:=m-1 downto 0 do
s := s + lary_temp[j];

Result.Add(s);
end;
end;

procedure TForm1.btnStartClick(Sender: TObject);
var
i: integer;
begin
SetLength(WordList, 9);
for i:=0 to 8 do
WordList := chr(i+48);

Memo1.Lines.Text := MakeList(4, 700).text;
end;

另外:给你个人一个提醒,不管你是激将法,还是其它什么想法,你上面说的话,确实比较气人,希望以后你能注意。
 
谢谢娃娃,我不是激将法也没有其它想法,只是象对很熟悉的朋友一样,很随便地说说而已,抱歉,谢谢你和大家的帮助!
 
094
095
096
097
098
099
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
160
161
162
163
164
上面的我截取的生成的数据的部分,不知道为什么100后就不显示了[:(],我正在查原因。
 
已经好了,我也不知道是怎么回事,谢谢娃娃!
 
后退
顶部