DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: pixelcraft
今日帖子: 59
在线用户: 15
导航: 论坛 -> 文档资料 斑竹:liumazi,ruralboy  
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 9:43:18
标题:
快速统计0-6个出现的个数 浏览:2487
加入我的收藏
楼主: 条件组:
03 08 09 10 14 18 20 22/0~1~2~3~4
08 10 13 15 20 22 24 29/0~1~2~3~4
01 06 09 11 12 13 14 18/0~1~2~3~4
07 09 10 12 13 20 24 30/0~1~2~3~4
03 07 10 14 21 30 32/0~1~2~3~4
03 08 14 20 24 30/0~1~2~3
03 09 13 14 16 17 27 31/0~1~2~3~4
01 06 07 08 10 12 14/0~1~2~3~4
03 04 09 12 19 22 23 28/0~1~2~3~4
03 11 12 17 22 24 26/0~1~2~3~4
01 04 13 15 16 19 23 32/0~1~2~3~4
04 10 14 16 17 23 27 31/0~1~2~3~4
02 09 12 16 17 22 24/0~1~2~3~4
11 13 17 19 23 26 28 29 32/0~1~2~3~4~5
03 04 09 13 15 22 26/0~1~2~3~4
06 11 16 22 23 25 30/0~1~2~3~4
02 03 06 09 10 18 23 24 31/0~1~2~3~4~5
02 05 10 17 21 28/0~1~2~3
01 06 07 19 25 26/0~1~2~3
07 11 16 21 25 31/0~1~2~3
04 07 12 18 19 21 24 26 28/0~1~2~3~4~5
02 05 06 20 25 26 27 33/0~1~2~3~4
04 05 06 11 19 22 25/0~1~2~3~4
01 04 13 19 23 28 31 33/0~1~2~3~4
02 06 17 18 21 27 33/0~1~2~3~4
01 02 05 15 18 26 27/0~1~2~3~4
01 05 15 23 24 27/0~1~2~3
01 12 18 21 24 27 28 31 33/0~1~2~3~4~5
12 13 21 27 29 31 32 33/0~1~2~3~4
05 08 09 18 29 30 31/0~1~2~3~4
04 08 14 15 28 29 31 32/0~1~2~3~4
04 08 14 27 28 29 32 33/0~1~2~3~4
21 29 32/0~1~2

统计【01 05 15 19 26 29】在条件组的每一行出现0到6个的个数。

实际统计结果:
[0]-11    [1]-9     [2]-8     [3]-4     [4]-1     [5]-0     [6]-0

我用的是遍历的方式,但效率太低了。

请高手指教用什么算法快速统计,谢谢!
----------------------------------------------
tianyang
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 9:45:12
1楼: [0] 03 08 09 10 14 18 20 22/0~1~2~3~4
[2] 08 10 13 15 20 22 24 29/0~1~2~3~4
[1] 01 06 09 11 12 13 14 18/0~1~2~3~4
[0] 07 09 10 12 13 20 24 30/0~1~2~3~4
[0] 03 07 10 14 21 30 32/0~1~2~3~4
[0] 03 08 14 20 24 30/0~1~2~3
[0] 03 09 13 14 16 17 27 31/0~1~2~3~4
[1] 01 06 07 08 10 12 14/0~1~2~3~4
[1] 03 04 09 12 19 22 23 28/0~1~2~3~4
[1] 03 11 12 17 22 24 26/0~1~2~3~4
[3] 01 04 13 15 16 19 23 32/0~1~2~3~4
[0] 04 10 14 16 17 23 27 31/0~1~2~3~4
[0] 02 09 12 16 17 22 24/0~1~2~3~4
[3] 11 13 17 19 23 26 28 29 32/0~1~2~3~4~5
[2] 03 04 09 13 15 22 26/0~1~2~3~4
[0] 06 11 16 22 23 25 30/0~1~2~3~4
[0] 02 03 06 09 10 18 23 24 31/0~1~2~3~4~5
[1] 02 05 10 17 21 28/0~1~2~3
[3] 01 06 07 19 25 26/0~1~2~3
[0] 07 11 16 21 25 31/0~1~2~3
[2] 04 07 12 18 19 21 24 26 28/0~1~2~3~4~5
[2] 02 05 06 20 25 26 27 33/0~1~2~3~4
[2] 04 05 06 11 19 22 25/0~1~2~3~4
[2] 01 04 13 19 23 28 31 33/0~1~2~3~4
[0] 02 06 17 18 21 27 33/0~1~2~3~4
[4] 01 02 05 15 18 26 27/0~1~2~3~4
[3] 01 05 15 23 24 27/0~1~2~3
[1] 01 12 18 21 24 27 28 31 33/0~1~2~3~4~5
[1] 12 13 21 27 29 31 32 33/0~1~2~3~4
[2] 05 08 09 18 29 30 31/0~1~2~3~4
[2] 04 08 14 15 28 29 31 32/0~1~2~3~4
[1] 04 08 14 27 28 29 32 33/0~1~2~3~4
[1] 21 29 32/0~1~2
实际统计数据
----------------------------------------------
tianyang
作者:
男 newbuyer (newbuyer) ★☆☆☆☆ -
普通会员
2022/10/9 9:52:44
1楼: 输入数看不太懂, 姑且猜一下:
假设一个数组 yALL: array[0..YourMaxValue] of Byte/Word;

FillChar(yALL, sizeof(yALL), 0);
for each c:Byte in InputData do
 Inc(yALL[c]);

for each c:Byte in [1,5,15,19,26,29] do
  Writeln('Count of '+c+' is ', yALL[c]);
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 10:20:34
2楼: 非常感谢newbuyer !!


输入数是01,05,15,19,26,29(string) 假如是s
条件组(上面的多行)用的是TStringList  假若是AA

我没有说清楚,其实就是统计S在AA中出0个的有几个,出1个的有几个...出6个的有几个。

希望用以下方式来实现:

procedure xxxx();

其中s、AA可以用全局变量,统计的结果也可以用全局数组变量!

再次感谢newbuyer!!
----------------------------------------------
tianyang
作者:
男 z_y_b_delphi (z_y_b_delphi) ★☆☆☆☆ -
普通会员
2022/10/9 10:53:17
3楼: 怎么不用正则表达式?
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 11:13:14
4楼: @z_y_b_delphi 请赐教,谢谢!
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 11:18:46
5楼: 是文本还是什么格式?这么点数据,计算不到1毫秒
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 11:21:35
6楼: @hq200306谢谢, 是文本

数据量比较大,我仅提供了一个样式而已
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 11:22:56
7楼: 有多大,1g?估计也不到一秒
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 11:29:11
8楼: @hq200306谢谢回复!

最大的条件组有5000多行,条件组有2000左右
输入数是01,05,15,19,26,29(string) 假如是s,这个输入数有近10万个

累计的话很多了
----------------------------------------------
tianyang
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/9 12:00:19
9楼: 没看懂你要干啥……
每行"/0~1~2~3~4~5"是没用的部分?
你至少需要用文字描述一遍,统计过程的细节.怎么得到的最终结果。
例如,以1个"S"和5行的"AA"来举例。
----------------------------------------------
z@S7
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 12:38:56
10楼: 是的,我没有说明白


例如:(AA)

03 08 09 10 14 18 20 22
08 10 13 15 20 22 24 29
01 06 09 11 12 13 14 18
07 09 10 12 13 20 24 30
03 07 10 14 21 30 32


有上面5行字符串,假设变量是AA:TStringList

统计01,05,15,19,26,29(假设变量是S:String)在AAZ中每行中出现的个数

实际结果是:

[0] 03 08 09 10 14 18 20 22
[2] 08 10 13 15 20 22 24 29
[1] 01 06 09 11 12 13 14 18
[0] 07 09 10 12 13 20 24 30
[0] 03 07 10 14 21 30 32

现在是想输出 0的个数,1的个数 ...6的个数

上面的结果是0有3个,1,有1个,2有1个 3到6有0个
我用的是遍历,一个一个的统计计算,但数据量比较大(上面仅是例子)比较慢,请高手们看看有什么比较快的方法实现统计,谢谢!
最好是delphi7
----------------------------------------------
tianyang
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2022/10/9 12:51:12
11楼: 1)统计S中逗号分割的每个2位字符串,在AA[]字符串中出现的个数(总和),记为Sum[]。
2)统计Sum[]取值的情况分布(因为S中的值只有6个,所以sum[x]取值只能是0到6)。

应该是这个意思吧。
----------------------------------------------
Bye bye DDRFAN...
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/9 12:56:27
11楼: 举个例,你是怎么判断"15"存在于"03 08 09 10 14 18 20 22"的?
是Pos('15','03 08 09 10 14 18 20 22')>0 ?

另外,我猜你大概可以用多线程或并行计算来增加处理速度。
----------------------------------------------
z@S7
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2022/10/9 12:59:12
12楼: 用字符串对比? 转整数 消耗会不会小点?
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 13:47:25
13楼: @ddrfan 是的
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 13:52:19
14楼: 按12楼思路,转数字比较

1、把“条件组”转byte
2、把第二组转byte集 合
3、for循环一下就出来了

你说5000*2000,估计花不了一秒时间
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 13:54:36
15楼: @ hq200306  能大概写一下程序吗?不胜感谢!
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 13:59:38
16楼: @tianyang 你自己练习一下,,优化的时间是花在字符在转数字
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 14:16:24
17楼: function Cfgs(s1: string; s2: string): INTEGER;
var i, j, HMS: integer;
begin
  s1 := trim(s1);
  HMS := LENGTH(S1) + 1;
  HMS := TRUNC(HMS / 3);
  s2 := trim(s2); j := 0;
  for i := 1 to HMS do
    if POS(COPY(S1, (I - 1) * 3 + 1, 2), s2) > 0 then j := j + 1;
  Cfgs := J;
end;

我计算两个字符串的重复个数的方法
 Cfgs('01,05,15,19,26,29','01 02 06 08 09 10 11 14 17 18 22 23 24 31 32')
返回的是重复的个数

按照高手们的说法转byte,该怎么改?
----------------------------------------------
tianyang
作者:
男 ddrfan (若苗瞬) ▲▲▲▲▲ -
普通会员
2022/10/9 15:00:47
18楼: 可能大家没看清LZ说的数据量。

1)
最大的条件组有5000多行,条件组有2000左右
5000*2000,是条件AA全部条数。

2)
输入数有近10万个,是S个数。
----------------------------------------------
Bye bye DDRFAN...
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 15:12:59
19楼: 有个软件对上面的统计,上亿的数据量,统计时间0.4秒,真是佩服,可惜高手联系不上!
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 15:17:40
20楼: 是分析博 彩 码?
这么点数据花不了1秒钟
----------------------------------------------
-
作者:
男 wangdonghai (wdh) ★☆☆☆☆ -
盒子活跃会员
2022/10/9 15:28:58
21楼: //先用一组数据测试
procedure DataTotal(const AStr: string; const ACondStrings,
  ARsStrings: TStrings);
var
  sList,sRsList: TStringList;
  i,j,iC: Integer;
  sName,sValue: string;
begin
  sList := nil;
  sRsList := nil;
  try
    sRsList := TStringList.Create;
    sRsList.Sorted := True;
    sList := TStringList.Create;
    sList.DelimitedText := AStr;
    ARsStrings.Clear;
    for i:=0 to ACondStrings.Count-1 do
    begin
      iC := 0;
      for j:=0 to sList.Count-1 do
        if Pos(sList[j],ACondStrings[i])>0 then
          Inc(iC);

      sName := IntToStr(iC);
      if ARsStrings.IndexOfName(sName)=-1 then
        ARsStrings.Add(sName+'=1')
      else begin
        sValue := ARsStrings.Values[sName];
        ARsStrings.Values[sName] := IntToStr(StrToInt(sValue)+1);
      end;
    end;
    for j:=0 to sList.Count do
    begin
      sName := IntToStr(j);
      if ARsStrings.IndexOfName(sName)=-1 then
        ARsStrings.Add(sName+'=0');
    end;
    //排序
    sRsList.Clear;
    sRsList.Assign(ARsStrings);
    ARsStrings.Clear;
    ARsStrings.Assign(sRsList);
  finally
    sRsList.Free;
    sList.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  edit1.Text := '01 05 15 19 26 29';//输入数据
  //Memo1.Text是条件组数据
  //Memo2显示结果
  DataTotal(edit1.Text,Memo1.Lines,Memo2.Lines);
end;
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 15:49:51
22楼: @wangdonghai 谢谢,我测试一下
----------------------------------------------
tianyang
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2022/10/9 16:12:24
23楼: 按此在新窗口浏览图片
内存换时间 加上 固态 加上 simd指令集
要快也行的。
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 16:24:24
24楼: 条件组:

02 03 04 05 07 08 09 10 11 13 14 15 17 18 19 20 22 24 25 27 28 29 31 33
01 02 03 04 05 06 09 11 12 13 15 16 17 19 20 22 24 25 27 28 29 31 32 33
01 04 05 06 08 09 10 11 15 16 17 18 19 20 23 24 25 26 27 28 29 31 32 33
01 02 03 08 09 10 12 13 14 15 16 17 19 20 21 22 23 24 26 27 29 31 32 33
01 02 03 04 05 06 08 09 10 11 12 13 15 19 21 22 24 26 27 28 29 31 32 33
02 03 04 05 06 07 08 09 10 12 13 14 18 19 20 22 23 24 25 26 27 29 31 33
01 02 03 04 05 06 08 10 12 13 14 15 17 18 20 21 22 24 26 27 28 31 32 33
01 02 07 08 09 10 11 12 13 15 16 17 18 19 20 21 22 23 24 25 28 30 31 32
01 03 05 06 07 08 10 11 13 15 16 17 18 21 22 23 24 26 27 28 29 30 31 32
01 03 05 06 07 09 10 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29
02 05 06 07 08 09 10 11 12 14 15 16 17 18 20 22 23 25 26 28 29 31 32 33
02 05 07 08 09 10 11 12 13 14 15 16 17 20 22 23 24 25 26 27 29 30 31 32
01 02 03 05 08 09 10 11 13 14 15 16 17 18 19 20 23 24 25 26 27 29 31 32
04 05 07 09 10 12 14 15 16 17 18 19 20 21 23 24 25 26 28 29 30 31 32 33
01 02 05 07 09 10 11 13 15 16 17 18 19 20 21 22 23 24 25 28 29 30 31 33
01 02 06 07 09 10 11 13 14 17 18 19 20 21 23 24 26 27 28 29 30 31 32 33
01 04 05 06 07 08 10 11 12 13 14 15 16 17 20 22 23 24 25 27 28 29 31 33
02 07 08 09 10 11 12 13 14 15 18 20 21 22 23 24 25 26 27 28 29 30 31 33
03 04 05 06 07 08 09 10 12 14 15 16 17 18 19 20 25 26 27 28 30 31 32 33
02 03 05 09 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 27 30 31 32 33
01 02 04 06 10 11 12 13 14 15 16 17 18 19 21 22 23 24 25 27 29 30 31 32
01 02 03 04 09 10 11 13 14 15 16 17 18 20 21 22 23 24 25 26 27 29 32 33
02 03 04 05 06 07 09 10 12 16 17 18 19 20 21 22 25 26 27 29 30 31 32 33
02 04 05 06 07 08 09 10 11 13 15 17 19 20 21 22 24 25 27 28 29 30 32 33
01 04 05 06 07 08 09 10 11 12 14 15 17 18 19 20 22 24 25 26 27 28 31 32
01 02 03 04 05 07 09 10 11 13 14 15 16 17 18 19 20 23 24 26 27 28 31 32
01 02 03 04 06 07 09 11 13 14 15 16 17 18 23 24 25 26 27 29 30 31 32 33
01 02 03 06 07 08 09 11 12 15 17 18 19 20 21 22 23 24 26 27 29 31 32 33
01 03 05 08 09 11 12 13 14 15 16 18 19 21 22 24 26 27 28 29 30 31 32 33
01 03 05 06 07 08 10 11 14 15 16 18 19 21 22 23 24 25 27 28 29 31 32 33
01 03 04 05 06 09 10 12 14 15 16 17 18 19 20 23 24 25 26 27 28 29 30 33
01 02 04 05 08 09 11 13 14 15 18 19 20 22 23 24 25 26 27 29 30 31 32 33
01 02 03 05 07 08 09 10 11 12 13 15 16 19 20 21 22 23 24 27 28 29 30 31


统计结果应该是:
[0]-0     [1]-0     [2]-0     [3]-3     [4]-13    [5]-10    [6]-7
运行您的结果是
0=32
1=1
2=0
3=3
4=13
5=11
6=6


03 08 09 10 14 18 20 22
08 10 13 15 20 22 24 29
01 06 09 11 12 13 14 18
07 09 10 12 13 20 24 30
03 07 10 14 21 30 32
是对的
----------------------------------------------
tianyang
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/9 16:27:02
25楼: 完犊子了,才疏学浅了,没研究明白newbuyer的
==========
假设一个数组 yALL: array[0..YourMaxValue] of Byte/Word;

FillChar(yALL, sizeof(yALL), 0);
for each c:Byte in InputData do
 Inc(yALL[c]);

for each c:Byte in [1,5,15,19,26,29] do
  Writeln('Count of '+c+' is ', yALL[c]);
==========
怎么鼓捣都是Pos更快一点……
----------------------------------------------
z@S7
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 16:35:03
26楼: @wangdonghai (wdh)

谢谢!

单个条件组测试成功!!

不知道加大数据量有什么效果。


不管怎么样,非常感谢!!
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 16:44:31
27楼: 想提高速度,用byte类型比较,字符串慢
----------------------------------------------
-
作者:
男 tianyang (tianyang) ★☆☆☆☆ -
普通会员
2022/10/9 16:45:40
28楼: @hq200306

就是因为自己水平很差,想让高手指教一下!按此在新窗口浏览图片
----------------------------------------------
tianyang
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 16:48:37
29楼: 数据量小无所谓,如果数据量大要自己写算法,只是说,按字符串去比较没有什么效率,如果写好算法,估计能提高几十倍速度
----------------------------------------------
-
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 17:48:57
30楼: 我试了下5万的数字,在2千个集 合比较,0.23秒,程序其余的时间就是字符串转数字的时间了。

procedure TForm4.SpeedButton1Click(Sender: TObject);
var
  bs: set of byte;
  i, k: Integer;
  j: byte;
  d1: TStopwatch;
  b: Boolean;
begin
  bs := [];
  for I := 1 to 10 do
  begin
    bs := bs + [i];
  end;

  b := false;

  d1 := TStopwatch.StartNew;
  for I := 1 to 5000 * 10 do
  begin
    j := i mod 100;

    for k := 1 to 2000 do
    begin
      if j in bs then
      begin
        b := true;
      end;
    end;
  end;

  d1.Stop;

  Caption := d1.ElapsedMilliseconds.ToString + '/' + b.ToString();
end;

我的估算,5000*2000,计算时间小于1秒
----------------------------------------------
-
作者:
男 hq200306 (200306) ★☆☆☆☆ -
普通会员
2022/10/9 18:04:16
31楼: 可优化地方太多,如果把集 合改为位运算,时间还要减半
----------------------------------------------
-
作者:
男 newbuyer (newbuyer) ★☆☆☆☆ -
普通会员
2022/10/9 23:37:08
32楼: @zhyhero
这是常用的查表, 空间换时间.

先把输入元素转换为byte数组, 
例如输入值是yx=[8,3,20]

yALL是一个例如255个元素的byte数组,都被填0.

遇到第i个输入元素例如8, 则将yALL[yx[1]]即是yALL[8]值加一.

一个循环下来, yALL里每个元素就是输入数组的元素出现次数.

楼主的情况这种方法也可用, 但是每行元素的数据比较少, 所以效率也应该提高不了多少, 每次清空yALL可能得不偿失, 可考虑分批处理, 例如yALL变成100个元素的二维数组 array[0..99] of array[0..33] of Byte, 每批处理100个输入行然后清零. 有点烦不知道是否值得. 不是算法行家就不献丑了. 

严格来说我觉得这个数据量不大的确转换为byte数组后逐个比较也完全够用.
----------------------------------------------
-
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2022/10/10 1:25:29
33楼: 有哪种高效的'23'(string)转换成23(byte)的方法么?

我感觉如果原始数据固定从String开始的话,时间都浪费在字符拆分和类型转换上了。大量的时间消耗最终会抵消掉用Byte来比较的速度优势。
----------------------------------------------
z@S7
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/10/10 2:00:42
34楼: 老实说,我没看懂楼主的需求。

不过我猜是彩那个票?
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/10 3:58:59
35楼: my tests... or would be tries!!  >:))

Using "STRINGS" as input values or conditions"

implementation

{$R *.dfm}

uses
  System.Generics.Collections;

type
  TMyDictPair = record
    Key: string;
    Value: integer;
  end;

  TMyArrDictPairs = array of TMyDictPair;

var
  MyTextWithValues    : string;
  MyTextWithConditions: string;

procedure TViewMyArrDictForm.BtnVerifyConditionsClick(Sender: TObject);
var
  MyArrDictPairs  : TMyArrDictPairs;
  MyDictPair      : TMyDictPair;
  MyDictText      : TArray<string>; // array of string;
  MyDictConditions: TArray<string>; // array of string;
  LIndexFound     : integer;
  MyGetTicks      : UInt64;
  // **********//
  function FindMyKeyOnDictPairs(const AArrDictPairs: TMyArrDictPairs; const AKey: string): integer;
  begin
    result := -1;
    //
    for var i: integer := 0 to high(AArrDictPairs) do
      if (AArrDictPairs[i].Key = AKey) then
        exit(i);
  end;

  function FindMyKeyOnText(const AArrText: TArray<string> { array of string }; const AKey: string; const ALastPos: integer): integer;
  var
    LIndex: integer;
  begin
    result := -1;
    //
    for var i: integer := 0 to high(AArrText) do
      if (ALastPos < i) and (AArrText[i] = AKey) then
        begin
          result          := i;
          LIndex          := FindMyKeyOnDictPairs(MyArrDictPairs, AKey);
          MyArrDictPairs[LIndex].Value := MyArrDictPairs[LIndex].Value + 1;
        end;
  end;

  procedure DontRepeatConditions;
    function MyFuncDontDuplicates(const ArrValor: TArray<string>; const AVal: string): integer;
    begin
      result := -1;
      //
      for var i: integer := 0 to high(ArrValor) do
        if ((ArrValor[i]) = (AVal)) then
          exit(i);
    end;

  var
    ArrTmp    : TArray<string>;
    BeforeItem: string;
    LIndex    : integer;
  begin
    LIndex := -1;
    //
    // ArrTmp := MyDictConditions; ...  cause "memory pointer sharing "!!!
    //
    for var MyItem in MyDictConditions do // better this way!!!
      ArrTmp := ArrTmp + [MyItem];
    //
    TArray.Sort<string>(MyDictConditions);
    //
    BeforeItem := '';
    //
    for var MyItem in MyDictConditions do
      begin
        if (MyItem = BeforeItem) then
          begin
          LIndex := MyFuncDontDuplicates(ArrTmp, MyItem);
          //
          if LIndex > -1 then
          Delete(ArrTmp, LIndex, 1);
          end;
        //
        BeforeItem := MyItem;
      end;
    //
    if Length(MyDictConditions) <> Length(ArrTmp) then
      MyDictConditions := ArrTmp;
  end;

// **********//
begin
  //
  // MyDictText       := ['10', '53', '34', '01', '94', '86', '42', '71', '01', '76', '84', '100', '2010', '01', '91'];
  // MyDictConditions := ['01', '34', '45', '91', '84', '103', '33', '05', '9', '26'];
  //
  // MyDictText       := '10 53 34 01 94 86 42 71 01 76 84 100 2010 01 91 33 40 82 10 10 33 21 14 9820 1201'.Split([' ']); // creating a "TArray<string>"
  // MyDictConditions := '01 34 45 91 84 103 33 05 9 26 01 10'.Split([' ']);
  //
  MyDictText       := MyTextWithValues.Split([' '], TStringSplitOptions.ExcludeEmpty); // creating a "TArray<string>"
  MyDictConditions := MyTextWithConditions.Split([' '], TStringSplitOptions.ExcludeEmpty);
  //
  DontRepeatConditions; // unique value in conditions!
  //
  Memo1.Text := 'my list of values:';
  Memo1.Lines.Add(''.Join(',', MyDictText));
  Memo1.Lines.Add(slinebreak + 'My list of conditions:');
  Memo1.Lines.Add(''.Join(',', MyDictConditions));
  Memo1.Lines.Add('**********');
  //
  // ---------- Preparing... ---------- //
  for var M1 in MyDictText do
    begin
      MyDictPair.Key   := M1;
      MyDictPair.Value := 0;
      //
      if (FindMyKeyOnDictPairs(MyArrDictPairs, M1) = -1) then
        MyArrDictPairs := MyArrDictPairs + [MyDictPair];
    end;
  //
  Memo1.Lines.Add(slinebreak + '********** Dict prepared **********');
  //
  Memo1.Lines.Add('Total values: ' + Length(MyDictText).ToString);
  Memo1.Lines.Add('Total conditions: ' + Length(MyDictConditions).ToString);
  //
  { Memo1.Lines.BeginUpdate;
    try
    for var M2 in MyArrDictPairs do
    Memo1.Lines.Add(M2.Key + ', ' + M2.Value.ToString);
    finally
    Memo1.Lines.EndUpdate;
    end; }
  //
  MyGetTicks := GetTickCount64;
  // ---------- searching... ----------//
  LIndexFound := -2;
  //
  for var M3 in MyDictConditions do
    begin
      while (LIndexFound <> -1) do
        LIndexFound := FindMyKeyOnText(MyDictText, M3, LIndexFound);
      //
      LIndexFound := -2;
    end;
  //
  Memo1.Lines.Add('======== Search Time: ' + (GetTickCount64 - MyGetTicks).ToString + 'ms ========');
  //
  Memo1.Lines.BeginUpdate;
  try
    for var M2 in MyArrDictPairs do
      Memo1.Lines.Add(M2.Key + ', ' + M2.Value.ToString);
  finally
    Memo1.Lines.EndUpdate;
  end;
end;

procedure TViewMyArrDictForm.BtnCreateATextToVerifyClick(Sender: TObject);
var
  MyGetTicks: UInt64;
begin
  MyTextWithValues     := '';
  MyTextWithConditions := '';
  //
  Memo1.Lines.Add(slinebreak + '---------- VALUE: ----------');
  //
  MyGetTicks := GetTickCount64;
  //
  for var i: integer := 1 to 20000 do
    MyTextWithValues := Format(MyTextWithValues + '%d ', [random(1000) + 1]);
  //
  MyTextWithValues := MyTextWithValues.Trim;
  //
  Memo1.Text := MyTextWithValues;
  Memo1.Lines.Add(slinebreak + '======== Time: ' + (GetTickCount64 - MyGetTicks).ToString + 'ms ========');
  //
  Memo1.Lines.Add(slinebreak + '---------- CONDITIONS: ----------');
  //
  for var i: integer     := 1 to 100 do
    MyTextWithConditions := Format(MyTextWithConditions + '%d ', [random(1000) + 1]);
  //
  MyTextWithConditions := MyTextWithConditions.Trim;
  //
  Memo1.Lines.Add(MyTextWithConditions);
end;

initialization

ReportMemoryLeaksOnShutdown := True;
randomize;

finalization

end.
此帖子包含附件:
PNG 图像
大小:80.9K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/10 4:00:47
36楼: using TDictionary<string, integer>... and TRegEx...

----------
  MyDict          : TDictionary<string, integer>;
  MyDictText      : array of string;
  MyDictConditions: array of string;
begin
  MyDict := TDictionary<string, integer>.Create;
  //
  MyDictText       := ['01', '34', '45', '91', '84', '103', '33', '34', '05', '9', '26', '45', '01', '01'];
  MyDictConditions := ['10', '53', '34', '01', '94', '86', '42', '71', '01'];
  //
  SW.StartNew;
  //
  for var M1 in MyDictText do
    if not MyDict.ContainsKey(M1) then
      begin
        MyDict.Add(M1, 0);
        Memo1.Lines.Add(M1);
      end;
  //
  SW.Stop;
  Memo1.Lines.Add('Time: ' + SW.ElapsedMilliseconds.ToString);
  //
  Memo1.Lines.Add('----------');
  //
  for var M2 in MyDictConditions do
    if MyDict.ContainsKey(M2) then
      MyDict.Items[M2] := MyDict.Items[M2] + 1;
  //
  Memo1.Lines.BeginUpdate;
  try
    for var M3 in MyDict.Keys do
      Memo1.Lines.Add(M3 + ', ' + MyDict.Items[M3].ToString);
  finally
    Memo1.Lines.EndUpdate;
  end;
  //
  exit;
  //
  RE_01 := '(45|01)';
  Text  := '01 34 45 91 84';
  //
  MTConditions := ['01', '34', '45', '91', '84', '103', '33', '34', '05', '9', '26', '45', '01', '01'];
  //
  MTMaxValueOnConditions := 103; // => MTConditions := [...,'103',...]
  //
  for var a: integer := 0 to MTMaxValueOnConditions do
    MTResult         := MTResult + [0];
  //
  RE := TRegEx.Create('');
  //
  SW.StartNew;
  //
  for var b: integer          := 0 to high(MTConditions) do // inc( var, n-value) ...
    MTResult[MTConditions[b].ToInteger - 1] := MTResult[MTConditions[b].ToInteger - 1] + integer(RE.IsMatch(Text, '(' + MTConditions[b] + ')'));
  //
  SW.Stop;
  //
  Memo1.Lines.Add('Time: ' + SW.ElapsedMilliseconds.ToString);
  //
  Memo1.Lines.BeginUpdate;
  try
    for var c: integer := 0 to MTMaxValueOnConditions do
      Memo1.Lines.Add('C: ' + c.ToString + ' = ' + MTResult[c].ToString);
  finally
    Memo1.Lines.EndUpdate;
  end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/10 4:07:41
37楼: screentshot
此帖子包含附件:
PNG 图像
大小:70.4K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/10 4:24:50
38楼: screenshot
此帖子包含附件:
PNG 图像
大小:33.2K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2022/10/10 4:35:58
39楼: using "SORTED" lists, you can (maybe) win more time on searches...! >:)

dividing your "big list of values" you can works with pieces of block, then, you time can be more usable, I think!

20.000 / 99 = 16ms
100.000 / 491 = 375ms

5 x 16ms = 80ms! = 100.000 values
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 1111111113 (1111111113) ▲△△△△ -
普通会员
2022/10/10 10:00:22
40楼: 并行被遗忘了?

给定以下在一维数组中查找奇数的简单任务:
 https://stackoverflow.com/questions/27535045/tparallel-for-performance/27542557#27542557
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行109.375毫秒 RSS