Технический форум

Технический форум (http://www.tehnari.ru/)
-   Помощь студентам (http://www.tehnari.ru/f41/)
-   -   Процедуры и функции на языке Pascal (http://www.tehnari.ru/f41/t106386/)

Олес 15.01.2016 17:32

Процедуры и функции на языке Pascal
 
Описать функцию PosLast(subS,S) целого типа, возвращающую номер позиции, с которой в строке S содержится последнее вхождение подстроки subS. Если в строке S отсутствуют подстроки subS, то функция возвращает 0. пожалуйста, помогите написать программу как можно подробнее. почему она считает с конца? зачем нужно k?

Function PosLast(subs, s: string): byte;
var
i, k: byte;
begin
k:=0;
i:=length(s);
while(i>= 1) and (k=0) do
if copy(s, i, length(subs))=subs then k:=i
else i:=i - 1;
PosLast:= k;
end;
var
s, s1: string;
i: byte;
begin
for i := 1 to 2 do
begin
writeln('Введите строку');
readln(s);
writeln('Введите подстроку');
readln(s1);
writeln('Номер позиции последнего вхождения=', PosLast(s1, s));
writeln;
end;
end.

Vladimir_S 15.01.2016 20:41

Цитата:

Сообщение от Олес (Сообщение 1198810)
Описать функцию PosLast(subS,S) целого типа, возвращающую номер позиции, с которой в строке S содержится последнее вхождение подстроки subS. Если в строке S отсутствуют подстроки subS, то функция возвращает 0. пожалуйста, помогите написать программу как можно подробнее. почему она считает с конца? зачем нужно k?

Знаете... я, извините, не стал разбираться с Вашей программой, а просто накатал свою. Надеюсь, устроит.
Пояснения:
1. В Паскале существует стандартная функция Pos(Substr,S:String):Byte, возвращающая индекс (номер первого элемента) вхождения подстроки в строку. Почему бы ею не воспользоваться?
2. Но если таких вхождений несколько, то функция Pos выдаст индекс первого из них. А нам надо последнего.
3. Выход: проинвертировать (переписать наоборот от конца к началу) и строку, и подстроку, потом через Pos найти индекс.
4. Но найденный индекс будет соответствовать последней букве исходной подстроки, причем считая справа налево.
5. Поэтому индекс нужно пересчитать.
Код:

Function PosLast(Subs, S: string): byte;
var
 k,i,L1,L2: byte;
 S_inv,Subs_inv:String;
begin
 L1:=Length(S);
 S_inv:='';
 for i:=1 to L1 do
  S_inv:=S_inv+S[L1-i+1];
 L2:=Length(Subs);
 Subs_inv:='';
 for i:=1 to L2 do
  Subs_inv:=Subs_inv+Subs[L2-i+1];
 k:=Pos(Subs_inv,S_inv);
 if k>0 then k:=L1+2-k-L2;
 PosLast:=k;
end;

var
 s,s1: string;

begin
 writeln('Enter the string:');
 readln(s);
 writeln('Enter the substring:');
 readln(s1);
 writeln('Last entry position number is ', PosLast(s1,s));
 readln
end.

Программа отлажена и оттестирована на Free Pascal.

Олес 15.01.2016 23:53

что считает конкретно эта скобка? S[L1-i+1]

Vladimir_S 16.01.2016 11:15

Цитата:

Сообщение от Олес (Сообщение 1198921)
что считает конкретно эта скобка? S[L1-i+1]

Она ничего не "считает".
Прежде всего, заметим, что тип "строка" в какой-то мере эквивалентен типу "массив символов" (Array [1..N] of Char). Но не полностью. Читать символ S[i] - можно, а вот присваивать (S[i]:='Щ') - нельзя, но можно добавлять символ: S:=S+'Щ'.
Теперь допустим, что Вам нужно "перевернуть" строку S, создав строку-перевертыш S1. Пусть S содержит N знаков. Тогда в строке S1 символы должны встать в позиции:
S1[1] ↔ S[N]
S1[2] ↔ S[N-1]
...
S1[N-1] ↔ S[2]
S1[N] ↔ S[1]
И вообще
S1[i] ↔ S[N-i+1]
Вот это и делается.

Vladimir_S 16.01.2016 11:23

Еще один момент.
Заменил в предпоследней строке функции
k:=L1-k-L2+2;
на
k:=L1+2-k-L2;
Разумеется, это одно и то же, просто сообразил, что в некоторых случаях некоторые трансляторы, получив промежуточный отрицательный результат, могут заверещать (в смысле выдать сообщение об ошибке).

Олес 17.01.2016 17:29

спасибо большое)


Часовой пояс GMT +4, время: 09:32.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.