Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.06.2013, 14:27   #1
20Анастасия20
 
Регистрация: 12.06.2013
Сообщений: 5
Вопрос Проблема с выводом вопросов случайным образом на Делфи

При создание тестовой оболочки возникла проблема: с выводом вопросов случайным образом.

До того как не было добавлено условие чтобы вопросы теста находящиеся в файле при выводе случайным образом НЕ повторялись все работало теперь при выводе иногда выводятся все 10 вопросов а иногда 2 -3 пустые
Пример вывода 10 вопроса:
Код:
AssignFile(F,'base.txt');// база где хранятся вопросы base.txt причем первая строка это название теста, вторая вопрос, третья количество вариантов ответа V ,четвертая номер правильного ответа К и далее в зависимости от кол-ва V варианты ответа
reset(F);
Readln(F,A);
label1.Caption:=A;// А переменная для обозначения строки

Randomize;
N10:=Random(N); //Случайный выбор 10 вопроса
if N10=0 then N10:=Random(N)
else
label2.Caption:=Inttostr(N10);
if (N10=N1) or (N10=N2) or (N10=N3) or (N10=N4) or (N10=N5) or (N10=N6) or (N10=N7) or (N10=N8) or (N10=N9)//проверка на повторение,после добавления этого условия возникла проблема с выводом
then
begin
N10:=Random(N);
label2.Caption:=Inttostr(N10);
end
else
for j:=1 to N do
begin
if j<>N10 then
begin
Readln(F,A);// считывается сам вопрос
Readln(F,V);// считывается количество вариантов ответа( +1 так как есть строка с номером правильного ответа)
for i:=1 to (V+1) do
Readln(F,A);
end
else
begin
Readln(F,A);
label14.Caption:=A; //выводится вопрос
Readln(F,V);
Readln(F,k10);

for m:=1 to V do
begin
Readln(F,A);
Radiogroup10.Items.Add(A); //выводятся варианты ответа
end;
end;
end;
CloseFile(F);
[HR]Пример хранения вопросов в base.txt
1 тема теста
2 Вопрос 1
3 Кол-во вариантов ответа(V)
4 Номер правильного(k)
5 вариант ответа1
6 вариант ответа 2 и т.д в зависимости от V
-
-
- Вопрос 2
- Кол-во вариантов ответа(V)
- Номер правильного(k)
- вариант ответа1
- вариант ответа 2 и т.д в зависимости от V
Цикл подсчета количества вопросов в базе
Код:
 AssignFile(F,'base.txt');
   reset(F);
   Readln(F,A);              
   While Not Eof(F) do
      begin
        Readln(F,A);
        Readln(F,A);
        V:=strtoint(A);
        For i:=1 to(V+1) do Readln(F,A);
        N:=N+1;
      end;
   CloseFile(F);

481875212@mail.ru
20Анастасия20 вне форума Ответить с цитированием
Старый 18.06.2013, 15:48   #2
BoozZzilla
Форумчанин
 
Аватар для BoozZzilla
 
Регистрация: 26.01.2009
Сообщений: 125
По умолчанию

а если так:

a,b:array [0..количествовопросов-1] of integer


for i=0 to количествовопросов-1 do
begin
b[i]:=i+1
end;

for i=0 to количествовопросов-1 do
begin
a[i]:=b[Random(количествовопросов-i)-1)]
for j=a[i]-1 to количествовопросов-i do
begin
b[j]:=b[j+1]
end;
end;

теперь в массиве a лежат рандомно цифры от нуля до того количества которое вы зададите, и вы берете номера вопросов из этого массива

Вот сижу и думаю что все у меня громоздко, давайте попросим профессионалов упростить эту идею, и уменьшить количество кода

Последний раз редактировалось BoozZzilla; 18.06.2013 в 16:12.
BoozZzilla вне форума Ответить с цитированием
Старый 18.06.2013, 16:13   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Настя, подобные проблемы (случайные числа без повторений) на форуме обсуждались НЕОДНОКРАТНО.

рекомендую Вам воспользоваться поиском
(или ознакомится, например, с этим моим постом #12 или с этим постом - Случайное перемешивание в массиве )
и сделать так: заполняете список (массив) с номерами вопросов. Перемешиваете (только правильно перемешиваете). Берёте номера вопросов из перемешанного списка. Всё. проблема решена!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.06.2013, 08:00   #4
20Анастасия20
 
Регистрация: 12.06.2013
Сообщений: 5
Вопрос

Попробовала использовать массив данный код работает, но возникла проблема: Мне нужен массив от1 до N так как количество вопросов не ограничено причем эта N далее будет считаться
Код:
mas: array [1..30] of integer;
AssignFile(F,'base.txt');
    reset(F);
    Readln(F,A);
    label1.Caption:=A; 
    for t:=1 to N  do
    mas[t]:=t;
    Randomize;
      for t:=1 to N-1 do
      begin
      N1:=Random(N-t+1)+t;
      if N1<>t then begin
      y:=mas[t];
      mas[t]:=mas[N1];
      mas[N1]:=y;
      end;
      end;

Исходник первый вариан http://letitbit.net/download/01106.0...ом648.rar.html

Вот вариант с массивом http://letitbit.net/download/16474.1...648_2.rar.html

Спасибо большое всем за ответы!
20Анастасия20 вне форума Ответить с цитированием
Старый 19.06.2013, 08:40   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Мне нужен массив от1 до N так как количество вопросов не ограничено причем эта N далее будет считаться
к счастью, в Delphi есть такой тип данных как ДИНАМИЧЕСКИЕ массивы.

достаточно написать так:
Код:
var mas: array of integer;

....

    AssignFile(F,'base.txt');
    reset(F);
    Readln(F,A);
    label1.Caption:=A; 

    SetLength( mas, N+1);  // примечание. почем размер N+1. дело в том, динамические массивы индексируются от НУЛЯ.
         // поэтому, Вам нужно или везде изменить циклы от нуля до N-1
         // либо завести ЛИШНИЙ дополнительный элемент массива. Тогда нулевой элемент массива mas не будет задействован.

    for t:=1 to N  do
       mas[t]:=t;
    Randomize;
    for t:=1 to N-1 do
    begin
        N1:=Random(N-t+1)+t;
        if N1<>t then begin
          y:=mas[t];
          mas[t]:=mas[N1];
          mas[N1]:=y;
        end;
    end;

....

  // в конце программы желательно освободить выделенную под массив память
  SetLength( mas, 0 );
вот и всё
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.06.2013, 09:41   #6
20Анастасия20
 
Регистрация: 12.06.2013
Сообщений: 5
Вопрос

Если я правильно поняла то получается вот так, проверяла несколько раз ,3 раза выводит нормально все а 1 раз без одного вопроса
Код:
//Вывод1 вопроса

     AssignFile(F,'base.txt');
     reset(F);
     Readln(F,A); 
     label1.Caption:=A; 
    
     SetLength( mas, N+1);
     for t:=1 to N  do
     mas[t]:=t;
     Randomize;
      for t:=1 to N-1 do
      begin
      N1:=Random(N-1)+1;
      if N1<>t then begin
      y:=mas[t];
      mas[t]:=mas[N1];
      mas[N1]:=y;
      end;
      end;
    
     for j:=1 to N do
            begin
         if j<>N1 then
        begin
          Readln(F,A);  
          Readln(F,V);  
          for i:=1 to (V+1) do
              Readln(F,A);
         end
        else
            begin
            Readln(F,A);
            label5.Caption:=A;   
            Readln(F,V);
            Readln(F,k1);

            for m:=1 to V do
               begin
               Readln(F,A);
               Radiogroup1.Items.Add(A);

               end;
               end;
               end;

               CloseFile(F);

   //Вывод 2 вопроса

  AssignFile(F,'base.txt');
   reset(F);
    Readln(F,A);
 //
    SetLength( mas, N+1);
     for t:=1 to N  do
     mas[t]:=t;
     Randomize;
      for t:=1 to N-1 do
      begin
      N2:=Random(N-1);
   if N1=N2 then
   N2:=Random(N-1)
   else
      if N2<>t then begin
      y:=mas[t];
      mas[t]:=mas[N2];
      mas[N2]:=y;
      end;
      end;

    for j:=1 to N do
            begin
         if j<>N2 then
        begin
          Readln(F,A);
          Readln(F,V);
          for i:=1 to (V+1) do
          Readln(F,A);
         end
                  else
            begin
            Readln(F,A);
            label6.Caption:=A;
            Readln(F,V);
            Readln(F,k2);

            for m:=1 to V do
               begin
               Readln(F,A);
               Radiogroup2.Items.Add(A);
               end;
               end;
               end;
               CloseFile(F);
Вот что получилось, возможно я не поняла как использовать массив
http://letitbit.net/download/13339.1...копия.rar.html
20Анастасия20 вне форума Ответить с цитированием
Старый 19.06.2013, 10:48   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Настя, я чуть позже посмотрю исходники вашего проекта.
На будущее большая просьба к Вам - выкладывать архивы с проектом на форуме (нажимаете при ответе на "расширенный режим" - внизу "Управление вложениями" - там выбираете свой архив, нажимаете "Загрузить", "Ответить" и вуаля - файл прикреплён к вашему сообщению.

p.s. да и вообще, пользоваться платной дрянью типа летитбит или депозитфайлес - категорически не рекомендую!


ДОБАВЛЕНО
нет, я так и не смог скачать архив с letitbit... извиняйте...

Последний раз редактировалось Serge_Bliznykov; 19.06.2013 в 10:56.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.06.2013, 11:28   #8
20Анастасия20
 
Регистрация: 12.06.2013
Сообщений: 5
По умолчанию

Спсаибо, я раньше не замечала вложения.
Вложения
Тип файла: rar Диплом648 - копия.rar (77.5 Кб, 29 просмотров)
20Анастасия20 вне форума Ответить с цитированием
Старый 20.06.2013, 03:09   #9
Step_UA
Форумчанин
 
Аватар для Step_UA
 
Регистрация: 09.06.2011
Сообщений: 388
По умолчанию

Код:
procedure TForm1.Button1Click(Sender: TObject);
type
  TEl=record
        V:string;
        K,count:integer;
        R:array of string;
      end;
var
   F:textfile;
   t,i,N:integer;
   A:String;
   Mas:array of TEl;
   tmp:TEl;
begin
   Form1.N5.Enabled:=true;
   N:=0;
   AssignFile(F,'base.txt');
   reset(F);
   Readln(F,A);
   label1.Caption:=A;
   //цикл считывания вопросов из базы
   While Not Eof(F) do
      begin
        setlength(Mas,N+1);
        Readln(F,Mas[n].V);
        Readln(F,Mas[n].count);
        Readln(F,Mas[n].K);
        setlength(Mas[n].R,Mas[n].count);
        For i:=0 to Mas[n].count-1 do Readln(F,Mas[n].R[i]);
        inc(n);
      end;
   CloseFile(F);
   // перемешиваем вопросы
   // или используем дополнительный массив и "косвенную" адресацию
   Randomize;
   for i:=0 to N-1 do
     begin
       repeat
         t:=random(n);
       until t<>i;
       tmp:=mas[i];
       mas[i]:=mas[t];
       mas[t]:=tmp
     end;
   // выводим первые 10 вопросов и варианты ответов
   for i:=0 to 9 do
     begin
       TLabel(FindComponent('label' + IntToStr(5+i))).Caption:=Mas[i].V;
       with TRadioGroup(FindComponent('Radiogroup'+inttostr(1+i))) do
         begin
           for t:=0 to Mas[i].count-1 do
               Items.Add(Mas[i].R[t]);
           Tag:=Mas[i].K;
         end;
     end;
   Button1.Enabled:=false;
end;
Код:
procedure TForm1.N5Click(Sender: TObject);
var i,S:integer;
begin
  S:=0;
  //Подсчет результатов
  for i:=1 to 10 do
    with TRadioGroup(FindComponent('Radiogroup'+inttostr(i))) do
      begin
        if ItemIndex=tag-1 then
          begin
            inc(S);
            TLabel(Form2.FindComponent('label'+inttostr(i+10))).Caption:='Верно';
          end;
        Enabled:=False;
      end;
  // Оценка
  if S > 4 then form2.label22.Caption:=inttostr((s+1) div 2)
           else form2.label22.Caption:='2';
  Form2.show;
  Form2.label24.Caption:=DateTimeToStr(Now);
end;
на неконкретные вопросы даю неконкретные ответы ...
Step_UA вне форума Ответить с цитированием
Старый 20.06.2013, 08:51   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Step_UA, просто отлично! Респект!
(особенно трюк с запоминанием правильного ответа в tag радиогруппы мне понравился, я бы до такого не додумался! )


только выделяемая под массивы память нигде не чистится. Это непорядок..
Или, если динамический массив объявлен в стеке (локальный в процедуре), то этого можно не делать?!




20Анастасия20, вопрос по данной теме (выдача случайных вопросов) можем считать закрытым?

Последний раз редактировалось Serge_Bliznykov; 20.06.2013 в 08:54.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Случайным образом определить цвет карандаша и кисти. vedro-compota Мультимедиа в Delphi 3 02.06.2010 13:27
Сформировать массив случайным образом... (Pascal ABC) om3n Помощь студентам 2 14.04.2010 22:27
проблема с выводом в делфи shelest Помощь студентам 5 02.03.2010 20:12
Генерация случайным образом Golovastik Общие вопросы C/C++ 9 07.10.2009 23:28
[Pascal] вывод элементов из файла случайным образом Рамик Помощь студентам 4 28.05.2009 17:18