向各位高手求一个高效的算法,请进来看,谢谢!

Im17benteng 2011-07-17 05:34:28
我有一个从1到10000000的数

首先随机从中抽掉十分之一的数

然后我需要一个算法,快速从剩余的数中查找出连续n个的数,比如5-10,连续6个的数(n是不固定的),


查找出来后立即移除出这些数,然后再进行查找

...全文
971 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiesb 2011-07-22
  • 打赏
  • 举报
回复
好好学习
SolarJupiter 2011-07-20
  • 打赏
  • 举报
回复
好好学习
dfasri 2011-07-19
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 im17benteng 的回复:]

可以直接分配数组的内存啊?
Data = Getmem(AllCount * 4);
1亿个DWORD?
以前没这么用过,看来要学的东西不少啊
[/Quote]
为什么不能这样用啊...4个BYTE合成一个DWORD, 那么分配8个BYTE就是两个DWORD, 有什么不行的?
或者, 理解成是 Data = Getmem(AllCount * SizeOf(DWORD)) 吧, 这样就好理解了吧..
用上超大数组来映射, 肯定会快的, 只是内存空间利用率低下而已, 想要快, 又要速度高, 可以考虑采用bit来标识的, 运算是多一点, 但都是多两三条CPU指令, 不会对速度有多大影响的. 即1亿的数据, 只要采用1亿/32个DWORD来记录就可以了. 因为一个DWORD有32位.
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
popad是出栈吧?
另外如果我要初始化一个结构体数组也能用这样的方法吗?
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
另外为什么
Clsed = Getmem( AllCount div 2);
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
可以直接分配数组的内存啊?
Data = Getmem(AllCount * 4);
1亿个DWORD?
以前没这么用过,看来要学的东西不少啊
dfasri 2011-07-19
  • 打赏
  • 举报
回复
让我们一起分析汇编吧. 算法, 通过只要知道初始化的过程, 就会知道大概的做法是怎样的了

const
AllCount=10000000; //总的数据量
One_tenth=1000000; //十分之一

//定义全局变量

var
tmpData:pdword;
DataCount:dword; //每次清除后剩余的数据量
Data:array of dword; //存贮数据的数组
Clsed:array of dword; //存贮被清除的连续数的第一个数
ClsCnt:dword; //被清除的连续数的组数


//下面是8个功能函数:

procedure initData; //分配内存,初始化数组
asm
pushad ; EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI全部压栈
mov eax,AllCount ; EAX = AllCount(即1亿)
mov DataCount,eax ; DataCount = EAX, 跟上面合起来 DataCount = AllCount
push eax ; EAX压栈(1亿的值)
shl eax,2 ; EAX左移两位, 即1亿 = 0x0098 9680 << 2 = 4亿.
call sysgetmem ; EAX为第一参数呼叫系统内存分配函数, 返回地址值在EAX
mov Data,eax ; Data被分配给指向4亿个BYTE的空间,共计即Data[10000000]
xor edx,edx ; 清空EDX
pop ecx ; ECX为EAX之前的压栈值, 1亿
@p1:
inc edx ; EDX++(从0开始)
mov [eax],edx ; *Data = EDX
add eax,4 ; Data地址移拉下一个, 即@DWORD[0] 变成@DWORD[4]
loop @p1 ; 循环1亿次, 即Data[]按顺序写入1~1亿的值
mov eax,allCount ; EAX = 1亿
shl eax,2 ; EAX = 4亿
call sysgetmem ; 分配4亿个BYTE
mov tmpData,eax ; tmpData = tmpData[10000000]
mov edx,eax ; EDX = tmpData
mov eax,Data ; Data地址赋值到EAX
mov ecx,allcount ; ECX = 1亿
shl ecx,2 ; ECX = 4亿
call move ; Move(const Source;var Dest; Count: Integer); 即Move(Data, tmpData, 4亿)
mov eax,allCount ; EAX = 1亿
shl eax,1 ; EAX = 2亿
call sysgetmem ; 分配2亿个BYTE的空间
mov Clsed,eax ; Clsed = DWORD[2亿/4];(2亿个BYTE)
popad ; EAX,ECX,EDX,EBX,ESP,EBP,ESI和EDI全部压栈
end;

即上述代码等效的功能:

Data = Getmem(AllCount * 4);
for(i=0 to AllCount - 1)
Data[i] = i + 1;
tmpData = Getmem(AllCount * 4);
Move(Data, tmpData, AllCount * 4);
Clsed = Getmem( AllCount div 2);


汇编上拆分没错的话, 代码就是这样了. 我想楼主应该想得到剩下的处理步骤了.
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
其实不用看代码的,最终的目前就是操作那个结构体

PSBTNode = ^TSBTNode;
TSBTNode = record
IsUse: Boolean; //是否使用中
count: Cardinal; //使用页数
value: Pointer; //内存地址
data: Cardinal; //节点序号
size: Cardinal; //子节点数
lch,rch: PSBTNode; //左右节点
end;


最主要的是
value: Pointer; //内存地址
data: Cardinal; //节点序号
这个data就是现在的数组了,value就是记录的地址,是以4096递加的

主要就是分配
VMAlloc(内存大小)
内存大小 div 4096 = 连续的页数,就是连续n个数
分配连续n页的内存,返回value,就是内存地址
VMReAlloc(内存大小)
根据内存大小计算出所需页,如果所需页=以前的页数,则直接返回,如果所需的页小于以前的页,则把多余的页放回原队列,如果所需的页大于以前的面,则重新分配,并copy原value里的内存到新申请的value的内存里,然后把原来申请的放回队列中

VMFree就是根据原来的value计算出数组的ID
,因为所有value都是有规律的,4096递加,并且有个基地址lpBase
所以
数组id = (现在用的value-lpBase) div 4096;

得到这个数据id了,就得到了这个节点,也得到了申请的页数PSBTNode.count

根据页数放回连续的页到队列中
cngst 2011-07-19
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 im17benteng 的回复:]

引用 44 楼 cngst 的回复:

已将程序源代码打包上传,可以在:

http://download.csdn.net/source/3452389

下载。


看到了大哥,您再费神帮我看看
[/Quote]

不好意思,代码太长,我自己写代码还行(有自己的思路带着,可以一气呵成),分析别人的代码,尤其这么长的代码,有点。。。
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
[Quote=引用 44 楼 cngst 的回复:]

已将程序源代码打包上传,可以在:

http://download.csdn.net/source/3452389

下载。
[/Quote]

看到了大哥,您再费神帮我看看
cngst 2011-07-19
  • 打赏
  • 举报
回复
已将程序源代码打包上传,可以在:

http://download.csdn.net/source/3452389

下载。
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
{ TVirtualMemPool }
constructor TVirtualMemPool.Create(ACount: Integer);
var
SysInfo: TSystemInfo;
begin
inherited Create;;
InitializeCriticalSection(m_VMLock);
InitializeCriticalSection(m_NMLock);
GetSystemInfo(SysInfo);
m_PageSize := SysInfo.dwPageSize;
m_SBTStorage := TSizeBalancedTree.Create(Self);
m_Count := ACount;
InitMemPool(m_Count);
end;

destructor TVirtualMemPool.Destroy;
begin
FreeAndNil(m_SBTStorage);
Clear;
VirtualFree(m_lpBase, 0, MEM_RELEASE);
DeleteCriticalSection(m_NMLock);
DeleteCriticalSection(m_VMLock);
inherited Destroy;
end;

function TVirtualMemPool.GetCount: Cardinal;
begin
Result := m_Count;
end;

function TVirtualMemPool.GetUseCount: Cardinal;
begin
EnterCriticalSection(m_NMLock);
try
Result := m_Count - m_SBTStorage.NodeCount;
finally
LeaveCriticalSection(m_NMLock);
end;
end;

function TVirtualMemPool.GetFreeCount: Cardinal;
begin
EnterCriticalSection(m_NMLock);
try
Result := m_SBTStorage.NodeCount;
finally
LeaveCriticalSection(m_NMLock);
end;
end;

procedure TVirtualMemPool.InitMemPool(ACount: Integer);
var
I: Integer;
begin
EnterCriticalSection(m_VMLock);
try
// 申请大块内存
m_lpBase := VirtualAlloc(nil,
ACount*m_PageSize,
MEM_RESERVE,
PAGE_NOACCESS);
SetLength(m_Buckets, ACount);
//debug('m_lpBase: %d, NumberOfNode: %d', [Cardinal(m_lpBase), NumberOfNode]);
for I := 0 to ACount-1 do
begin
{ 为第I页地址提交内存。 }
New(m_Buckets[I]);
m_Buckets[I]^.data := I;
m_Buckets[I]^.value := VirtualAlloc(Pointer(Cardinal(m_lpBase)+(I*m_PageSize)),
m_PageSize,
MEM_COMMIT,
PAGE_READWRITE);
//debug('I: %d=%d', [I, Cardinal(m_Buckets[I]^.value)]);
//ZeroMemory(m_Buckets[I]^.value, m_PageSize);
m_SBTStorage.add(m_Buckets[I]);
end;
finally
LeaveCriticalSection(m_VMLock);
end;
end;

procedure TVirtualMemPool.Clear;
var
I: Integer;
begin
EnterCriticalSection(m_VMLock);
try
for I := 0 to Length(m_Buckets)-1 do
begin
Dispose(m_Buckets[I]);
end;
finally
LeaveCriticalSection(m_VMLock);
end;
end;

function TVirtualMemPool.VMAlloc(dwSize: Cardinal; IsLock: Boolean = True): Pointer;
var
N, M, D1, D2, NStart, NEnd: Integer;
P: PSBTNode;
begin
if FreeCount<=0 then
begin
Result := nil;
raise Exception.Create('No free pages in main memory.');
Exit;
end;
if IsLock then EnterCriticalSection(m_VMLock);
try
N := dwSize div m_PageSize;
if (dwSize mod m_PageSize)<>0 then
Inc(N);
M := 1;
D2 := -1;
D1 := m_SBTStorage.select(1);
if N<=1 then
begin
NStart := D1;
//移出使用中的对像
P := m_SBTStorage.remove(NStart);
P^.count := 1;
Result := P^.value;
Exit;
end;
while True do
begin
//右旋转
D2 := m_SBTStorage.succ(D1);
if D2=D1 then
Break;
if D2=D1+1 then
begin
Inc(M);
end
else
begin
M := 1;
end;
if M>=N then
Break;
D1 := D2;
end;
NStart := D2 - N + 1;
NEnd := NStart + N;
P := m_SBTStorage.remove(NStart);
P^.count := N;
Result := P^.value;
Inc(NStart);
while NStart<NEnd do
begin
m_SBTStorage.remove(NStart);
Inc(NStart);
end;
finally
if IsLock then LeaveCriticalSection(m_VMLock);
end;
end;

function TVirtualMemPool.VMReAlloc(var P; dwSize: Cardinal): Pointer;
var
OldN, M, NewN, NEnd: Cardinal;
NewP: Pointer;
begin
Result := nil;
if Pointer(P)=nil then
begin
Result := VMAlloc(dwSize);
Exit;
end;
EnterCriticalSection(m_VMLock);
try
M := (Cardinal(Pointer(P))-Cardinal(m_lpBase)) div m_PageSize;
// 原页数
OldN := m_Buckets[M]^.count;
// 新页数
NewN := dwSize div m_PageSize;
if (dwSize mod m_PageSize)<>0 then
Inc(NewN);
// 新页数=原页数
if NewN=OldN then
begin
Result := Pointer(P);
end
// 新页数<原页数,多余的页放回页表
else if NewN<OldN then
begin
NEnd := M + OldN;
m_Buckets[M]^.count := OldN-NewN;
M := M + NewN;
while M<NEnd do
begin
m_SBTStorage.add(m_Buckets[M]);
Inc(M);
end;
Result := Pointer(P);
end
// 新页数>原页数,重新申请并Copy原数据到新数据
else if NewN>OldN then
begin
NewP := VMAlloc(dwSize, False);
//原数据Copy到新数据中
if NewP<>nil then
CopyMemory(NewP, Pointer(P), OldN*m_PageSize);
//放回原页数
VMFree(P, False);
//返回
Pointer(P) := NewP;
Result := NewP;
end;
finally
LeaveCriticalSection(m_VMLock);
end;
end;

function TVirtualMemPool.VMFree(var P; IsLock: Boolean = True): Boolean;
var
M, N, NEnd: Cardinal;
begin
if IsLock then EnterCriticalSection(m_VMLock);
try
M := (Cardinal(Pointer(P))-Cardinal(m_lpBase)) div m_PageSize;
Pointer(P) := nil;
// 页数
N := m_Buckets[M]^.count;
NEnd := M + N;
// 放回
while M<NEnd do
begin
m_SBTStorage.add(m_Buckets[M]);
Inc(M);
end;
finally
if IsLock then LeaveCriticalSection(m_VMLock);
end;
Result := True;
end;

end.

//使用方法
var
VMP: TVirtualMemPool;
P: PAnsiChar;
S: AnsiString;
begin
VMP := TVirtualMemPool.Create(200000);
try
//分配
P := VMP.VMAlloc(4096*3);
Writeln(Cardinal(P));
S := 'ABCDEFG';
CopyMemory(P, @S[1], Length(S));
FillChar(P^, 4096*3, 88);
//重新分配
P := VMP.VMReAlloc(P, 4096*6);
Writeln(Cardinal(P));
//回收
VMP.VMFree(P);
if P=nil then
Writeln('OK');
Readln;
finally
FreeAndNil(VMP);
end;
end;

//我这里是按页大小分配的,页大小4096,如果分配3页就是4096*3,相当于,查找3个连续的数!

希望cngst大哥帮我看看,或有其他高手提供好的算法!
非常感谢cngst大哥和上面的各位高手,这个贴子完成后是不是可以推荐到首页呢?
Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
{ TSizeBalancedTree }
constructor TSizeBalancedTree.Create(AVMpool: TVirtualMemPool);
begin
VMPool := AVMpool;
NodeCount := 0;
new(null);
null^.data := 0;
null^.size := 0;
null^.lch := null;
null^.rch := null;
root := null;
end;

destructor TSizeBalancedTree.Destroy;
begin
NodeCount := 0;
Dispose(null);
inherited Destroy;
end;

procedure TSizeBalancedTree.lrotate(var x: PSBTNode);
var
y: PSBTNode;
begin
y := x^.rch;
x^.rch := y^.lch;
y^.lch := x;
y^.size := x^.size;
x^.size := x^.lch^.size+x^.rch^.size+1;
x := y;
end;

procedure TSizeBalancedTree.rrotate(var x: PSBTNode);
var
y: PSBTNode;
begin
y := x^.lch;
x^.lch := y^.rch;
y^.rch := x;
y^.size := x^.size;
x^.size := x^.lch^.size+x^.rch^.size+1;
x := y;
end;

procedure TSizeBalancedTree.maintain(var t: PSBTNode; const flag: Boolean);
begin
if t=null then
exit;
if not flag then
if t^.lch^.lch^.size>t^.rch^.size then
rrotate(t)
else if t^.lch^.rch^.size>t^.rch^.size then
begin
lrotate(t^.lch);
rrotate(t);
end
else
exit
else if t^.rch^.rch^.size>t^.lch^.size then
lrotate(t)
else if t^.rch^.lch^.size>t^.lch^.size then
begin
rrotate(t^.rch);
lrotate(t);
end
else
exit;
maintain(t^.lch, false);
maintain(t^.rch, true);
maintain(t, false);
maintain(t, true);
end;

procedure TSizeBalancedTree.TreeAdd(var t: PSBTNode; v: PSBTNode);
begin
if t=null then
begin
t := v;
//进入的内存设置为未使用
t^.IsUse := False;
t^.count := 0;
t^.size := 1;
t^.lch := null;
t^.rch := null;
Inc(NodeCount);
end
else begin
inc(t^.size);
if v^.data<t^.data then
TreeAdd(t^.lch, v)
else
TreeAdd(t^.rch, v);
maintain(t, v^.data>=t^.data);
end;
end;

function TSizeBalancedTree.TreeRemove(var t: PSBTNode; var n: PSBTNode; v: Cardinal): Cardinal;
var
tmp: PSBTNode;
begin
Result := Cardinal(-1);
if t=null then
Exit;
dec(t^.size);
if(v=t^.data) or ((v<t^.data) and (t^.lch=null)) or ((v>t^.data) and (t^.rch=null)) then
begin
Result := t^.data;
if(t^.lch=null) or (t^.rch=null) then
begin
if t^.lch=null then
begin
tmp := t;
t := tmp^.rch;
if tmp<>null then
begin
n := tmp;
Dec(NodeCount);
Exit;
end;
end;
if t^.rch=null then
begin
tmp := t;
t := tmp^.lch;
if tmp<>null then
begin
n := tmp;
Dec(NodeCount);
Exit;
end;
end;
end
else
t^.data := TreeRemove(t^.lch, n, t^.data+1);
end
else if v<t^.data then
Result := TreeRemove(t^.lch, n, v)
else
Result := TreeRemove(t^.rch, n, v);
end;

function TSizeBalancedTree.TreeSelect(var t: PSBTNode; k: Cardinal): Cardinal;
begin
if (k=t^.lch^.size+1) then
begin
Result := t^.data;
exit;
end;
if k<=t^.lch^.size then
Result := TreeSelect(t^.lch, k)
else
Result := TreeSelect(t^.rch, k-1-t^.lch^.size);
end;

function TSizeBalancedTree.TreeFind(var t: PSBTNode; v: Cardinal): Boolean;
begin
if t=null then
begin
Result := false;
exit;
end;
if v<t^.data then
Result := TreeFind(t^.lch,v)
else
Result := (v=t^.data) or TreeFind(t^.rch,v);
end;

function TSizeBalancedTree.TreeRank(var t: PSBTNode; v: Cardinal): Cardinal;
begin
if t=null then
begin
Result := 1;
exit;
end;
if v<t^.data then
Result := TreeRank(t^.lch,v)
else
Result := t^.lch^.size+1+TreeRank(t^.rch,v);
end;

function TSizeBalancedTree.TreeSucc(var t: PSBTNode; v: Cardinal): Cardinal;
var
tmp:Cardinal;
begin
if t=null then
begin
Result := v;
exit;
end;
if v>=t^.data then
Result := TreeSucc(t^.rch,v)
else
begin
tmp:=TreeSucc(t^.lch,v);
if tmp=v then
tmp := t^.data;
Result := tmp;
end;
end;

function TSizeBalancedTree.TreePred(var t: PSBTNode; v: Cardinal): Cardinal;
var
tmp: Cardinal;
begin
if t=null then
begin
Result := v;
exit;
end;
if v<=t^.data then
Result := TreePred(t^.lch, v)
else
begin
tmp := TreePred(t^.rch,v);
if tmp=v then
tmp := t^.data;
Result := tmp;
end;
end;

procedure TSizeBalancedTree.add(v: PSBTNode);
begin
TreeAdd(root, v);
end;

function TSizeBalancedTree.remove(v: Cardinal): PSBTNode;
var
v2: Cardinal;
C: Pointer;
P: PSBTNode;
begin
Result := nil;
TreeRemove(root, Result, v);
v2 := Result^.data;
Result^.data := v;
//移出的内存设置为使用
Result^.IsUse := True;
//value交换
C := VMPool.m_Buckets[v2]^.value;
VMPool.m_Buckets[v2]^.value := VMPool.m_Buckets[v]^.value;
VMPool.m_Buckets[v]^.value := C;
//位置交换
P := VMPool.m_Buckets[v2];
VMPool.m_Buckets[v2] := VMPool.m_Buckets[v];
VMPool.m_Buckets[v] := P;
end;

function TSizeBalancedTree.select(k: Cardinal): Cardinal;
begin
Result := TreeSelect(root, k);
end;

function TSizeBalancedTree.find(v: Cardinal): Boolean;
begin
Result := TreeFind(root, v);
end;

function TSizeBalancedTree.rank(v: Cardinal): Cardinal;
begin
Result := TreeRank(root, v);
end;

function TSizeBalancedTree.succ(v: Cardinal): Cardinal;
begin
Result := TreeSucc(root, v);
end;

function TSizeBalancedTree.pred(v: Cardinal): Cardinal;
begin
Result := TreePred(root, v);
end;

Im17benteng 2011-07-19
  • 打赏
  • 举报
回复
最后再请cngst大哥帮忙看看我完整的应用应该是这样,cngst大哥的算法非常快,但我还是没办法使用到我这个应用中来,现在我贴出我完整理应用的代码,请大哥费神再帮忙看一下!

分页式虚拟内存管理
unit uVirtualMemPool;

interface

uses
SysUtils, Windows;

type
TVirtualMemPool = class;

PSBTNode = ^TSBTNode;
TSBTNode = record
IsUse: Boolean; //是否使用中
count: Cardinal; //使用页数
value: Pointer; //内存地址
data: Cardinal; //节点序号
size: Cardinal; //子节点数
lch,rch: PSBTNode; //左右节点
end;

// 平衡二叉查找树SBT
TSizeBalancedTree = class
private
VMPool: TVirtualMemPool;
// 节点数
NodeCount: Cardinal;
// 根节点,空节点
root,null: PSBTNode;
// 左旋转
procedure lrotate(var x: PSBTNode); inline;
// 右旋转
procedure rrotate(var x: PSBTNode); inline;
// 保持性质
procedure maintain(var t: PSBTNode; const flag: Boolean); inline;
// 增加
procedure TreeAdd(var t: PSBTNode; v: PSBTNode); inline;
// 移除
function TreeRemove(var t: PSBTNode; var n: PSBTNode; v: Cardinal): Cardinal; inline;
// 返回第 x 大的元素
function TreeSelect(var t: PSBTNode; k: Cardinal): Cardinal; inline;
// 查找
function TreeFind(var t: PSBTNode; v: Cardinal): Boolean; inline;
// 排名
function TreeRank(var t: PSBTNode; v: Cardinal): Cardinal; inline;
// 向前,大
function TreeSucc(var t: PSBTNode; v: Cardinal): Cardinal; inline;
// 向后,小
function TreePred(var t: PSBTNode; v: Cardinal): Cardinal; inline;
public
constructor Create(AVMpool: TVirtualMemPool);
destructor Destroy; override;
procedure add(v: PSBTNode);
function remove(v: Cardinal): PSBTNode;
function select(k: Cardinal): Cardinal; inline;
function find(v: Cardinal): Boolean; inline;
function rank(v: Cardinal): Cardinal; inline;
function succ(v: Cardinal): Cardinal; inline;
function pred(v: Cardinal): Cardinal; inline;
end;

// 内存管理
TVirtualMemPool = class
public
m_VMLock: TRTLCriticalSection;
m_NMLock: TRTLCriticalSection;
m_PageSize: Cardinal;
m_Count: Cardinal;
m_lpBase: Pointer;
m_Buckets: array of PSBTNode;
m_SBTStorage: TSizeBalancedTree;
private
function GetCount: Cardinal;
function GetUseCount: Cardinal;
function GetFreeCount: Cardinal;
procedure InitMemPool(ACount: Integer);
procedure Clear;
public
property Count: Cardinal read GetCount;
property UseCount: Cardinal read GetUseCount;
property FreeCount: Cardinal read GetFreeCount;
public
constructor Create(ACount: Integer);
destructor Destroy; override;
public
function VMAlloc(dwSize: Cardinal; IsLock: Boolean = True): Pointer;
function VMReAlloc(var P; dwSize: Cardinal): Pointer;
function VMFree(var P; IsLock: Boolean = True): Boolean;
end;

implementation

dfasri 2011-07-19
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 im17benteng 的回复:]
你说的这种链表就是双向链表吧?不如普通的算法在插入时可能要比较慢了,查找时速度还可以!
因为插入时要进行排序的
[/Quote]

请问..插入时要进行什么排序.....? 不是本身就按顺序拆的了么...
天涯倦客 2011-07-19
  • 打赏
  • 举报
回复
数 是连续的 1-10000000 ?
luo000102 2011-07-19
  • 打赏
  • 举报
回复
算法迷茫中....
蓝色光芒 2011-07-18
  • 打赏
  • 举报
回复
假设已经使用了前面的9000000个,需要移动后面1000000到最前面,这个移动过程,耗时相信也不会少,每使用一次,都要移动后面的数据,当内存释放的时候,还得把数据插回去,这个又是大面积移动,如果是内存管理,那多线程下,只有使用全局锁,而且是缩整个列表,而不能使用 lock xchg , lock xadd,等指令了
Im17benteng 2011-07-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 kiboisme 的回复:]

更正一下:
是遍历比较n DIV 4个整数如果是$01010101,
(n shl 2)更好些
[/Quote]

你这个算法就算是前面9000000已经全被使用是不是还一样要循环过这9000000?
Im17benteng 2011-07-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 kiboisme 的回复:]

更正一下:
是遍历比较n DIV 4个整数如果是$01010101,
(n shl 2)更好些
[/Quote]

如果我要取得连接3个数,但之前的9000000中,都没有连续的3个数,这样不是要循环9000000次,效率太低下了吧
加载更多回复(34)

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧