我memo1中有形如
1,2,3,4,5,6,7
1,2,3,4,5,6,8
1,2,3,4,5,6,9
1,2,3,4,5,6,10
1,2,3,4,5,7,8
1,2,3,4,5,7,9
1,2,3,4,5,7,10
1,2,3,4,5,8,9
1,2,3,4,5,8,10
1,2,3,4,5,9,10
1,2,3,4,6,7,8
1,2,3,4,6,7,9
1,2,3,4,6,7,10
1,2,3,4,6,8,9
1,2,3,4,6,8,10
1,2,3,4,6,9,10
1,2,3,4,7,8,9
1,2,3,4,7,8,10
1,2,3,4,7,9,10
1,2,3,4,8,9,10
1,2,3,5,6,7,8
1,2,3,5,6,7,9
1,2,3,5,6,7,10
1,2,3,5,6,8,9
若干行,每行不会完全重复并由小到大排好了序,我要达到如下目的:
先从第一行开始,第二行到最后一行去和第一行比较,有6个数字相同的就将该行添加到memo2中,再拿第三行至最后行和第二行比较,有6个数字相同的就将该行添加到memo2中,以此类推。我写的代码如下:不知道对不对,请指教,谢谢
var
s1,s2,s3:tstringlist;
i,j,k,count:integer;
begin
s1:=tstringlist.Create;
s2:=tstringlist.Create;
s3:=tstringlist.Create;
s1.Assign(memo1.Lines);
memo2.Clear;
for i:=0 to  s1.Count-1 do
   begin
   s1.Delimiter:=',';
   s2.DelimitedText:=s1.Strings[i];//得到比较行数据
   for j:=i+1 to s1.Count-1 do
      begin
        s3.Delimiter:=',';
        s3.DelimitedText:=s1.Strings[j];//得到比较行下一行至最后一行数据
        count:=0;
        for k:=0 to s3.count-1 do  //循环比较行内每个数字
        begin
           if s3.indexof(s2[k])>-1 then
               inc(count);
        end;
        if count>=6 then
        begin
           memo2.Lines.Add(s1.Strings[j]);
           break;
        end;
      end;
   end;
end;

解决方案 »

  1.   

    for j:=i+1 to s1.Count-1 do
    这句话有问题吧,为什么从i+1开始呢,就是从i+1开始,表示从下一个字符串开始,那为什么以s1.Count-1为结束呢,s1.Count是s1的字符个数,和i没有任何关系
    假如你的 i到了100,那么s1.Count才多少啊,你这个循环根本进不去
      

  2.   

    源代码,你看一下,中午没睡觉……
    加入两个Memo、4个Button4。下面是代码,一个大循环,一个递归小函数就搞定了。
    实在没啥说的,其实可以做一个大循环,从下面向上计数,用类似:
    36=0//36是数字,统计36出现的次数,0代表0次
    35=2//这里是35出现了2次,以此类推……
    ……
    的字符串列表,前面是字符,后面用来表示统计次数,倒着数,达到5个就可以加,然后就不用计数了,前面的只要包含这个数字就肯定超过5个,这样不浪费。不过懒的写了,嘿嘿,自己改吧。
    unit Unit1;interfaceuses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,math;type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      s1,s2,s3:tstringlist;
      i,j,k,count:integer;
    begin
      s1:=tstringlist.Create;
      s2:=tstringlist.Create;
      s3:=tstringlist.Create;
      s1.Assign(memo1.Lines);
      memo2.Clear;
      for i:=0 to s1.Count-1 do
      begin
        s1.Delimiter:=',';
        s2.DelimitedText:=s1.Strings[i];//得到比较行数据
        for j:=i+1 to s1.Count-1 do
        begin
          s3.Delimiter:=',';
          s3.DelimitedText:=s1.Strings[j];//得到比较行下一行至最后一行数据
          count:=0;
          for k:=0 to s3.count-1 do //循环比较行内每个数字
          begin
            if s3.indexof(s2[k])>-1 then   inc(count);
          end;
          if count>=6 then
          begin
            memo2.Lines.Add(s1.Strings[j]);
            break;
          end;
        end;
      end;
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      i,j,num:integer;
      slLotteryNumbers,slLotteryPrize:tstringlist;
      str:string;
    begin
      sllotterynumbers:=tstringlist.Create;
      sllotteryprize:=tstringlist.Create;  for I := 0 to 30 do
      begin
        sllotterynumbers.Clear;    j:=0;
        while j<7 do //这里不能用for,要排除重复情况
        begin
          num:=random(36);
          //为了格式整齐前面补齐了0,可以不用,结果一样。
          if sllotterynumbers.IndexOf(format('%.2d', [num]))<=0 then
          begin
            sllotterynumbers.Add(format('%.2d', [num]));
            j:=j+1;
          end;
        end;    str:='';
        sllotterynumbers.Sort;
        for j:= 0 to 6 do
        begin
          str:=str+sllotterynumbers[j]+',';
        end;
        sllotteryprize.Add(copy(str,1,length(str)-1));
      end;  self.Memo1.Lines:=sllotteryprize;
    end;procedure TForm1.Button4Click(Sender: TObject);//递归查找字符串
    function intinstr(num:integer;str:string):boolean;
    var
      i:integer;
    begin
      i:=pos(',',str);
      result:=false;  if i>0 then//找到','的情况
      begin
        if num=strtoint(copy(str,1,i-1)) then
        begin
          result:=true;
        end else
        begin
          result:=intinstr(num,copy(str,i+1,length(str)));
        end;
      end else
      if length(str)>0 then//最后一组数字(也可以在字符串最后加上更省事)
      begin
        if num=strtoint(str) then result:=true;
      end;
    end;var
      i,j,k:integer;//循环用变量
      count:integer;//计数器
      slLotteryNumbers,slLotteryPrizes:tstringlist;//号码和奖期两个字符串列表
      slNow,slAlready:tstringlist;//now放置当前的字符串列表,already放置已经找到的
      str:string;//临时字符串
    begin
      //初始化字符串列表
      sllotterynumbers:=tstringlist.Create;
      sllotteryprizes:=tstringlist.Create;
      slalready:=tstringlist.Create;  //先给prize赋值。
      sllotteryprizes:=tstringlist(self.Memo1.Lines);//  //先将第一期的号码放置在now字符串列表中。
      tstringlist(self.Memo1.Lines).Delimiter:=',';
      sllotterynumbers.Text:=self.Memo1.Lines[0];
      str:='';//记录已经找到的数字,不在重复。
      {附带说一下啊,循环也不是上来就for,多长啊!}
      for I := 0 to sllotteryprizes.Count-6 do//后面剩下5个还能出现6次吗?
      begin
        sllotterynumbers.DelimitedText:=sllotteryprizes[i];
        j:=0;//初始化循环变量    while (j<sllotterynumbers.Count-1) do//循环找每一个数字
        begin
          k:=i+1;//初始化循环变量
          count:=0;//初始化计数器
          str:='';//用来标记哪行找到的      while (count<6) and (k<sllotteryprizes.Count) do//到尾或者满足计数
          begin
            if intinstr(strtoint(sllotterynumbers[j]),sllotteryprizes[k]) then
            begin
              count:=count+1;//找到则计数器+1
              str:=str+';'+inttostr(k);//完全可以不加,为了验证
            end;
            k:=k+1;//指针向下
          end;      if count>5 then//满足计数器
          begin
            //slAlready.Add(sllotteryprizes[i]+'='+sllotterynumbers[j]+str);//这里可以验证
            slAlready.Add(sllotteryprizes[i]);//添加列表
            break;
          end;      j:=j+1;
        end;
      end;
      self.Memo2.Lines.BeginUpdate;
      self.Memo2.Lines:=slalready;
      self.Memo2.Lines.EndUpdate;end;end.
      

  3.   

    有问题,问题就是字符串比较不是数字比较。楼主的程序根本不能完成他要的结果,我把他的那个都贴上了,第一个按钮是楼主自己的程序:if s3.indexof(s2[k])>-1 then   inc(count);这里判断是错误的,要转化为数字,'1'、'10'不一样的。第二个按钮是动态创建30个奖期,第四个按钮是我写的,你比较一下就知道了,结果不一样的。还有就是楼主的程序实在有点偷懒,整个一个for嵌套循环……
    感兴趣可以倒过来比较,那样循环一遍就可以了,不用嵌套循环。
      

  4.   

    if s3.indexof(s2[k])>-1 then inc(count)
    这行我改了,应该是<>-1,另外
     if count>=6 then
          begin
            memo2.Lines.Add(s1.Strings[j]);
            break;
          end;
    这里把break去掉,让他循环完。我自己认为是对的
      

  5.   

    发现了一个错误,随机生成号码(我估计就是彩票的分析程序)有重复的情况,
    if sllotterynumbers.IndexOf(format('%.2d', [num]))<=0 then
    应该改成:
    if sllotterynumbers.IndexOf(format('%.2d', [num]))<0 then
    否则可能出现重复的。顺便把倒序查找贴出来,更容易理解,代码也更短,一次循环搞定,不用嵌套。正确的随机生成号码:procedure TForm1.Button2Click(Sender: TObject);
    var
      i,j,num:integer;
      slLotteryNumbers,slLotteryPrize:tstringlist;
      str:string;
    begin
      sllotterynumbers:=tstringlist.Create;
      sllotteryprize:=tstringlist.Create;  for I := 0 to 30 do
      begin
        sllotterynumbers.Clear;    j:=0;
        while j<7 do //这里不能用for,要排除重复情况
        begin
          num:=random(36);
          //为了格式整齐前面补齐了0,可以不用,结果一样。
          if sllotterynumbers.IndexOf(format('%.2d', [num]))<0 then
          begin
            sllotterynumbers.Add(format('%.2d', [num]));
            j:=j+1;
          end;
        end;    str:='';
        sllotterynumbers.Sort;
        for j:= 0 to 6 do
        begin
          str:=str+sllotterynumbers[j]+',';
        end;
        sllotteryprize.Add(copy(str,1,length(str)-1));
      end;  self.Memo1.Lines:=sllotteryprize;
    end;
    顺序查找,多重循环嵌套:
    procedure TForm1.Button4Click(Sender: TObject);//递归查找字符串
    function intinstr(num:integer;str:string):boolean;
    var
      i:integer;
    begin
      i:=pos(',',str);
      result:=false;  if i>0 then//找到','的情况
      begin
        if num=strtoint(copy(str,1,i-1)) then
        begin
          result:=true;
        end else
        begin
          result:=intinstr(num,copy(str,i+1,length(str)));
        end;
      end else
      if length(str)>0 then//最后一组数字(也可以在字符串最后加上更省事)
      begin
        if num=strtoint(str) then result:=true;
      end;
    end;var
      i,j,k:integer;//循环用变量
      count:integer;//计数器
      slLotteryNumbers,slLotteryPrizes:tstringlist;//号码和奖期两个字符串列表
      slAlready:tstringlist;//now放置当前的字符串列表,already放置已经找到的
      str:string;//临时字符串
    begin
      //初始化字符串列表
      sllotterynumbers:=tstringlist.Create;
      sllotteryprizes:=tstringlist.Create;
      slalready:=tstringlist.Create;  //先给prize赋值。
      sllotteryprizes:=tstringlist(self.Memo1.Lines);  //先将第一期的号码放置在now字符串列表中。
      tstringlist(self.Memo1.Lines).Delimiter:=',';
      sllotterynumbers.Text:=self.Memo1.Lines[0];
      str:='';//记录已经找到的数字,不在重复。
      {附带说一下啊,循环也不是上来就for,多长啊!}
      for I := 0 to sllotteryprizes.Count-6 do//后面剩下5个还能出现6次吗?
      begin
        sllotterynumbers.Clear;
        sllotterynumbers.DelimitedText:=sllotteryprizes[i];
        j:=0;//初始化循环变量
        k:=0;
        while (j<sllotterynumbers.Count) do//循环找每一个数字
        begin
          k:=i+1;//初始化循环变量
          count:=0;//初始化计数器
          str:='';//用来标记哪行找到的      while (count<=6) and (k<sllotteryprizes.Count) do//到尾或者满足计数
          begin
            if intinstr(strtoint(sllotterynumbers[j]),sllotteryprizes[k]) then
            begin
              count:=count+1;//找到则计数器+1(计数器是从0开始)
              str:=str+';'+inttostr(k);//完全可以不加,为了验证
            end;
            k:=k+1;//指针向下
          end;      if count>5 then//满足计数器
          begin
            //slAlready.Add(sllotteryprizes[i]+'='+sllotterynumbers[j]+str);//这里可以验证
            slAlready.Add(sllotteryprizes[i]);//添加列表
            break;//找到了,跳出
          end;      j:=j+1;
        end;
      end;
      self.Memo2.Lines.BeginUpdate;
      self.Memo2.Lines:=slalready;
      self.Memo2.Lines.EndUpdate;end;
    逆序查找,少了一层嵌套,也不用break,多了一个含有36个计数器的stringlist,其实可以考虑数组,用序号来表示数字,比我这个还要简洁、清楚。procedure TForm1.Button1Click(Sender: TObject);
    function intinstr(num:integer;str:string):boolean;
    var
      i:integer;
    begin
      i:=pos(',',str);
      result:=false;  if i>0 then//找到','的情况
      begin
        if num=strtoint(copy(str,1,i-1)) then
        begin
          result:=true;
        end else
        begin
          result:=intinstr(num,copy(str,i+1,length(str)));
        end;
      end else
      if length(str)>0 then//最后一组数字(也可以在字符串最后加上更省事)
      begin
        if num=strtoint(str) then result:=true;
      end;
    end;var
      i,j,k:integer;//循环用变量
      count:integer;//计数器
      slLotteryNumbers,slLotteryPrizes:tstringlist;//号码和奖期两个字符串列表
      slAlready,slCount:tstringlist;//already放置已经找到的
      str,stemp:string;//临时字符串
    begin
      {倒序查找}
      //初始化字符串列表
      sllotterynumbers:=tstringlist.Create;
      sllotteryprizes:=tstringlist.Create;
      slalready:=tstringlist.Create;
      slcount:=tstringlist.Create;  for i := 0 to 36 do
      begin
        slcount.Add(inttostr(i)+'='+'0');
      end;  //初始化
      sllotteryprizes:=tstringlist(self.Memo1.Lines);//
      sllotteryprizes.Delimiter:=',';  //倒序匹配很好啊,整个减少了一层循环。而且很容易理解。
      for I := sllotteryprizes.Count-1 downto 0 do//倒序循环
      begin
        sllotterynumbers.DelimitedText:=sllotteryprizes[i];//拆分奖期为号码    stemp:='';//初始化临时字符串
        str:='';
        for j := 0 to sllotterynumbers.Count-1 do
        begin
          str:= inttostr(strtoint(sllotterynumbers[j]));//取得拆分后的数字
          count:=strtoint(slcount.Values[str]);//得到计数器次数
          if (count>5) and (stemp='') then//计数是从1开始,所以应该是>5
          begin
            //这就是发现了
            stemp:=sllotteryprizes[i];
            str:='';
          end;
          count:=count+1;
          slcount.Values[str]:=inttostr(count);//记录计数器
        end;    if stemp<>'' then//存在6次以上的号码
        begin
          slalready.Insert(0,stemp);//这次要用插入了,否则顺序不对。
          //showmessage(slcount.Text);
        end;
      end;  self.Memo2.Lines.BeginUpdate;
      self.Memo2.Lines:=slalready;
      self.Memo2.Lines.EndUpdate;
    end;
      

  6.   

    那会是北大看门的吧,呵呵,哥哥好谦虚,你的bug还没修改呢?就是怎么做到从1-30号码,而避免00这个号
      

  7.   


    找到这一句:num:=random(36);
    如果需要从1-30,那么改成这样:num:=random(29)+1;
    如果需要从1-36,那么改成这样:num:=random(35)+1;
    如果需要从……等等,看明白没?
      

  8.   

    偶然看到一个东西,某风水大师说的和LZ的很象啊。
    其实要是真能中奖。他肯定不会说出来的,他自己早去买了,
    这就是传说中的 "大梨赚财迷",一个骗子而已。
    七乐彩先天无效组合计算(上)    通过上一讲的分析,下面对先天无效组合进行求解。    一、组合式结构:    A、十进制结构:(共2654注)    1)当十进制时,其七乐彩基本奖号的和值小于47的组合共1477注,具体组合如下:01-02-03-04-05-06-07
    01-02-03-04-05-06-08
    01-02-03-04-05-06-09
    01-02-03-04-05-06-10
    01-02-03-04-05-06-11
    01-02-03-04-05-06-12
    01-02-03-04-05-06-13
    01-02-03-04-05-06-14
    01-02-03-04-05-06-15