我在编写一个试题库系统,其中的组卷系统我遇到难题了 :(
    我的主要思想是:用TQuery 组件从试题库里查询到符合条件的试题,他们的难度不同,所属知识点也不动,所以我想用随机的方法提取一定数目的试题,并存于一张表里,
    我现在最想知道的是 用什么方法可以做到。    我知道有 random \ randomize 知道 TQuery 的 Recordcount    谁能告诉我? 我可以多给分他,我现在有6000多分没有用。

解决方案 »

  1.   

    Random(TQuery1.RecordCount)不行吗?
      

  2.   

    很高兴你们关注我的问题, 即使在这里没有解决,来者都会有分的。而且我会把最好我解决了的方法 在这里贴出来的,谢谢你们。Random 返回的是 integer  而我要是的记录,一条一条的记录
      

  3.   


      Sql.Text := 'select Top 10 * from tablename order by NewId() ' ; //随机取 10 条纪录
      
      

  4.   

    DbGrid , DbGridEh ; 等
      

  5.   

    看看我开发考试系统时的方法如何:
    void __fastcall MakeDM()
    {
    //生成试题库
            //TODO: Add your source code here
            TADOQuery *QUE;
            QUE=DM->Query;
            QUE->SQL->Text="delete from StDM"; //清控试题代码库
            QUE->ExecSQL();
            QUE->Close();
            QUE->SQL->Text="delete from KST";  //清空考试题库
            QUE->ExecSQL();
            QUE->Close();
            QUE->Connection=DM->Conn;
            QUE->SQL->Clear();
            QUE->SQL->Add("Select DM,Count,Min,Max,flag from StCount");
            //QUE->Prepared();
            QUE->Open();
            QUE->First();
            while(!QUE->Eof)
            {
                 MakeTest(QUE->FieldByName("DM")->AsString,QUE->FieldByName("Count")->AsInteger,QUE->FieldByName("Min")->AsInteger,QUE->FieldByName("Max")->AsInteger,QUE->FieldByName("flag")->AsInteger);
                 QUE->Next();
            }
            QUE->Close();
            QUE->SQL->Clear();
            QUE->SQL->Add("Insert into KST(dm,txnr,jg1,jg2,jg3,zqda,tpbj,pdbj,tpmc) ");
            QUE->SQL->Add("Select dm,txnr,jg1,jg2,jg3,zqda,tpbj,pdbj,tpmc from kstxk where dm  IN (select dm from stdm) order by pdbj");
            QUE->ExecSQL();}void MakeTest(AnsiString StDM,int Count,int Min,int Max,int flag)
    {
            int ID[50],i,tmp;
            for(i=0;i<=50;i++)
                    ID[i]=0;
            bool Status=false;
            i=1;
            ID[0]=random(Max-Min+1)+Min;
            randomize();
            while(i<Count)
            {
                    tmp=random(Max-Min+1)+Min;
                    for(int j=i-1;j>=0;j--)
                    {
                            if(ID[j]==tmp)
                            {
                            Status=true;
                            break;
                            }
                    }
                    if(!Status)
                    {
                            ID[i]=tmp;
                            i++;
                    }
                    else  Status=false;
            }
            //插入数据
            TADOQuery *QUE1=DM->Query1;
            QUE1->Close();
            QUE1->SQL->Clear();
            for(i=0;i<Count;i++)
            {
                    QUE1->SQL->Text="insert into StDM(DM,pdbj) values('" + StDM+FormatFloat("###000",ID[i]) +"','" + IntToStr(flag) + "')";
                    QUE1->ExecSQL();
            
    }
      

  6.   

    呵呵,我以前也做过!
    方法是把所有符合条件的试题id全部读取出来,保存在listA中,假设有M道题
    假设要取N(N<=M)道题
    循环N次
      i=random(M)
      将i对应的试题id存入listB中
      listA.delete(i)
      dec(m)
    循环结束
    这样listB中就保存了选出来的试题。
    将listB中的试题id组合成字符串ids
    然后select * from shiti where id in (ids)
    所有的试题就都出来了这个方法存在的问题:多用户操作,一个删试题,一个生成试卷,有可能最后出来的试题数目<N
      

  7.   

    晕,random随机读取你需要的id号不就可以了嘛!!
      

  8.   

    谢谢你们啦, 以下是我解决问题的代码:procedure TForm_ShiJuanYangBen.Xuanti(Query: TQuery; Tixing,
      ZhiShiDian: string; Nandu: TCaption; n: integer);
    var             // 自动与半自动选题 :参数 知识点,难度,和 该题型题目个数
      num : integer;
      i : integer;
      listA : TStringList;
      listB : TStringList;
      Bstring : string;
    begin
      with Query do                     // Query 的 SQL 查询
        begin
          Close;
          SQL.Clear;
          SQL.Add('select *');
          SQL.Add('from tabletest');
          SQL.Add('where TMType = '''+ Tixing +'''');
          if ZhiShiDian <> '' then
            SQL.Add(' and chapter in ( '+ ZhiShiDian +')');
          SQL.Add(' and Difficult = '''+ Nandu +'''');
          Open;
        end;
      Query.First;
      listA := TStringList.Create;
      listB := TStringList.Create;
      Bstring := '''beging''';
      try
        while not Query.Eof do                //listA 提取 符合条件的纪录的ID
          begin
            listA.Add(Query['ID']);
            Query.Next;
          end;
        Query.First;
        if listA.Count > n then
          begin
            Randomize;
            for i := 1 to n do                // 随机提取 n 条纪录
              begin
                num := random(listA.Count);
                listB.Add(listA.Strings[num]);
                Bstring := Bstring + ', '''+ listA.Strings[num] +'''';
                listA.Delete(num);
              end;
            with Query do                     //根据 ID 的集合,Query 的 SQL 查询
              begin
                Close;
                SQL.Clear;
                SQL.Add('select *');
                SQL.Add('from tabletest');
                SQL.Add('where id in ('+ Bstring +')');
                Open;
              end;
          end
        else
          MessageDlg('符合条件的"'+Tixing+'"的题量不足,请手工调整!',mtInformation,[mbOK],0);
      finally
        listA.Free;
        listB.Free;
      end;
    end;
      

  9.   

    这样写listb就没用了,可以删之