Консультация № 178073
28.04.2010, 10:58
43.11 руб.
0 8 1
Доброго времени суток дорогие эксперты!

Необходимо решить парочку задач на тему "Строковый тип"

Задание 1: Составить программу, которая использует указанную функцию или процедуру обработки строки. Реализация такой подпрограммы должна происходить без использования стандартных процедур и функций при работе со строками (length, concat, copy, delete, insert, pos, uppercase, lowercase и др; сравнение строк напрямую недопустимо – допускается лишь посимвольное сравнение).
Причем: необходимо реализовать подпрограмму, реализующую указанную последовательность действий при заданных ограничениях (если таковые имеются).

вот задача 1:
Функция Poz_end(subs,s:string):integer, аналогичная стандартной функции Pascal Pos(subs,s:string):integer, с той лишь разницей, что функция Poz_end находит последнее вхождение в строке s подстроки subs.

Задача 2) 2) Вводится строка. Если она является записью числа в римской системе счисления, то преобразовать ее в целое число.


Писать программы и под программы в TP-7.0 с коментариями для понимания большего!

Обсуждение

Неизвестный
28.04.2010, 21:15
общий
это ответ
Здравствуйте, Юдин Евгений Сергеевич.

Решение первой задачи (я позволил себе назвать требуемую функцию LastPos, поскольку Poz_end — коряво (ни английский, ни русский) и по смыслу неверно — "позиция конца")
Код:
program q178073a;

{ функция находит последнее вхождение в строке s подстроки substr
возвращает найденную позицию или 0, если подстрока substr не найдена в строке s
}
function LastPos( substr: String; s: String): byte;
var nS, nSub, p, i : integer;
ok : boolean;
begin
nS := ord( s[0] ); { длина строки s }
nSub := ord( substr[0] ); { длина искомой подстроки substr }
p := nS - nSub; { отступаем от конца строки s на длину искомой подстроки }
while p >= 0 do begin { пока не проверили всю строку s }
ok := true; { предполагаем совпадение }
for i := 1 to nSub do
if substr[i] <> s[p+i] then begin
ok := false; { нет, не совпало }
break;
end;

if ok then begin { нашли последнее вхождение }
LastPos := p+1; { возвращаем позицию }
exit;
end;
dec( p ); { в данной позиции не совпало, переходим к предыдущей }
end;
LastPos := 0; { подстрока не найдена, возвращаем 0 }
end;

procedure test( substr, str: string );
var n: byte;
begin
n := LastPos( substr, str );

if n > 0 then
writeln( 'Позиция последнего вхождения подстроки "', substr,
'" в строку "', str, '" = ', n )
else
writeln( 'Подстрока "', substr, '" не найдена в строке "', str, '"' );
end;

begin
test( '123', 'asdf123123qwer12312zx' );
test( '123', '123asfjkafj' );
test( '123', 'asfjkafj123' );
test( '123', 'asfjkafj' );
test( '123', '12' );
end.


Решение второй задачи приведено в приложении.
Программа проверена на табличке примеров со страницы википедии Римские цифры

Обе программы протестированы в среде Borland Pascal 7.0. Чтобы текст смотрелся нормально, установите шаг табуляции = 4.

Успехов!

Приложение:
{ Преобразование чисел из римской системы в десятичную }
program q178073b;

{
Перевод римского числа в арабское.
Функция возвращает числовое значение переданной строки или
отрицательное число при ошибке:
-1 - встретился недопустимый символ
-2 - слишком длинная строка
}
function rome2arabic( a: string ): longint;
var i, len: integer;
b: array [1..50] of integer;
s: longint;
begin
len := length( a );
if len > 50 then begin
rome2arabic := -2; { слишком длинная строка }
exit;
end;

for i := 1 to len do begin
if not (a[i] in ['I','V','X','L','C','D','M']) then begin
rome2arabic := -1; { встретился недопустимый символ }
exit;
end;
case a[i] of
'I': b[i] := 1;
'V': b[i] := 5;
'X': b[i] := 10;
'L': b[i] := 50;
'C': b[i] := 100;
'D': b[i] := 500;
'M': b[i] := 1000;
end;
end;
s := b[1];
for i := 2 to len do begin
inc( s, b[i] );
if b[i-1] < b[i] then dec( s, 2*b[i-1] )
end;
rome2arabic := s;
end;

var s: string;
n: longint;

begin
while true do begin
write( 'Римское число или [Enter] для выхода: '); readln( s );
if length(s) = 0 then exit;

n := rome2arabic( s );
if n < 0 then
writeln( 'Недопустимый символ для числа в римской системе' )
else
writeln( n );
end;
end.
5
Отличный ответ) все вроверил и все работает) Выражаю огромню благодарность за содеяное вам amnick!
давно
Академик
320937
2216
28.04.2010, 21:23
общий
amnick:
Добрый вечер! Программа на ввод IIIIIIIIII выдает ответ 10, а должна быть ошибка.
Неизвестный
28.04.2010, 22:14
общий
lamed:
К сожалению, я не знаю точных правил записи. Согласно википедии, (см. ссылку в ответе):
Натуральные числа записываются при помощи повторения этих цифр. При этом, если большая цифра стоит перед меньшей, то они складываются (принцип сложения), если же меньшая — перед большей, то меньшая вычитается из большей (принцип вычитания).

Или, например, вот здесь.

Нигде не оговаривается предел количества повторений одного знака. Вы уверены, что IIIIIIIIII является неверным? Если бы Вы дали ссылку, то тогда можно попытаться исправить программу. Да, я заметил при тестировании, что, например, строка IIX преобразуется в 10 — и по вышеприведнному правилу так и должно быть: 1 + (10-1), хотя правильность записи вызывает сомнение. Что сказали бы древнеримские учителя по этому поводу?

Программа преобразует корректное римское число, но не может определить правильность записи, если используются допустимые символы. Полагаю, что для учебного примера этого вполне достаточно.
Неизвестный
28.04.2010, 22:48
общий
amnick:
Я полагаю, они (достаточно одного) высекли бы Вас розгами и поставили на горох
Посмотрите википедию: Википедия - максимум использовали четыре подряд идущих I, и то только до 1390 года. То есть второй принцип построения чисел - минимизация записи
Неизвестный
28.04.2010, 23:07
общий
Ну, это не смертельно, хотя и ой как больно .
Почитал-таки статью более внимательно и нашел:
Регулярное выражение для проверки римских цифр — '^(?i)M{0,3}(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$'.
А про "четыре подряд идущих I" я и так знал.
Можно сделать проверку в соответствии с этим выражением. Весьма желательно услышать мнение Юдина Евгения Сергеевича — нужно ли это? Потому как время требуется, чтобы написать эту проверку.
Неизвестный
28.04.2010, 23:11
общий
Юдин Евгений Сергеевич:
Ну, Евгений Сергеевич, слово за Вами. Кстати, работу эксперта Вы не оценили. Али плохо помог? Если "плохо", то чем - давайте поправим
Неизвестный
29.04.2010, 18:58
общий
Юдин Евгений Сергеевич:
Если нужна проверка ввода в соответствии с вышеприведенным регулярным выражением, то напишите, не откладывая! На выходных я ни на какие вопросы не отвечаю!
Неизвестный
30.04.2010, 14:48
общий
Спасибо все работает)
Форма ответа