此文章转载于http://www.raysoftware.cn/?p=278&tdsourcetag=s_pcqq_aiomsg的博客

从Delphi支持泛型的第一天起就有了一种新的动态数组类型,泛型化的动态数组–TArray.
虽然这个类型比较方便,但是却没有提供更丰富的操作.因为XE4中提供了对数据类型的Helper扩展,例如StringHelper,企图实现一个TArrayHelper但是发现Helper不支持泛型的类型.
没办法只好包装了一个record,好处是似乎只要支持泛型的Delphi版本都可以支持.使用Demo如下:

procedure TestTArrayEx;
var
a, b, c: TArrayEx<Integer>;
f: TArrayEx<Single>;
s : TArrayEx<string>;
//
i: Integer;
z: array of Integer;
args:TArrayEx<string>;
begin
// assign a := [2, 2, 3, 4];
s := ['haha', 'hello']; // clone
b := a.Clone; // 给元素赋值
b[0] := 5; // operator +
c := a + b; c := 88 + c + 99;
a.Append([10, 20, 30]);
a.Insert(2, 1000);
a.Insert(2, [1000, 45]); a[0] := 7; // Unique
c.Unique;
// Delete
c.Delete(0, 3); // compare
if c = z then
// for in loop
for i in c do
if i = 0 then
begin
//
end; //
f := [1, 2, 3.1415926];
f.Size := 200;
if f[0] = 1.2 then
begin
f.Size := 100;
end;
end;

这些成员方法和操作符重载都是原来的TArray所不具备的.注重开发效率可以用这个办法封装一些类型,简化操作.
TArrayEx的实现代码在下面.记得必须是支持泛型版本的Delphi哦,也就是至少要Delphi2009版以后的.

unit TJArrayEx;

{ ******************************************************************************
泛型动态数组的扩展. sample: var
a, b, c: TArrayEx<Integer>;
f: TArrayEx<Single>;
s : TArrayEx<string>;
//
i: Integer;
z: array of Integer;
args:TArrayEx<string>;
begin
// assign a := [2, 2, 3, 4];
s := ['haha', 'hello']; // clone
b := a.Clone; // 给元素赋值
b[0] := 5; // operator +
c := a + b; c := 88 + c + 99;
a.Append([10, 20, 30]);
a.Insert(2, 1000);
a.Insert(2, [1000, 45]); a[0] := 7; // Unique
c.Unique;
// Delete
c.Delete(0, 3); // compare
if c = z then
// for in loop
for i in c do
if i = 0 then
begin
//
end; // f := [1, 2, 3.1415926];
f.Size := 200;
if f[0] = 1.0 then
begin
end; args := ['38inch','45inch','XL','XL2','X','38inch','45inch'];
args.Unique;
//sort
args.Sort;
//search
if args.BinarySearch('XL',i) then
ShowMessageFmt('foud index:%d',[i]); end; ****************************************************************************** }
interface uses System.Generics.Defaults, System.SysUtils; type
TArrayEx<T> = record
strict private
type
TEnumerator = class
private
FValue: TArray<T>;
FIndex: NativeInt;
function GetCurrent: T;
public
constructor Create(const AValue: TArray<T>);
function MoveNext: Boolean;
property Current: T read GetCurrent;
end;
public
function GetEnumerator(): TEnumerator;
strict private
FData: TArray<T>;
function GetRawData: TArray<T>;
function GetElements(Index: Integer): T;
procedure SetElements(Index: Integer; const Value: T);
private
class function EqualArray(A, B: TArray<T>): Boolean; static;
class function CompareT(const A, B: T): Boolean; static;
class procedure CopyArray(var FromArray, ToArray: TArray<T>;
FromIndex: NativeInt = 0; ToIndex: NativeInt = 0;
Count: NativeInt = -1); static;
class procedure MoveArray(var AArray: array of T;
FromIndex, ToIndex, Count: Integer); static;
class function DynArrayToTArray(const Value: array of T): TArray<T>; static;
class function Min(A, B: NativeInt): NativeInt; static;
procedure QuickSort(const Comparer: IComparer<T>; L, R: Integer);
public // operators
class operator Implicit(Value: TArray<T>): TArrayEx<T>; overload;
class operator Implicit(Value: array of T): TArrayEx<T>; overload;
(*
这个无解,Delphi不允许array of T作为返回值.也就是这个转换是被废了.只好用AssignTo
class operator Implicit(Value: TArrayEx<T>):array of T; overload;
*)
class operator Implicit(Value: TArrayEx<T>): TArray<T>; overload;
class operator Explicit(Value: TArrayEx<T>): TArray<T>; overload;
class operator Explicit(Value: array of T): TArrayEx<T>; overload; class operator Add(A, B: TArrayEx<T>): TArrayEx<T>; overload;
class operator Add(A: TArrayEx<T>; const B: T): TArrayEx<T>; overload;
class operator Add(const A: T; B: TArrayEx<T>): TArrayEx<T>; overload;
class operator Add(A: TArrayEx<T>; B: array of T): TArrayEx<T>; overload;
class operator Add(A: array of T; B: TArrayEx<T>): TArrayEx<T>; overload;
class operator In (A: T; B: TArrayEx<T>): Boolean; overload;
//
class operator Equal(A, B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: TArrayEx<T>; B: TArray<T>): Boolean; overload;
class operator Equal(A: TArray<T>; B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: array of T; B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: TArrayEx<T>; B: array of T): Boolean; overload; public
procedure SetLen(Value: NativeInt); inline;
function GetLen: NativeInt; inline;
function ByteLen: NativeInt; inline;
class function Create(Value: array of T): TArrayEx<T>; overload; static;
class function Create(Value: TArrayEx<T>): TArrayEx<T>; overload; static;
class function Create(const Value: T): TArrayEx<T>; overload; static;
function Clone(): TArrayEx<T>;
procedure SetValue(Value: array of T);
function ToArray(): TArray<T>;
function SubArray(AFrom, ACount: NativeInt): TArrayEx<T>;
procedure Delete(AFrom, ACount: NativeInt); overload;
procedure Delete(AIndex: NativeInt); overload;
procedure Append(Values: TArrayEx<T>); overload;
procedure Append(const Value: T); overload;
procedure Append(Values: array of T); overload;
procedure Append(Values: TArray<T>); overload;
function Insert(AIndex: NativeInt; const Value: T): NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: array of T)
: NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: TArray<T>)
: NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: TArrayEx<T>)
: NativeInt; overload;
procedure Unique();
// 排序
procedure Sort(); overload;
procedure Sort(const Comparer: IComparer<T>); overload;
procedure Sort(const Comparer: IComparer<T>;
Index, Count: Integer); overload;
// 搜索
function BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>; Index, Count: Integer): Boolean; overload;
function BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>): Boolean; overload;
function BinarySearch(const Item: T; out FoundIndex: Integer)
: Boolean; overload; property Size: NativeInt read GetLen write SetLen;
property Len: NativeInt read GetLen write SetLen;
property RawData: TArray<T> read GetRawData;
property Elements[Index: Integer]: T read GetElements
write SetElements; default;
end; implementation uses System.RTLConsts; class operator TArrayEx<T>.Add(A, B: TArrayEx<T>): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: TArrayEx<T>; const B: T): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(const A: T; B: TArrayEx<T>): TArrayEx<T>;
begin
Result.SetValue([A]);
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: TArrayEx<T>; B: array of T): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: array of T; B: TArrayEx<T>): TArrayEx<T>;
begin
Result.FData := DynArrayToTArray(A);
Result.Append(B);
end; class operator TArrayEx<T>.In(A: T; B: TArrayEx<T>): Boolean;
var
Tmp: T;
begin
Result := False;
for Tmp in B.FData do
if CompareT(A, Tmp) then
begin
Result := True;
Break;
end;
end; class operator TArrayEx<T>.Equal(A, B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(A.FData, B.FData);
end; class operator TArrayEx<T>.Equal(A: TArrayEx<T>; B: TArray<T>): Boolean;
begin
Result := EqualArray(A.FData, B);
end; class operator TArrayEx<T>.Equal(A: TArray<T>; B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(A, B.FData);
end; class operator TArrayEx<T>.Equal(A: array of T; B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(DynArrayToTArray(A), B.FData);
end; class operator TArrayEx<T>.Equal(A: TArrayEx<T>; B: array of T): Boolean;
begin
Result := EqualArray(A.FData, DynArrayToTArray(B));
end; function TArrayEx<T>.BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>; Index, Count: Integer): Boolean;
var
L, H: Integer;
mid, cmp: Integer;
begin
if (Index < Low(FData)) or ((Index > High(FData)) and (Count > 0)) or
(Index + Count - 1 > High(FData)) or (Count < 0) or (Index + Count < 0) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
if Count = 0 then
begin
FoundIndex := Index;
Exit(False);
end; Result := False;
L := Index;
H := Index + Count - 1;
while L <= H do
begin
mid := L + (H - L) shr 1;
cmp := Comparer.Compare(FData[mid], Item);
if cmp < 0 then
L := mid + 1
else
begin
H := mid - 1;
if cmp = 0 then
Result := True;
end;
end;
FoundIndex := L;
end; function TArrayEx<T>.BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>): Boolean;
begin
Result := BinarySearch(Item, FoundIndex, Comparer, Low(FData), Length(FData));
end; function TArrayEx<T>.BinarySearch(const Item: T;
out FoundIndex: Integer): Boolean;
begin
Result := BinarySearch(Item, FoundIndex, TComparer<T>.Default, Low(FData),
Length(FData));
end; function TArrayEx<T>.ByteLen: NativeInt;
begin
Result := Length(FData) * Sizeof(T);
end; class function TArrayEx<T>.Min(A, B: NativeInt): NativeInt;
begin
Result := A;
if Result > B then
Result := B;
end; class procedure TArrayEx<T>.CopyArray(var FromArray, ToArray: TArray<T>;
FromIndex, ToIndex, Count: NativeInt);
var
i: Integer;
begin
if Count = 0 then
Exit;
if Count < 0 then
Count := Min(Length(FromArray), Length(ToArray));
if Length(FromArray) < (FromIndex + Count) then
Count := Length(FromArray) - FromIndex;
if Length(ToArray) < (ToIndex + Count) then
Count := Length(ToArray) - ToIndex; if Count > 0 then
for i := 0 to Count - 1 do
ToArray[ToIndex + i] := FromArray[FromIndex + i];
end; class procedure TArrayEx<T>.MoveArray(var AArray: array of T;
FromIndex, ToIndex, Count: Integer);
var
i: Integer;
begin
if Count > 0 then
begin
if FromIndex < ToIndex then
for i := Count - 1 downto 0 do
AArray[ToIndex + i] := AArray[FromIndex + i]
else if FromIndex > ToIndex then
for i := 0 to Count - 1 do
AArray[ToIndex + i] := AArray[FromIndex + i];
end;
end; procedure TArrayEx<T>.QuickSort(const Comparer: IComparer<T>; L, R: Integer);
var
i, J: Integer;
pivot, temp: T;
begin
if (Length(FData) = 0) or ((R - L) <= 0) then
Exit;
repeat
i := L;
J := R;
pivot := FData[L + (R - L) shr 1];
repeat
while Comparer.Compare(FData[i], pivot) < 0 do
Inc(i);
while Comparer.Compare(FData[J], pivot) > 0 do
Dec(J);
if i <= J then
begin
if i <> J then
begin
temp := FData[i];
FData[i] := FData[J];
FData[J] := temp;
end;
Inc(i);
Dec(J);
end;
until i > J;
if L < J then
QuickSort(Comparer, L, J);
L := i;
until i >= R;
end; class function TArrayEx<T>.DynArrayToTArray(const Value: array of T): TArray<T>;
var
i: Integer;
begin
SetLength(Result, Length(Value));
for i := Low(Value) to High(Value) do
Result[i] := Value[i];
end; class function TArrayEx<T>.EqualArray(A, B: TArray<T>): Boolean;
var
i: Integer;
begin
Result := True;
if A = B then
Exit;
if Length(A) <> Length(B) then
begin
Result := False;
end
else
begin
for i := Low(A) to High(A) do
if not CompareT(A[i], B[i]) then
begin
Result := False;
Break;
end;
end;
end; class function TArrayEx<T>.CompareT(const A, B: T): Boolean;
var
Compare: IComparer<T>;
begin
Compare := TComparer<T>.Default;
Result := Compare.Compare(A, B) = 0;
end;
// class function TArrayEx<T>.CompareT(const A, B: T): Boolean;
// var
// p1, p2: PByte;
// i: Integer;
// begin
// Result := True;
// p1 := PByte(@A);
// p2 := PByte(@B);
// for i := 0 to Sizeof(T) - 1 do
// begin
// //
// if p1^ <> p2^ then
// begin
// Result := False;
// Exit;
// end;
// Inc(p1);
// Inc(p2);
// end;
// end; function TArrayEx<T>.GetElements(Index: Integer): T;
begin
Result := FData[Index];
end; function TArrayEx<T>.GetEnumerator: TEnumerator;
begin
Result := TEnumerator.Create(FData);
end; function TArrayEx<T>.GetLen: NativeInt;
begin
Result := Length(FData);
end; function TArrayEx<T>.GetRawData: TArray<T>;
begin
Result := FData;
end; class operator TArrayEx<T>.Implicit(Value: TArrayEx<T>): TArray<T>;
begin
SetLength(Result, Length(Value.FData));
CopyArray(Value.FData, Result, 0, 0, Length(Value.FData));
end; class operator TArrayEx<T>.Explicit(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class operator TArrayEx<T>.Implicit(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class operator TArrayEx<T>.Implicit(Value: TArray<T>): TArrayEx<T>;
begin
SetLength(Result.FData, Length(Value));
CopyArray(Value, Result.FData, 0, 0, Length(Value));
end; class operator TArrayEx<T>.Explicit(Value: TArrayEx<T>): TArray<T>;
begin
SetLength(Result, Length(Value.FData));
CopyArray(Value.FData, Result, 0, 0, Length(Value.FData));
end; procedure TArrayEx<T>.SetElements(Index: Integer; const Value: T);
begin
FData[Index] := Value;
end; procedure TArrayEx<T>.SetLen(Value: NativeInt);
begin
SetLength(FData, Value);
end; procedure TArrayEx<T>.SetValue(Value: array of T);
begin
FData := DynArrayToTArray(Value);
end; procedure TArrayEx<T>.Sort;
begin
QuickSort(TComparer<T>.Default, Low(FData), High(FData));
end; procedure TArrayEx<T>.Sort(const Comparer: IComparer<T>; Index, Count: Integer);
begin
if (Index < Low(FData)) or ((Index > High(FData)) and (Count > 0)) or
(Index + Count - 1 > High(FData)) or (Count < 0) or (Index + Count < 0) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
if Count <= 1 then
Exit;
QuickSort(Comparer, Index, Index + Count - 1);
end; procedure TArrayEx<T>.Sort(const Comparer: IComparer<T>);
begin
QuickSort(Comparer, Low(FData), High(FData));
end; function TArrayEx<T>.ToArray(): TArray<T>;
begin
SetLength(Result, Length(FData));
CopyArray(FData, Result, 0, 0, Length(FData));
end; class function TArrayEx<T>.Create(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class function TArrayEx<T>.Create(Value: TArrayEx<T>): TArrayEx<T>;
begin
Result := Value.Clone;
end; class function TArrayEx<T>.Create(const Value: T): TArrayEx<T>;
begin
Result.SetValue([Value]);
end; function TArrayEx<T>.Clone(): TArrayEx<T>;
begin
Result := SubArray(0, Length(FData));
end; function TArrayEx<T>.SubArray(AFrom, ACount: NativeInt): TArrayEx<T>;
begin
SetLength(Result.FData, ACount);
CopyArray(FData, Result.FData, AFrom, 0, ACount);
end; procedure TArrayEx<T>.Delete(AFrom, ACount: NativeInt);
begin
if AFrom >= Length(FData) then
Exit;
if (AFrom + ACount) > Length(FData) then
ACount := Length(FData) - AFrom; MoveArray(FData, AFrom + ACount, AFrom, Length(FData) - (AFrom + ACount));
SetLength(FData, Length(FData) - ACount);
end; procedure TArrayEx<T>.Delete(AIndex: NativeInt);
begin
Delete(AIndex, 1);
end; procedure TArrayEx<T>.Append(Values: TArrayEx<T>);
begin
Insert(Length(FData), Values);
end; procedure TArrayEx<T>.Append(Values: TArray<T>);
begin
Insert(Length(FData), Values);
end; procedure TArrayEx<T>.Append(const Value: T);
begin
SetLength(FData, Length(FData) + 1);
FData[High(FData)] := Value;
end; procedure TArrayEx<T>.Append(Values: array of T);
begin
Insert(Length(FData), Values);
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Value: T): NativeInt;
var
i: Integer;
begin
Result := -1;
if (AIndex > Length(FData)) or (AIndex < 0) then
Exit;
SetLength(FData, Length(FData) + 1);
MoveArray(FData, AIndex, AIndex + 1, Length(FData) - AIndex);
FData[AIndex] := Value;
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: array of T)
: NativeInt;
var
i: Integer;
begin
SetLength(FData, Length(FData) +Length(Values));
MoveArray(FData, AIndex, AIndex + Length(Values), Length(FData) - AIndex);
for i := 0 to Length(Values) - 1 do
FData[AIndex + i] := Values[i];
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: TArray<T>)
: NativeInt;
var
i: Integer;
begin
SetLength(FData, Length(FData) + Length(Values));
MoveArray(FData, AIndex, AIndex + Length(Values), Length(FData) - AIndex);
for i := 0 to Length(Values) - 1 do
FData[AIndex + i] := Values[i];
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: TArrayEx<T>)
: NativeInt;
begin
Result := Insert(AIndex, Values.ToArray);
end; procedure TArrayEx<T>.Unique();
var
i, J: Integer;
Tmp: TArrayEx<T>;
Flag: Boolean;
begin for i := High(FData) downto Low(FData) do
begin
Flag := False;
for J := High(Tmp.FData) downto Low(Tmp.FData) do
begin
if CompareT(FData[i], Tmp[J]) then
begin
Flag := True;
Break;
end;
end;
if not Flag then
Tmp.Append(FData[i]);
end;
FData := Tmp.FData;
end; { TArrayEx<T>.TEnumerator } constructor TArrayEx<T>.TEnumerator.Create(const AValue: TArray<T>);
begin
FValue := AValue;
FIndex := -1;
end; function TArrayEx<T>.TEnumerator.GetCurrent: T;
begin
Result := FValue[FIndex];
end; function TArrayEx<T>.TEnumerator.MoveNext: Boolean;
begin
Result := False;
if (FIndex >= Length(FValue)) then
Exit; Inc(FIndex);
Result := FIndex < Length(FValue);
end; end.

  

Delphi泛型动态数组的扩展--转贴的更多相关文章

  1. Delphi 的动态数组

    传统的Pascal 语言其数组大小是预先确定的,当你用数组结构声明数据类型时,你必须指定数组元素的个数.专业程序员也许知道些许动态数组的实现技术,一般是采用指针,用手工分配并释放所需的内存. Delp ...

  2. [转]delphi 删除动态数组的指定元素

    type TArr = array of TPoint; {把数组先定义成一个类型会方便许多, 这里仅用 TPoint 测试} {删除动态数组指定元素的过程: 参数 arr 是数组名, 参数 Inde ...

  3. delphi动态数组指针问题

    就一个button事件 procedure TForm1.btn7Click(Sender: TObject); Type TMyArr = array of array of array of In ...

  4. 扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法

    扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法 在C#中对泛型的扩展,输入参数是泛型本身的内容,返回值则是bool.基于这一点, ...

  5. Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)

    一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...

  6. delphi 静态3维数组。 严重占用堆栈 切记。 应该用动态数组, 非要用静态数组的话, 要在编译器里 把 堆栈 调大

    delphi 代码正确, 但是运行就崩溃. 原因为 定义了  一些   静态3维数组. 应该扩大 软件的 堆栈 设置.    然后正常解决问题 静态3维数组.   严重占用堆栈   切记. 应该用动态 ...

  7. 一篇文章让你了解动态数组的数据结构的实现过程(Java 实现)

    目录 数组基础简单回顾 二次封装数组类设计 基本设计 向数组中添加元素 在数组中查询元素和修改元素 数组中的包含.搜索和删除元素 使用泛型使该类更加通用(能够存放 "任意" 数据类 ...

  8. [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)

    [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...

  9. 常用数据结构-线性表及Java 动态数组 深究

    [Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...

随机推荐

  1. PAT乙级01

    1001 害死人不偿命的(3n+1)猜想 (15)(15 分) 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反 ...

  2. SSH入门常用命令

    一.参考链接大猫的博客

  3. 11 tensorflow在tf.while_loop循环(非一般循环)中使用操纵变量该怎么做

    代码(操纵全局变量) xiaojie=1 i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_c ...

  4. 记录今天客户的SQLSERVER启动不起来( 错误9003)的解决过程2013-11-26

    记录今天客户的SQLSERVER启动不起来( 错误9003)的解决过程2013-11-26 今天一大早上班就接到客户的电话,说:SQLSERVER启动不起来,业务系统使用不了 于是我就使用QQ远程,帮 ...

  5. scrapy简单入门及选择器(xpath\css)

    简介 scrapy被认为是比较简单的爬虫框架,资料比较齐全,网上也有很多教程.官网上介绍了它的四种安装方法,PyPI.Conda.APT.Source,我们只介绍最简单的安装方法. 安装 Window ...

  6. [翻译] UPCardsCarousel

    UPCardsCarousel UPCardsCarousel is a carousel with a cards based UI for iOS. UPCardsCarousel是一个旋转木马效 ...

  7. symfony学习笔记2—纯的PHP代码和symfony的区别

    Symfony vs 纯PHP为啥symfony比普通的php文件访问要好?这一章我们写一个简单的php文件项目,然后组织它,你会发现为什么web应用会发展到现在这个样子.最后我们将学习symfony ...

  8. python -wordcloudan云词安装

    1安装网站:https://download.lfd.uci.edu/pythonlibs/u2yrk7ps/wordcloud-1.4.1-cp36-cp36m-win_amd64.whl 2安装过 ...

  9. java枚举学习入门

    一.前言  在java编程过程中,我们通常需要定义一些固定数量的常量,在jdk1.5以前,通常的做法是定义一个静态常量类,但自jdk1.5后,java引入了枚举(关键字enum,全称为 enumera ...

  10. 「GXOI / GZOI2019」旅行者

    题目 我还是太傻了 考虑每一条边的贡献,对于一条有向边\((u,v,w)\),我们求出\(k\)个关键点中到\(u\)最近的距离\(dis_1\),以及\(v\)到\(k\)个关键点中最近的距离\(d ...