СДАМ ГИА: РЕШУ ЕГЭ
Образовательный портал для подготовки к экзаменам
Информатика
Информатика
Cайты, меню, вход, новости


Задания
Версия для печати и копирования в MS Word
Задания Д19 C4 № 3632

Вам необходимо написать программу распознавания чисел, записанных прописью. Сначала на вход программе подаётся обучающий блок, состоящий из 27 строк. Первые 9 строк содержат слова "один", "два", ...., "девять", следующие 9 строк — слова "одиннадцать", "двенадцать", ... "девятнадцать", следующие 9 строк — слова "десять", "двадцать", ..., "девяносто". Все слова записаны меленькими русскими буквами без лишних пробелов в начале и в конце строки.

Затем на вход программе подаётся значение N — количество записей, которые необходимо обработать. Следующие N строк содержат записанные словами числа. Каждое число записано по-русски, маленькими буквами, без ошибок. Если число состоит из нескольких слов, между словами находится ровно один пробел, лишних пробелов в начале и в конце строк нет.

Напишите эффективную программу, которая определит сумму тех входных чисел, которые находятся в интервале то 1 до 99.

Размер памяти, которую использует Ваша программа, не должен зависеть от длины исходного списка.

Перед текстом программы кратко опишите используемый Вами алгоритм решения задачи.

 

Пример входных данных (обучающий блок показан в примере с сокращениями):

один

два

...

девяноста

5

двадцать восемь

два миллиона

четырнадцать

сто двадцать три

тысяча девятьсот восемьдесят четыре

Пример выходных данных для приведённого выше примера входных данных:

42

Решение.

Вариант 1.

 

Программа читает обучающий блок и запоминает написание чисел и их значения. Допускается построение полного "словаря" всех чисел от 1 до 99 или хранение только исходного обучающего блока. В приведённом примере на Паскале реализовано построение полного "словаря".

Затем программа читает входные строки, не запоминая их в массиве. Если построен полный "словарь", прочитанная строка ищется в этом словаре как единое целое. Числовое значение введённой строки равно сумме значений составляющих слов. Если вся строка при поиске в полном "словаре" отсутствует в обучающих данных, введённое число не попадает в интервал от 1 до 99 и не должно учитываться. Дополнительная проверка вхождения числа в заданный интервал не требуется, т. к. все числа, которые удаётся распознать с помощью приведённого обучающего блока, автоматически в него попадают, но за наличие такой дополнительной проверки в программе оценка снижается.

 

Паскаль
program c4;

program c4;

var

w: array[1..99] of string;

N: integer;

s: integer;

line: string;

i, j: integer;

begin

{читаем обучающий блок}

for i := 1 to 9 do readln(w[i]);

for i := 11 to 19 do readln(w[i]);

for i := 1 to 9 do readln(w[10*i]);

{строим полный словарь}

for i := 2 to 9 do begin

for j := 1 to 9 do begin

w[10*i + j] := w[10*i]+ ' ' + w[j];

end;

end;

{читаем и обрабатываем основной набор данных}

readln(N);

s:= 0 ;

for i:=1 to N do begin

readln(line);

j:=1;

while (j<100) and (w[j]<>line) do j:=j+1;

if j<100 then s:=s+j; end;

writeln(s);

end.

 

Вариант 2.

Программа читает обучающий блок и запоминает написание чисел и их значения. Допускается построение полного "словаря" всех чисел от 1 до 99 или хранение только исходного обучающего блока. В приведённом примере на Паскале — хранение исходного обучающего блока. Если полный "словарь" отсутствует, строка разбивается на слова (в подходящей строке их может быть не более двух). Числовое значение введённой строки равно сумме значений составляющих слов. Если какое-то слово отсутствует в обучающих данных, введённое число не попадает в интервал от 1 до 99 и не должно учитываться. Дополнительная проверка вхождения числа в заданный интервал не требуется, т. к. все числа, которые удаётся распознать с помощью приведённого обучающего блока, автоматически в него попадают, но за наличие такой дополнительной проверки в программе оценка снижается.

 

Паскаль
program c4;

const nw=27;

var

words: array[1..nw] of string;

values: array[1..nw] of integer;

{поиск слова в словаре, возврат числового значения}

function word2value (w: string) : integer;

var

i: integer;

begin

i:=1;

while (i<=nw) and (words[i]<>w) do i:=i+1;

if i<=nw then word2value:=values[i]

else word2value:=0;

end;

var

N: integer;

s: integer;

v1, v2: integer;

line: string;

i, j: integer;

begin

{читаем обучающий блок}

for i := 1 to 9 do begin

readln(words[i] ) ;

values[i] :=i ;

end;

for i := 10 to 18 do begin

readln(words[i]);

values[i]:=i+1;

end;

for i := 19 to 27 do begin

readln(words[i]);

values[i] :=10*(i-18) ;

end;

{читаем и обрабатываем основной набор данных}

readln(N);

s:= 0 ;

for i:=1 to N do begin

readln(line);

j:=pos(line, ' ') ;

if j>0 then begin

v1:= word2value(copy(line,1,j-1));

v2:= word2value(copy(line,j+1,length(line)-j));

if (v1>0) and (v2>0) then s:=s+v1+v2;

end

else begin

v1:= word2value(line);

if v1>0 then s:=s+v1;

end;

end;

writeln(s);

end.

 

Бейсик
DIM w$(99)

FOR i = 1 TO 9

LINE INPUT w$(i)

NEXT i

FOR i = 11 TO 19

LINE INPUT w$(i)

NEXT i

FOR i = 10 TO 90 STEP 10

LINE INPUT w$(i)

NEXT i

FOR i = 20 TO 9 0

FOR j = 1 TO 9

w$(i + j) = w$(i) + " " + w$(j)

NEXT j

NEXT i

INPUT N s = 0 FOR i = 1 TO N

LINE INPUT line$

j = 1

WHILE j < 100 AND w$(j) <> line$

j = j + 1

WEND

IF j < 10 0 THEN s = s + j

NEXT i

PRINT s

END

 

Алгоритмический язык
алг c4 нач

литтаб слова[1:99]

лит трока

цел N

цел сумма

цел i, j

нц для i от 1 до 9

ввод слова[i]

кц

нц для i от 11 до 19

ввод слова[i]

кц

нц для i от 10 до 90 шаг 10

ввод слова[i]

кц

нц для i от 20 до 90 шаг 10

нц для j от 1 до 9

кц

кц

ввод N

сумма:= 0

нц для i от 1 до N

ввод строка

j : =1

нц пока j < 10 0 и слова [j] <>строка

j:=j +1

кц

если j <10 0 то сумма:=сумма+j все

кц вывод

кон

 

Перл
for $v (1..9, 11..19, 20, 30, 40, 50, 60, 70, 80, 90) {

chomp ($w = <>) ;

$value{$w} = $v; }

$n = <>;

$s = 0;

while ($ n--) {

chomp ($line = <>);

$num = 0;

$value{$w}}

for $w (split / /,$line) {

if ($value{$w}) {$num += $value{$w}}

else {$num=0; last}

}

$s += $num;

}

print $s;