Матч 247, Произношение (Speller)

Дивизион 2, Уровень 3

 

Имеется строка, которая содержит целое число от 1 до 99 словами. Грамматика, описывающая число, имеет вид:

<NUMBER> ::= <ONES> | <TEEN> | <TENS> | <TENS>-<ONES>

<ONES> ::= one | two | three | four | five | six | seven | eight | nine

<TEEN> ::= ten | eleven | twelve | thirteen | fourteen | fifteen |

           sixteen | seventeen | eighteen | nineteen

<TENS> ::= twenty | thirty | forty | fifty | sixty | seventy | eighty | ninety

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

 

Класс: Speller

Метод: int value(String number)

Ограничения: строка number содержит от 1 до 20 символов, каждый из символов строки является кодом от 33 до 126 включительно.

 

Вход. Строка number, содержащая чсло от 1 до 99, записанное словами.

 

Выход. Целое число, которое является «ближайшим» по написанию к слову, записанному с строке number. Если существует несколько чисел, ближайших по написанию к number, вернуть -1.

 

Пример входа

number

Forty-two

FORTY-TWO

Eighteen

Fi

 

Пример выхода

42

-1

18

-1

 

 

РЕШЕНИЕ

обработка текста

 

Занесем в вектор строк v имена числительные, соответствующие числам от 1 до 99. Для заданной строки number ищем строку в массиве v, находящуюся на наименьшем расстоянии от нее. Или то же самое, что ищется строка в v, имеющая максимум общих букв с number. Если таких строк существует несколько (имеет место неоднозначность решения), то выводится -1. Иначе выводится значение переменной p, которая содержит искомый ответ.

Функция cmpr(string a, string b) возвращает -1 , если строки a и b имеют разную длину (расстояние между строками разной длины равно бесконечности). Иначе возвращаемое значение равно числу букв, находящихся на одинаковых позицияк.

 

ПРОГРАММА

 

#include <cstdio>

#include <string>

#include <vector>

using namespace std;

 

class Speller

{

public:

  int cmpr(string a, string b)

  {

    int i, res;

    if (a.size() != b.size()) return -1;

    for(i = res = 0; i < a.size(); i++) res += (a[i] == b[i]);

    return res;

  }

 

  int value(string number)

  {

    vector<string> v(100);

    int max = -1, p= -1, i, j;

    string digits[] = {"one","two","three","four","five","six","seven",

                        "eight","nine"};

    string teens[] = {"ten","eleven","twelve","thirteen","fourteen","fifteen",    

                      "sixteen","seventeen","eighteen","nineteen"};

    string tens[] = {"twenty","thirty","forty","fifty","sixty","seventy",

                     "eighty","ninety"};

    for(i = 0; i < 9; i++) v[i+1] = digits[i];

    for(i = 0; i < 10; i++) v[i+10] = teens[i];

    for(i = 20; i < 100; i++)

      if (i % 10 == 0) v[i] = tens[i / 10 - 2];

      else v[i] = tens[i / 10 - 2] + "-" + v[i % 10];

    for(i = 1; i < v.size(); i++)

    {

      j = cmpr(v[i],number);

      if (j > max) {max = j; p = i;} else

      if (j == max) p = -1;

    }

    return p;

  }

};