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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 27.09.2014, 00:21   #1
Lizoveta
Пользователь
 
Регистрация: 22.06.2013
Сообщений: 44
По умолчанию Паскаль, расстояние Левенштейна, сравнивание строк

Добрый вечер!
Вообще, это программа должна была найти количество строк, которые можно составить из двух символов '0' и '1', длина строки=8 и все строки в данном списке должны отличаться между собой как минимум на 5 символов. Т.е. расстояние Левенштейна между любыми двумя такими строками должно быть >5. Первая строка состоит из одних нулей.
Вывести я хотела именно сами строки, для наглядности.
Но я явно сделала что-то неправильно, т.к. моя программа вообще ничего не выводит, и массив, по-моему, даже не получает никакого значения.
Помогите, пожалуйста, исправить программу, найти ошибку или понять, как это можно было сделать иначе
Буду очень благодарна!
Код:
const n=256; m=8;
var a: array[1..n] of string[8];
    i,j,k,razn,l: integer;
    s: string[2];
    str: string[8];
    kon: boolean;
begin
randomize;
     for j:=1 to m do a[1,j]:='0';
repeat
     repeat
     k:=0;
           for j:=1 to m do begin
               s:='01';
               str[j]:=s[random(2)+1];
               if str[j]='1' then k:=k+1;
           end;
     until k>=5;
     i:=1;
     l:=1;
     repeat
         razn:=0;
         kon:=false;
         for j:=1 to m do begin
             if str[j]<>a[i,j] then razn:=razn+1;
         end;
         if razn>=5 then begin
            l:=l+1;
            a[l]:=str;
            kon:=true;
         end;
         i:=i+1;
     until (i>=l) or (kon=true);
until (l>=4);
for i:=1 to l do writeln(a[i]);
writeln;
end.
Lizoveta вне форума Ответить с цитированием
Старый 27.09.2014, 10:06   #2
GetMax
Форумчанин
 
Регистрация: 21.10.2010
Сообщений: 588
По умолчанию

Код:
for j:=1 to m do a[1,j]:='0';
У вас массив объявлен одномерным, а вы обращаетесь к нему как к двумерному.
Код:
str[j]:=s[random(2)+1];
Используйте конкатенацию строк.
Код:
str := str + s[random(2)+1]
Да и вообще str это встроенная паскалевская процедура. Используйте другое имя для переменной.
Код:
until (l>=4);
Здесь у Вас происходит зацикливание, т.к. условие никогда не выполняется.
Пользователь не знает, чего он хочет, пока не увидит то, что он получил.
Для благодарностей WMR R145235935681
GetMax вне форума Ответить с цитированием
Старый 27.09.2014, 11:04   #3
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Нужно найти список строк, каждая из этих строк имеет длину 8 символов, состоит из символов "0" и "1" и отличается от каждой строки списка минимум на 5 символов? Я правильно понял?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 27.09.2014, 22:41   #4
Lizoveta
Пользователь
 
Регистрация: 22.06.2013
Сообщений: 44
По умолчанию

Спасибо! Я все исправила Теперь, если сделать в конце, например,until l>=2 она выдает действительно строку, правда всего одну, без первой. Но это уже хоть что-то!
Цитата:
Сообщение от GetMax Посмотреть сообщение
Код:
until (l>=4);
Здесь у Вас происходит зацикливание, т.к. условие никогда не выполняется.
Почему же оно никогда не выполнится? Я просто не знаю, сколько там может получится строк, но я примерно предположила, что всяко больше 4...Неужели их будет меньше?
Lizoveta вне форума Ответить с цитированием
Старый 27.09.2014, 22:42   #5
Lizoveta
Пользователь
 
Регистрация: 22.06.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Нужно найти список строк, каждая из этих строк имеет длину 8 символов, состоит из символов "0" и "1" и отличается от каждой строки списка минимум на 5 символов? Я правильно понял?
Да, Вы все правильно поняли При этом список заведомо начинается со строки "00000000".
Lizoveta вне форума Ответить с цитированием
Старый 28.09.2014, 00:50   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Я написал тестовую программу. Она мне выдала список строк, соответствующих критериям:
Цитата:
- каждая из этих строк имеет длину 8 символов,
- состоит из символов "0" и "1",
- отличается от каждой строки списка минимум 5-ю символами
Вот этот список:
Код:
    00000000
    00011111
    11100011
    11111100
Каждая строка списка имеет минимум 5 отличий по отношению к любой из остальных строк списка при условии, что 1-я строка списка содержит только нули, а поиск вёлся последовательно от 00000001 до 11111111.

Это правильный ответ? Если нет, то приведи пример правильно сформированного списка.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 28.09.2014, 01:08   #7
Lizoveta
Пользователь
 
Регистрация: 22.06.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Я написал тестовую программу. Она мне выдала список строк, соответствующих критериям:

Вот этот список:
Код:
    00000000
    00011111
    11100011
    11111100
Каждая строка списка имеет минимум 5 отличий по отношению к любой из остальных строк списка при условии, что 1-я строка списка содержит только нули, а поиск вёлся последовательно от 00000001 до 11111111.

Это правильный ответ? Если нет, то приведи пример правильно сформированного списка.
Мне кажется, да. Здесь точно все подходят и вроде как больше ничего к нему не добавишь. Не можете подсказать, пожалуйста, как Вы организовали поиск всех вариантов именно последовательно от 00000001 до 11111111, а не как я рандомно?
Lizoveta вне форума Ответить с цитированием
Старый 28.09.2014, 01:15   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Не можете подсказать, пожалуйста, как Вы организовали поиск всех вариантов именно последовательно от 00000001 до 11111111, а не как я рандомно?
Если результат моей программы правильный и править её не надо, то я тебе исходник подарю и даже отвечу на твои вопросы по этому исходнику. Я сегодня добрый (наелся тёщиных пирожков). Главное - проверь и подтверди правильность результатов!
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 28.09.2014, 22:11   #9
Lizoveta
Пользователь
 
Регистрация: 22.06.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Если результат моей программы правильный и править её не надо, то я тебе исходник подарю и даже отвечу на твои вопросы по этому исходнику. Я сегодня добрый (наелся тёщиных пирожков). Главное - проверь и подтверди правильность результатов!
Вы понимаете, в чем проблема...Мне как бы правильный ответ то и надо было с помощью программы выяснить Так я на 100% утверждать не могу, но вроде в ручную я проверяла: все правильно.
Пирожки - это хорошо, а тёщины тем более. Надеюсь, доброту за день не растеряли?
Lizoveta вне форума Ответить с цитированием
Старый 28.09.2014, 22:19   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Надеюсь, доброту за день не растеряли?
Не растеряли. Угощайся. Если будут непонятки - спрашивай, это мой код, я за него отвечаю.

Код:
program p265982;

{$ifdef WIN32}
{$APPTYPE CONSOLE}
{$endif}

(*
  Для компиляции в турбо-паскале заменить все комментарии вида
  // текст комментария
  на комментарии вида
  { текст комментария }
*)

// перевод в строку 8-битного числа
function Byte2Bin(X: Byte): string;
var
  bit: Integer;
begin
  Result:= '00000000';
  bit:= 8;

  while X <> 0 do
    begin
      Inc(Result[bit], X and 1);
      Dec(bit);
      X:= X shr 1;
    end;
end;

// вычисление расстояния Левенштейна между двумя 8-битными числами
function LevenDistance(const A, B: Byte): Integer;
var
  Sum: Byte;
begin
  Sum:= A xor B; // различающиеся разряды (ключевое место всей программы)
  Result:= 0;

  // подсчёт кол-ва этих разрядов (оно и есть
  // то самое расстояние умного еврея Левенштейна)
  while Sum <> 0 do
    begin
      Inc(Result, Sum and 1); 
      Sum:= Sum shr 1;
    end;
end;

const                           
  Limit = 5;                    // начальное условие

var
  X: Byte;                      // 8-битное число для последовательного поиска
  Found: array[0..$FF] of Byte; // список найденных вариантов
  Index, Total: Integer;        // индексы
  LD: Integer;                  // для просмотра в отладчике (можно выкинуть)

begin
  Total:= 1;      // начальное условие
  Found[0]:= $00; // начальное условие

  // цикл поиска
  for X:= 1 to $FF do
    begin
      // проход по массиву найденных элементов и поиск в нём элемента,
      // расстояние которого относительно Х меньше Limit.
      // Если такой элемент в массиве не найден, значит добавит Х
      // в массив найденных элементов.
      Index:= 0;
      while Index < Total do
        begin
          LD:= LevenDistance(X, Found[Index]);
          if LD < Limit
            then Break; // не подходит - на выход

          Inc(Index);
        end;

      if Index = Total // подошло
        then begin
               Found[Total]:= X;
               Inc(Total); // кол-во найденных +1
             end;

    end;

  // вывод списка найденных на консоль
  for Index:= 0 to Total - 1 do
    WriteLn('    ', Byte2Bin(Found[Index]));
  WriteLn(' Total: ', Total);

  Write(' Press ENTER to exit... ');
  ReadLn;
end.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
найти расстояние от произвольной точки до ближайшей стороны треугольника. Неправильно находит расстояние zaira001002 Помощь студентам 4 05.11.2012 20:55
Сравнивание строк Gadvain Microsoft Office Excel 6 28.02.2012 12:11
Паскаль. Расстояние от точки до начала координат с использованием массивов. OFFSET Паскаль, Turbo Pascal, PascalABC.NET 5 25.11.2011 23:12
алгоритм Левенштейна alina1987 Помощь студентам 1 21.11.2009 15:11