Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.07.2013, 23:15
vazer vazer вне форума
Прохожий
 
Регистрация: 14.07.2013
Сообщения: 4
Версия Delphi: delphi 2010
Репутация: 10
По умолчанию нестыковка с рандомом без повторений

Код:
var
 mark,endofupr:boolean;
 i,x,l,m,n1:integer;
 mas: array of integer;
begin
   i:=0;
   SetLength(mas, Listbox1.Items.Count);  //установил длину массива
   for i:=0 to Listbox1.Items.Count do
   mas[i]:=999; //забил весь массив такими элементами, они точно не встретятся, а их будет нужно сравнивать 
   mark:=true;
                         while mark=true do
                             begin
                               mark:=false;
                               k:=Random(Listbox1.Items.Count);
                               for i:=0 to length(mas)-1 do
                               if k=mas[i] then mark:=true;
                             end;
                         mas[j]:=k;
                         j:=j+1;
                           if j=Listbox1.Items.Count then showmessage('end of ist');                         
                       end;
              upr:= ListBox1.Items[k];
end

значит так. в этом коде, у меня есть несколько строк в листбоксе, я вывожу их в строку поочередно, в случайном порядке, но так, чтоб они не повторялись между собой.
мучаюсь целый день, понапереставлял уже все, что только можно, а оно ни в какую.
почему-то не записываются значения в массив.
я его сначала забил 999, как вы можете заметить, потому что они точно не встретятся в моей программе ( в отличие от стандартного нуля).
и после выполнения алгоритма, вывожу этот массив,для проверки, а там все те же девятки, хотя должжны быть разные номера элементов листбокса.
переменным j,k я задал ноль в теле самого юнита, они у меня глобальные
всем спасибо за внимание
Ответить с цитированием
  #2  
Старый 15.07.2013, 01:08
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

end в конце лишний.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #3  
Старый 15.07.2013, 02:25
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Строку
Код:
 upr:= ListBox1.Items[k];
тоже перенести вверх надо
Ответить с цитированием
  #4  
Старый 15.07.2013, 03:05
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,030
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Alegun
Строку
Код:
 upr:= ListBox1.Items[k];
тоже перенести вверх надо

Можно проще и "железобетонней" с помощью промежуточного списка строк. Сначала копируешь все в промежуточный список, потом, пока в нем хоть один элемент есть, выбираешь случайный, добавляешь в строку и удаляешь из пром. списка:
Код:
function GetRandomStrings(ListBox : TListBox) : String;
var
  Idx : Integer;
  Buf : TStringList;
begin
  Randomize; // Init random
  Result := '';
  Buf := TStringList.Create;
  Try
    Buf.Assign(ListBox.Items);
    While Buf.Count > 1 Do
      Begin
        Idx := Random(Buf.Count); // Get random number 0..Count-1
        Result := Result + Buf[Idx] + ' '; // Add this item to the result
        Buf.Delete(Idx); // Remove "used" item
      End;
    Result := Result := Buf[0]; // Last one
  Finally
    Buf.Free;
  End;
end;
Ответить с цитированием
  #5  
Старый 15.07.2013, 15:58
vazer vazer вне форума
Прохожий
 
Регистрация: 14.07.2013
Сообщения: 4
Версия Delphi: delphi 2010
Репутация: 10
По умолчанию

Код:
procedure TForm1.Timer1Timer(Sender: TObject); //действие по таймеру
var
 mark,endofupr:boolean;
 i,x,l,m,n1:integer;
 mas: array of integer;
begin
   i:=0;
   SetLength(mas, Listbox1.Items.Count);
   for i:=0 to Listbox1.Items.Count do
   mas[i]:=999; //забил весь массив такими элементами, они точно не встретятся, а их будет нужно сравнивать 
   endofupr:=true;
   mark:=true;
   Timer1.enabled := false; //выключаем таймер
       if checkbox1.Checked=true then //если выводить рандомно
          begin
              Randomize;
              k:=Random(Listbox1.Items.Count);//выбираем число между количеством строк
                 if checkbox2.Checked = true then //если без повторений
                      begin
                        if j>0 then //первый случай мы уже учли внизу
                         while mark=true do
                             begin
                               mark:=false;
                               k:=Random(Listbox1.Items.Count);
                               for i:=0 to length(mas)-1 do
                               if k=mas[i] then mark:=true;
                             end;
                         mas[j]:=k;
                         j:=j+1;
                           if j=Listbox1.Items.Count then
                            begin
                             showmessage('last exercise for today');
                             endofupr:=false;
                            end;
                       end;

              edit3.Text:=edit3.Text+'['+inttostr(mas[j])+']'; //это всякая фигня для проверки. 
//и вот эти мас[i] почему-то по выводу равны [999], хотя им нужно присвоить номера строк. почему не присваиваются -не понимаю
              edit3.Text:=edit3.Text+inttostr(k);
              //edit3.Text:=edit3.Text+'('+inttostr(j)+')';

              upr:= ListBox1.Items[k];
          end
                                  else //если не рандомные и тд



Так, я, пожалуй, ошибся, вывесив только часть кода. так, думаю, будет проще понять что и как. а то тут вы говорите про лишние энды, и мало ли где я еще напутал при редактироваании. а это ж к делу не относится.
собственно выводом по таймеру управляют два чекбокса: один из них отевчает за случайный вывод. а второй за вывод с/без повторениями.
как уже говорил, у меня проблема с рандомом без повторений.

сейчас попробую сделать массив не чисел с номерами строк, а просто со строками, и выводить напрямую из него. ну, мало ли.

и да, я не понял почему upr:=... перенести вверх

если вы о том, что это присваивание и вывод должны быть в цикле, то нет. это единичное действие по таймеру, а этиот таймер будет включаться не раз, так что вот как раз в каждое включение нужно вывести один, не повторяющийся, элемент

то есть конкретно в этой процедуре выводится одна строка, просто она(процедура) выполняется несколько раз.ну и эти строки, повторяюсь, не должны, гхм, пардон за такое построение предложения, повторяться.

Последний раз редактировалось vazer, 15.07.2013 в 19:56.
Ответить с цитированием
  #6  
Старый 15.07.2013, 23:25
vazer vazer вне форума
Прохожий
 
Регистрация: 14.07.2013
Сообщения: 4
Версия Delphi: delphi 2010
Репутация: 10
По умолчанию

так, в общем, вопрос решил, может не очень красиво, конечно.
но спасибо lmikle за идею, действительно сделал со списком.

Код:
 if checkbox1.Checked=true then //если рандомные
          begin
              Randomize;
                 if checkbox2.Checked = true then //если без повторений
                      begin
                        if l>1 then //
                             begin
                              indx:=random(l);
                              upr:=mas[indx];
                              for i:=indx to l do
                                  mas[i]:=mas[i+1];
                              l:=l-1;
                             end
                                          else
                             begin
                               showmessage('last exercise for today');
                               upr:=mas[l-1];
                               endofupr:=false;
                             end;

вот шматок кода, если кому интересно.
теперь задам еще несколько вопросов, с вашего позволения.

1)решил прописать программу в автозагрузку, воспользовавшись вот этим вот. хотел спросить: arunonce если тру, то добавляет в автозагрузку только раз, потом я могу отключить и все.
а если фолс, то включается постоянно, даже если галочку убрать, я правильно понимаю?

Код:
procedure SetAutorun(aProgTitle,aCmdLine: string; aRunOnce: boolean );
 var
 hKey: string;
 hReg: TRegIniFile;
 begin
 if aRunOnce then hKey := 'Once'
 else
 hKey := '';
 hReg := TRegIniFile.Create( '' );
 hReg.RootKey := HKEY_LOCAL_MACHINE;
 hReg.WriteString('Software\Microsoft\Windows\CurrentVersion\Run'
 + hKey + #0,
 aProgTitle,
 aCmdLine );
 hReg.destroy;
 end;
в общем, из-за этой процедуры у меня не включается комп=\ показывает черный экран с мышью после приветствия, и все. приходится через безопасный режим удалять программу, убирать из автозагрузки и тд.
хотя вообще не понимаю, как это связано.

2)меня в автозагрузке висят несколько старых названий этой программы(я их менял в процессе создания), без галочек уже, конечно, и с несуществующими реальными адресами. их можно оттуда убрать? а то напрягает немного,и вдруг это как-то мешает, и поэтому не работает автозагрузка по-новой.

при чем если с одной из программ совпадает и имя и расположение, а получается, что одна с галочкой, а вторая(старая), без.

3)ну и вопрос с автоматическим включением программы нужно решать: может кто знает другой путь для добавления туда?

Последний раз редактировалось lmikle, 16.07.2013 в 05:07.
Ответить с цитированием
  #7  
Старый 15.07.2013, 23:45
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

В HKLM прописывать плохая идея, может прав не хватить админских, лучше в HKCU, здесь такое уже было.
Ответить с цитированием
  #8  
Старый 16.07.2013, 00:05
vazer vazer вне форума
Прохожий
 
Регистрация: 14.07.2013
Сообщения: 4
Версия Delphi: delphi 2010
Репутация: 10
По умолчанию

спасибо,поставил для пользователя.
кстати, если arunoce=false то вроде пока не наблюдаю никаких черных экранов.
но надо бы, конечно, еще потестировать.

а вопрос об удалении из списка автозагрузки программ, уже от автозагрузки отключенных, остается открытым
Ответить с цитированием
  #9  
Старый 16.07.2013, 00:11
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

regedit.exe не помогает? Посмотрите в поисковике, сейчас существует куева хуча чистильщиков "мёртвых" веток в реестре. Ну или самый эффективный и радикальный вариант - переустановка
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter