在dataset中有个double类型的字段uservalue。我打算写一个函数判断连续N个结果有M个数据超过他们的平均数X。现在平均数好办是已知的。 我把数据集装入到了数组里面。var a:array of double;
begin
  with dataset do 
    begin
      first;
      setlength(a,recordcount);
      for i:=low(a) to high(a) do
      begin
        a[i]:=fieldbyname('uservalue').asfloat;
        next;
      end 
    end;
end;现在就把数据都装入了数组a 中如果判断连续N个结果同时超过X就好办:
var i,k:integer;
begin
  k:=0;
  for i:=low(a) to high(a) do
  begin
     if (a[i]>X) then
        k:=k+1
     else
        k:=0;
  end;
  if k=N then showmessage('发现!');end;现在的问题是连续N个结果有M个超过X。这M个结果在N个结果中可以不是连续的,但是N个结果又是连续的。 我想了半天都没有写出合适的解决方法来。希望哪位热心人帮我一下,谢谢!

解决方案 »

  1.   

    for i:=0 to Length(a)-N-1 do
    begin
      k := 0;
      for j:=i to i+N-1 do
        if a[j] > X then
          k := k + 1;
      if k>=M then
      begin
        showmessage('发现!');
        break;
      end; 
    end;
      

  2.   

    var
      i, k : integer;
    begin
      k := 0;
      for i := low(a) to high(a) do
         if a[i] > X then k := k + 1;
      if k >= M then showmessage('发现!');
    end;
      

  3.   

    function GetoverNum(m:integer;//从数组a的第i个开始
                        n:integer;//连续个数,本例中为N个
                        a:array of integer;//数组a   
                       ):integer;//返回超过平均数的个数
    var 
      i,k:integer;
      x,y:integer;//分别为n个数的平均数和总数
    begin
      k:=0;
      if (m+n) < high(a) then
      begin 
        //求平均数x
        y := 0;
        for i := m to (m+n-1) do
        begin
          y := y + a[i];
        end; 
        x := y/n;
        
        for i:=m to (m+n-1) do
        begin
          if (a[i]>X) then
            k:=k+1;//M个结果可以不连续
        end;
      end;
      Result := k;
    end;调用 
    //查找第一个符合条件首个的位置
    for m := low(a) to (high(a)-N +1) do 
    begin
      if GetoverNum(m,N,a) = M then
      begin
        showmessage(format('第%d个开始的N个连续结果符合条件!',[m]));
        break;
      end;
    end;//查找符合条件的个数
    k:=0;
    for m := low(a) to (high(a)-N +1) do 
    begin
      if GetoverNum(m,N,a) = M then
      begin
        k := k +1;    
      end;
    end;
    showmessage(format('共有%d个符合条件的结果集!',[k]));
      

  4.   

    //这是测试以后的代码
    function TForm1.GetoverNum(m:integer;//从数组a的第i个开始
                        n:integer;//连续个数,本例中为N个
                        a:array of integer//数组a
                       ):integer;//返回超过平均数的个数
    var
      i,k:integer;
      x,y:integer;//分别为n个数的平均数和总数
    begin
      k:=0;
      if (m+n) < high(a) then
      begin 
        //求平均数x
        y := 0;
        for i := m to (m+n-1) do
        begin
          y := y + a[i];
        end;
        x := Trunc(y/n);
        
        for i:=m to (m+n-1) do
        begin
          if (a[i]>X) then
            k:=k+1;//M个结果可以不连续
        end;
      end;
      Result := k;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a:array[3..30] of Integer ;
      i,m,k:integer;
    begin
    {  for i := 3 to 30 do
      begin
        a[i] := i;
      end;
      for m := low(a) to (high(a)-5 +1) do
      begin
        if GetoverNum(m,5,a) = 2 then
        begin
          showmessage(format('第%d个开始的5个连续结果符合条件!',[m]));
          break;
        end;
      end;}
      k:=0;
      for m := low(a) to (high(a)-7 +1) do
      begin
        if GetoverNum(m,7,a) = 3 then
        begin
          k := k +1;
        end;
      end;
      showmessage(format('共有%d个符合条件的结果集!',[k]));end;
      

  5.   

    delphi72() (程序没有验证,但是思路不错)jadeluo(秀峰) (程序思路不对,没有满足要求)xiaocai800322(走自己的路) (平均数X是整个数据序列的平均数,是固定的,不需要每次都进行计算,如果需要计算,直接用SQL的AVG函数即可完成,没有必要写这么麻烦。程序的可读性不是很好,但是你写了比较详细的代码,还扩充了想法。)我把我写的贡献出来,经过了初步测试,但是不能确保万无一失。(考虑到程序的效率,但是不能保证能否节约少循环几次,效率也是比较重要)
        k := 0; k1 := 0; k2 := 0; j:=0;    for i:=Low(a) to High(a) do
        begin      if  (a[i]>X) then
          begin
            k := k+1;
            k1 := k1+1;
          end
          else
          begin
            k1 := k1+1;
          end;
          if K>=M then
          begin 
         //累计符合条件的达到M个,那么向前回溯连续N个,看看这个N个中是不是有M个符合条件        for j := k1-1 downto K1-N-1 do
            begin
              if  (a[j]>X) then
              begin
                k2 := k2+1;          end
              else
              begin
                continue;
              end;          if (K2>=M) then
              begin
                  showmessage('发现');
                  exit;
              end;        end;      end;    end;思考这段程序的意义:
        在实验室的质量控制中,需要对某个检验指标每天进行标准测试,测试的数据需要判断它们是否处在正常区间。如何判断一个数据集中,连续N个结果有M个数据超过他们的平均数X + - x倍标准差是westgard多规则质控分析的一种规则。其中的N、M、x都是用户指定的。当出现违背规则的时候,计算机就应该提示用户。这样,他们就及时进行查找数据失控原因。这么做的目的是让机器做的结果始终都是客观可控的。这在实验室机构和检验科等都是非常重要的。而且,这种失控也是和现实情况有必然的联系。比如连续10个结果超过2倍标准差就是代表机器可能堵塞了,所有的结果都在平均数一侧代表机器试剂有问题。    但是更加有挑战的是,我们应该让计算机来发现新的模式(是不是采用决策树进行分类),在新的模式下面就能总结新的失控规律,让用户迅速找到失控的原因进行处理。这里面的N、M、X应该有机器来进行建议。这里面将来还有数据预测和挖掘的东西。    新的题目:给定多个数据序列,让计算机发现数据的失控规律和模式,建议N,M,x应该是多少?然后此次模式进行分析。    这些知识应用在科技领域的数据分析方面,直接给人带来的好处就是,报告更加准确,人做事情就决策更加准确。    谢谢,散分!!