Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Pascal
Перезагрузить страницу удалить второе вхождение подстроки в строку без использования функций Паскаля
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
Max$$ Max$$ вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 16.10.2017
По умолчанию удалить второе вхождение подстроки в строку без использования функций Паскаля - 16.10.2017, 12:21

Здравствуйте! Помогите найти ошибку в программе!!

Лаба: написать программу, удаляющую второе вхождение подстроки в исходную строку,пункта запрещается использовать стандартные функции для работы со строками (за исключением фукнции определения длины строки). Нашел функцию по алгоритму Бойера-Мура, но программа работает так, что удаляет все вхождения, а мне нужно каждое второе. В чем ошибка?

Pascal Код:
Program lab2;
uses crt;
 
 function BMSearch(StartPos: Integer; const S, P: String): Integer;
 type
 TBMTable = array[0..255] of Integer;
 var
 Pos, lp, i, kol: Integer;
 BMT: TBMTable;
 begin
 
 for i := 0 to 255 do BMT[i] := Length(P);
 for i := Length(P) downto 1 do if BMT[Byte(P[i])] = Length(P) then
 BMT[Byte(P[i])] := Length(P) - i;
 
 lp := Length(P);
 Pos := StartPos + lp -1;
 while Pos <= Length(S) do
 if P[lp] <> S[Pos] then Pos := Pos + BMT[Byte(S[Pos])] else
 if lp = 1 then begin Result := Pos; Exit; end else
 for i := lp - 1 downto 1 do if P[i] <> S[Pos - lp + i] then
 begin
 Inc(Pos);
 Break;
 end else if i = 1 then
 begin
 Result := Pos - lp + 1;
 
 Exit;
 end;
 Result := 0;
 end;
 
 Procedure Vvod(var s1,s2:string);
 begin
 Writeln('Введите исходную строку: ');
readln(s1);
 writeln('Введите подстроку: ');
readln(s2);
 end;
 
 Procedure Vivod(s1,s2:string);
 begin
 writeln('Результат: ',s1);
 end;
 
 function Del(s1, s2: String):string;
 var i, n: integer;
 begin
 i := 0; n := 1;
 
 repeat
 n := BMSearch(1, s1, s2);
 if n > 0 then
 begin
 inc(i);
 if i mod 2 = 0 then delete(s1, n, length(s2)) else inc(n);
 end;
 until n = 0;
 Del := s1;
 end;
 
 var
 s1, s2: string;
 
 begin
 Vvod(s1,s2);
 s1 := Del(s1, s2);
 Vivod(s1,s2);
 readln;
 end.
Ответить с цитированием
  (#2 (permalink)) Старый
deckard deckard вне форума
Member
 
Сообщений: 77
Сказал(а) спасибо: 0
Поблагодарили 5 раз(а) в 5 сообщениях
Регистрация: 04.03.2008
По умолчанию 16.10.2017, 16:38

Pascal Код:
delete(s1, n, length(s2))

Вы одновременно в цикле сканируете строку s1, а потом удаляете из s1
подстроку s2, так что строка s1 меняется. Т е следующий BMSearch
сканирует уже не исходную, а урезанную s1. А надо сначала просканировать
строку и получить массив из вхождений, а затем обработать этот массив
и удалить нужные подстроки.
Ответить с цитированием
  (#3 (permalink)) Старый
Max$$ Max$$ вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 16.10.2017
По умолчанию 17.10.2017, 16:15

Работает как надо теперь. Ошибка была в n := BMSearch(1, s1, s2); Поиск вхождений каждый раз начинался с первой позиции. Заменил 1 на n и все стало работать правильно, удаляются все четные вхождения. Ваш вариант тоже попробую, спасибо!
Ответить с цитированием
  (#4 (permalink)) Старый
Max$$ Max$$ вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 16.10.2017
По умолчанию 30.11.2017, 21:13

Цитата:
Сообщение от deckard Посмотреть сообщение
Pascal Код:
delete(s1, n, length(s2))

Вы одновременно в цикле сканируете строку s1, а потом удаляете из s1
подстроку s2, так что строка s1 меняется. Т е следующий BMSearch
сканирует уже не исходную, а урезанную s1. А надо сначала просканировать
строку и получить массив из вхождений, а затем обработать этот массив
и удалить нужные подстроки.
Вы были правы. Как исправить эту программу, чтобы она не удаляла, а заносила в массив позиции четных вхождений? Что-то я запутался...
Ответить с цитированием
  (#5 (permalink)) Старый
deckard deckard вне форума
Member
 
Сообщений: 77
Сказал(а) спасибо: 0
Поблагодарили 5 раз(а) в 5 сообщениях
Регистрация: 04.03.2008
По умолчанию 01.12.2017, 16:57

Основой программы является функция

myinstr(start:integer;s1:string;s2:string):integer ;

которая ищет подстроку в строке с позиции start.

Эта функция в свою очередь использует функцию mymid для
поиска подстроки.

Обратите внимание на 3 последовательных цикла
в функции del: удаляемые символы
сначала находятся, затеи заменяются кодом chr(1)
и только затем удаляются

Pascal Код:
function myLen(s:string):integer;
begin
myLen:=ord(s[0]);
end;

function mymid(s:string;b:integer;l:integer):string;
var i:integer;buf:string[255];
begin
buf:='';
for i:=b to b+l-1 do begin
if i<=myLen(s) then buf:=buf+s[i];
end;
mymid:=buf;
end;

function myinstr(start:integer;s1:string;s2:string):integer;
var scanwindow:string;l1:integer;l2:integer;i:integer;
begin
l1:=myLen(s1);l2:=myLen(s2);
myinstr:=0;
for i:=start to l1+1-l2 do begin
  scanwindow:=mymid(s1,i,l2);
  if scanwindow=s2 then begin myinstr:=i;exit;end;
end;
end;

function del(s:string;c:string):string;
var p,start,i,j,n,L:integer;ins:array [0..100] of integer;
buf:string;bufdel:string;
begin
bufdel:=s;
start:=1;L:=myLen(c);
if L=0 then begin del:=s;exit;end;
{ischem vse podstroki i sohranyaem nachalnye pozicii
v massive ins[n]}

n:=0;
repeat
p:=myinstr(start,s,c);
if p>0 then begin n:=n+1;ins[n]:=p;start:=p+L;end;
until p=0;
{zapolnyaem udalyaemye symvoly kodom chr(1)}
i:=0;
repeat
i:=i+2;
if i<=n then begin for j:=ins[i] to ins[i]+L-1 do bufdel[j]:=chr(1); end;
until i>n;
writeln(bufdel);
{ubiraem udalyaemye simvoly}
buf:='';L:=myLen(s);
for j:=1 to L do begin if bufdel[j]<>chr(1) then buf:=buf+bufdel[j] end;
del:=buf;
end;

{main}
var a:string;b:string;
begin
a:='test1 test2 test3 test4 test5 test6';
b:=del(a,'test');
writeln(b);
readln;
end.
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Max$$ Max$$ вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 16.10.2017
По умолчанию 02.12.2017, 20:11

Спасибо большое!!!!
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
удалить строку time_to_go_on Prolog 3 28.06.2012 22:36
Вхождение буквы в строку Hom9IchOK С/С++ 11 25.12.2009 17:28
С использованием спискоразрушающих функций удалить из списка первое вхождение yaLex Lisp 2 02.12.2009 12:19
Как удалить последнюю строку если она пустая Kate&amp;Lena Visual C++ 4 19.08.2009 17:34
Как удалить адресную строку в браузере? Alexuc Любые вопросы от новичков 5 01.12.2008 20:01
Как удалить последнюю строку в файле Marla Singer Perl 1 07.11.2008 08:14
сортировка без использования встроенных функций Bardessa PHP 15 12.01.2007 01:57
Как удалить строку из таблицы elf_grey C++ Builder 1 20.07.2006 16:25
Как удалить из файла одну строку dazhdbog C++ Builder 3 30.12.2005 17:32
Как удалить из строки все заданные подстроки slayerwow Pascal 3 17.11.2005 19:42
Как удалить строку из текстового файла Yor1k Visual C++ 4 28.02.2004 16:58
Как из матрицы удалить строку с введенным номером Belldandy Assembler 2 05.06.2003 18:00



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов