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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.08.2011, 16:11   #11
Tolyman
Пользователь
 
Регистрация: 10.08.2011
Сообщений: 10
По умолчанию

Мы берем подпоследовательность длины k значит мы должны найти похожую подпоследовательность в которую входят все k элементов в нужном порядке. Критерий похожести состоит в том, чтобы были все k элементов последовательности, в том же порядке, и между элементами не было мусора более чем по 2. И даже если после каждого успешного элемента будет стоять 2 мусора, и мусора получится 2k-4, то все равно такая последовательность будет похожей. Конечно, желательно, чтобы можно было изменять критерий похожести - 0 мусора между элементами, 1,2...

Последний раз редактировалось Tolyman; 11.08.2011 в 16:15.
Tolyman вне форума Ответить с цитированием
Старый 11.08.2011, 17:31   #12
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

ну наконец-то, вытащили из вас клещами описание задачи )

Код:
program
  SubSeq;

{$APPTYPE CONSOLE}

const
  N  = 100000;     // total seq length
  //
  K  = 8;         // subsequence length (from 1 to N/2)
  B  = 0;          // subsequence start index (from 0 to N - 2*K)
  //
  M  = 3;          // max number of bad emelments we can tolerate in between of other elements (from 0 to N-K)

var
  seq: pIntegerArray;

// --  --
procedure printSeq(s, l: Integer; const title: string);
var
  i: Integer;
begin
  writeln(title);
  write('@', s, ', len=', l, ' [ ');
  for i := s to s + l - 2 do
    write(seq[i], ', ');
  //
  writeln(seq[s + l - 1], ']');
  writeln;
end;

// --  see if we can make up a subsequence starting from this index --
function tryThis(index: Integer; var len: Integer): Boolean;
var
  c, t, o1: Integer;
begin
  c := 1;
  o1 := 1;
  result := true;
  //
  while (result and (index + o1 < N) and (c < K)) do begin
    //
    if (seq[index + o1] = seq[B + c]) then begin
      //
      inc(c);
      inc(o1);
    end
    else begin
      //
      t := 1;
      while (t <= M) do begin
        //
        if (seq[index + o1 + t] = seq[B + c]) then
          break
        else
          inc(t);
      end;
      //
      if (t > M) then begin
        //
        // too much trash
        result := false;
        break;
      end
      else begin
        //
        inc(c);
        inc(o1, t + 1);
      end;
    end;
  end;
  //
  len := o1;
end;

// -- main --

var
  i, j, l: Integer;
  bestIndex, bestLen: Integer;
begin
  writeLn('N  = ', N, ';   B = ', B, ';   K = ', K, ';   M = ', M);
  //
  bestIndex := -1;
  bestLen := MaxInt;
  //
  Randomize();
  GetMem(seq, sizeof(Integer) * N);
  try
    for i := 0 to N - 1 do
      seq[i] := 5 - Random(10);
    //
    printSeq(B, K, 'Source subseqence:');
    //
    j := 0;
    while (j < N - K) do begin
      //
      if ((j < B) or (j > B + K)) and (seq[j] = seq[B]) then begin
        //
        if (tryThis(j, l)) then begin
          //
          printSeq(j, l, 'Found some:');
          if (l < bestLen) then begin
            //
            bestIndex := j;
            bestLen := l;
          end;
        end;
      end;
      //
      inc(j);
    end;
    //
  finally
    FreeMem(seq);
  end;
  //
  if (bestIndex >= 0) then
    writeLn('Best sub-sequence found at ', bestIndex, '; length=', bestLen)
  else
    writeLn('No luck');
end.
как-то так, комменты по коду я разбросал
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 11.08.2011, 17:47   #13
Tolyman
Пользователь
 
Регистрация: 10.08.2011
Сообщений: 10
По умолчанию

Спасибо. Дома попробую разобраться.
Tolyman вне форума Ответить с цитированием
Старый 12.08.2011, 11:53   #14
Tolyman
Пользователь
 
Регистрация: 10.08.2011
Сообщений: 10
По умолчанию

Извини за необразованность но последний вопрос: в какой среде скомпилировать твою программу?
Tolyman вне форума Ответить с цитированием
Старый 12.08.2011, 12:46   #15
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

желательно в Delphi, можно и под free pascal/Lazarus
а можно и в Борланд Паскале под ДОС (с небольшими изменениями)
тут даже не сколько важно скомпилировать, а просто понять, что и как она делает.

1) формируется массив seq из N случайных чисел

2) индекс j пробегает от 0 до N - K, и если j не попадает внутрь самой подпоследовательности (в диапазон от B до B + K - 1), и если первая цифра подпоследовательности (seq[B]) совпадает с seq[j], то вызывается процедура tryThis(j)

3) tryThis уже по переданному ей индексу пытается проверить, можно ли построить начиная с этого индекса подпоследовательность, учитывая, что могут быть от 0 до M "леывх" элементов между каждым подходящим.

4) если построить удалось, tryThis возвращает True и заодно длину получившейся подпоследовательности (включая мусор). Длина затем сравнивается с "лучшей" длиной (bestLen) и если она короче, то bestLen обновляется (вместе с bestIndex).

5) в конце выдается индекс "лучшей" по длине подпоследовательности, или "No luck", если ничё не нашлось.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 12.08.2011, 14:35   #16
Tolyman
Пользователь
 
Регистрация: 10.08.2011
Сообщений: 10
По умолчанию

В структуре программы я разобрался, она просто прелесть. Просто БП не знает например что такое pIntegerArray, try - finally(а это не знает фри паскаль), Делфи матюкнулся на то что не описан type. И еще где нужно описать result? Я вроде как попробывал переделать под ТП, но еще не успел проверить. Я его описал как булин в самой функции возле этих
var
c, t, o1: Integer;

Последний раз редактировалось Tolyman; 12.08.2011 в 14:37.
Tolyman вне форума Ответить с цитированием
Старый 12.08.2011, 14:38   #17
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Это биологические алгоритмы, направлены на поиск цепочек ДНК. Советую копать в том направлении . Возможно тама есть и более оптимальные алгоритмы.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 12.08.2011, 14:51   #18
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

pIntegerArray можно заменить на

Код:
seq: array[0..N-1] of Integer;
тогда GetMem/FreeMem равно как и try/finally можно убрать.

Да, result можно описать как локальную boolean переменную, в конце не забыть tryThis := result;

И да, алгоритм не то, что не оптимальный, он просто в лоб. Если N, К или М будут на несколько порядков больше, нужно что-то думать. Или если B (начало подпоследовательности) заранее неизвестно (т.е. предполагается, что его будут подбирать), тут всё немного сложнее (если хочется оптимально).
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 12.08.2011, 15:15   #19
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

ну и сразу добавлю.

в случае:
Цитата:
Код:
const
  N  = 100000; 
...
var
seq: array[0..N-1] of Integer;
можете забыть про Turbo Pascal.
там общий размер всех переменных не может превышать 64 кб
поэтому такой код не откомпилируется.

Надо брать Delphi (рекомендую), ну или FreePascal...

вот код консольной программы под Delphi (и под FreePascal после правильного импорта скорее всего тоже откомпилируется!)
Код:
program
  SubSeq;

{$APPTYPE CONSOLE}

const
  N = 100000; // total seq length
  //
  K = 8; // subsequence length (from 1 to N/2)
  B = 0; // subsequence start index (from 0 to N - 2*K)
  //
  M = 3; // max number of bad emelments we can tolerate in between of other elements (from 0 to N-K)

var
  seq: array[0..N - 1] of Integer;

// --  --

procedure printSeq(s, l: Integer; const title: string);
var
  i: Integer;
begin
  writeln(title);
  write('@', s, ', len=', l, ' [ ');
  for i := s to s + l - 2 do
    write(seq[i], ', ');
  //
  writeln(seq[s + l - 1], ']');
  writeln;
end;

// --  see if we can make up a subsequence starting from this index --

function tryThis(index: Integer; var len: Integer): Boolean;
var
  c, t, o1: Integer;
begin
  c := 1;
  o1 := 1;
  result := true;
  //
  while (result and (index + o1 < N) and (c < K)) do begin
    //
    if (seq[index + o1] = seq[B + c]) then begin
      //
      inc(c);
      inc(o1);
    end
    else begin
      //
      t := 1;
      while (t <= M) do begin
        //
        if (seq[index + o1 + t] = seq[B + c]) then
          break
        else
          inc(t);
      end;
      //
      if (t > M) then begin
        //
        // too much trash
        result := false;
        break;
      end
      else begin
        //
        inc(c);
        inc(o1, t + 1);
      end;
    end;
  end;
  //
  len := o1;
end;

// -- main --

var
  i, j, l: Integer;
  bestIndex, bestLen: Integer;
begin
  writeLn('N  = ', N, ';   B = ', B, ';   K = ', K, ';   M = ', M);
  //
  bestIndex := -1;
  bestLen := MaxInt;
  //
  Randomize();
  for i := 0 to N - 1 do
    seq[i] := 5 - Random(10);
    //
  printSeq(B, K, 'Source subseqence:');
    //
  j := 0;
  while (j < N - K) do begin
      //
    if ((j < B) or (j > B + K)) and (seq[j] = seq[B]) then begin
        //
      if (tryThis(j, l)) then begin
          //
        printSeq(j, l, 'Found some:');
        if (l < bestLen) then begin
            //
          bestIndex := j;
          bestLen := l;
        end;
      end;
    end;
      //
    inc(j);
  end;
  if (bestIndex >= 0) then
    writeLn('Best sub-sequence found at ', bestIndex, '; length=', bestLen)
  else
    writeLn('No luck');
  readln;
end.

Последний раз редактировалось Serge_Bliznykov; 12.08.2011 в 15:18.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 12.08.2011, 15:20   #20
Tolyman
Пользователь
 
Регистрация: 10.08.2011
Сообщений: 10
По умолчанию

Я сразу N уменьшил до 10000. И запустил на ТП. Все нормально. Теперь нужно сделать, чтобы брало данные из файла, а потом записывало в файл, но надеюсь это я смогу сделать. Спасибо Вам всем.
Tolyman вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
С\С++ Дана последовательность чисел. Найти количество различных чисел в этой последовательности yuliyayuliya Помощь студентам 1 14.04.2011 06:30
Сравнение двух листов и вывод в определённой последовательности ОlGa Microsoft Office Excel 1 29.01.2010 21:06
Определить k-ую цифру последовательности Фибоначчи и последовательности натуральных чисел. Med Помощь студентам 1 20.03.2009 11:40
обмен чисел последовательности maziLa Паскаль, Turbo Pascal, PascalABC.NET 2 09.12.2008 00:15
вычисление суммы чисел, кратных 3 из последовательности, состоящей из 10 чисел, заранее заданных Белка Помощь студентам 3 27.10.2007 11:53