Форум » Обработка числовых последовательностей » C4 диагностическая работа » Ответить

C4 диагностическая работа

oval: [quote]Вам необходимо написать программу распознавания чисел, записанных прописью. Сначала на вход программе подается обучающий блок, состоящий из 27 строк. Первые 9 строк содержат слова «один», «два», …, «девять», следующие 9 строк - слова «одиннадцать», «двенадцать», …, «девятнадцать», следующие 9 строк слова - слова «десять», «двадцать», …, «девяносто». Все слова записаны маленькими русскими буквами без лишних пробелов в начале и в конце строки. Затем на вход программе подается число N – количество записей, которые необходимо обработать. Следующие N строк содержат записанные словами числа. Каждое число записано по-русски, маленькими буквами, без ошибок. Если число состоит из нескольких слов, между словами находится ровно один пробел, лишних пробелов в начале и конце строк нет. Напишите эффективную программу, которая определяет сумму тех чисел, которые находятся в интервале от 1 до 99. Размер памяти, которую использует Ваша программа, не должен зависеть от длины исходного списка. Перед текстом программы кратко опишите используемый вами алгоритм решения задачи. Пример входных данных (обучающий блок показан в примере с сокращениями): один два …… девяносто 5 двадцать восемь два миллиона четырнадцать сто двадцать три тысяча девятьсот восемьдесят четыре Пример выходных данных для приведенного выше примера входных данных: 42 [/quote] решение [more][quote][pre2]var sum,j,i,t,n,number:integer; s, s1:string; word: array[1..27]of string; begin for i:=1 to 27 do readln(word[ i]); readln(n); sum:=0; for t:=1 to n do begin readln(s); number:=0; i:=1; while i <= length(s) do begin while (s[ i]<>' ') and (i <= length(s)) do i:=i+1; s1:=copy(s,1,i-1); delete(s,1,i); i:=1; j:=1; while (s1<> word[j]) and (j<=27) do j:=j+1; if j<=27 then case j of 1..9 : number:=number+j; 10..18: number:=number+j+1; 19..27: number:=number+(j-18)*10 end else begin i:=length(s)+1; number:=0; end; end; sum:=sum+number; end; writeln(sum); end.[/pre2][/quote][/more]

Ответов - 12

Поляков: oval пишет: while (s1<> word[j]) and (j<=27) do j:=j+1; Здесь нужно поменять местами условия, иначе получим выход за границы массива. Самое главное: на тестовом примере программа выдает 149 вместо 42.

oval: Поляков пишет: oval пишет: цитата: while (s1<> word[j]) and (j<=27) do j:=j+1; Здесь нужно поменять местами условия, иначе получим выход за границы массива. это да, не последнюю версию выложила :( Поляков пишет: Самое главное: на тестовом примере программа выдает 149 вместо 42. 42, еще раз проверила, ABCPascal чтение из файла.

Поляков: oval пишет: 42, еще раз проверила, ABCPascal чтение из файла. Да, приношу извинения. Ошибся при переводе на АЛГО (у него нет case). Мне кажется, что понятнее вариант с функциями: [pre2] for t:=1 to n do begin readln(s); number := 0; m := 1; while m > 0 do begin m := Pos(' ',s); if m = 0 then s1 := s else begin s1 := Copy(s, 1, m-1); Delete(s, 1, m); end; i := 1; while (i <= 27) and (s1 <> word[ i]) do i:=i+1; if i > 27 then begin m := 0; number := 0; end else if i < 19 then number:=number + i + (i div 10) else number:=number + (i-18)*10; end; sum:=sum+number; end; writeln(sum); [/pre2]


oval: Поляков пишет: Мне кажется, что понятнее вариант с функциями: возможно а еще можно было бы добавить 28 буферный элемент, тогда условие цикл while (i <= 27) and (s1 <> word[ i]) do i:=i+1; работал бы при любом порядке условий

oval: этот вариант написал мой ученик [pre2]var a: array [1..99] OF STRING; s:string; sum,i,j,n:integer; begin {обнуляем} for i:=1 to 9 do readln(a[ i]); for i:=11 to 19 do readln(a[ i]); i:=10; while i<=90 do begin readln (a[ i]); i:=i+10;end; for i:=2 to 9 do for j:=1 to 9 do a[10*i+j]:=a[10*i]+' '+a[j]; {построили полный алфавит} readln (n); {читаем количество строк, которые надо обработать} for i:=1 to n do begin readln (s); for j:=1 to 99 do if s=a[j] then sum:=sum+j; end; writeln(sum); end.[/pre2]

Поляков: oval пишет: этот вариант написал мой ученик Нечто похожее рекомендуют и авторы. Но мне не нравится это решение, большой расход памяти на лишние элементы массива. Хотя по критериям - это 4 балла.

tavabar: Прошу прощения, но не пойму, почему в ответах ДР№2 на задание С4 используется оператор j:=pos(line,' '); , а не оператор j:=pos(' ',line); ? Подскажите...

Поляков: tavabar пишет: почему в ответах ДР№2 на задание С4 используется оператор j:=pos(line,' '); , а не оператор j:=pos(' ',line); ? Опечатка. В Си-подобных языках сначала указываем где ищем, а потом - то, что ищем.

Бибиков: Здравствуйте. Оцените, пожалуйста, мое решение, которое кардинально отличается от того, что предлагается в КИМах: program Bibba; const u=90; var k,i,N,z,p,sum,total:integer; s,c:string; A:array[1..u] of string; begin total:=0; for i:=1 to u do A:=''; for i:=1 to 9 do readln(A); for i:=11 to 19 do readln(A); for i:=1 to 9 do readln(A[10*i]); readln(n); for i:=1 to n do begin; readln(s); sum:=0; z:=0; p:=pos(' ',s); if p>0 then begin c:=copy(s,1,p-1); delete(s,1,p); p:=pos(' ',s); if p=0 then begin for k:=1 to u do if A[k]=c then begin sum:=sum+k; z:=z+1; end; for k:=1 to u do if A[k]=s then begin sum:=sum+k; z:=z+1; end; if z=2 then total:=total+sum; end; end else for k:=1 to u do if A[k]=s then total:=total+k; end; writeln(total); end.

Бибиков: Суть решение такова: Введенный в начале учебный блок не подвергается изменениям. Затем в каждой нововведенной n-ой строке выполняется следующий алгоритм: 1)Ищется пробел 2)Если в слове только ОДИН пробел, то строка делится на два слова, каждое из которых сравнивается с массивом А. Только если оба слова принадлежат массиву они прибавляются к сумме 3)Если в слове больше одного пробела - ничего не выполняется 4)Если в слове один пробел - проверяется принадлежность всей строки к массиву А. 5)В итоге выводится общая сумма

Поляков: Бибиков пишет: Оцените, пожалуйста, мое решение, которое кардинально отличается от того, что предлагается в КИМах: Согласно критериям для этой задачи, это 4 балла. Но решение какое-то половинчатое, недоделанное. Если выделять массив, то эффективнее строить полный словарь. Если разбирать строку по пробелам, то достаточно 27 элементов массива.

malloc: Добрый вечер. Оцените, пожалуйста, мое решение (язык C++, компилятор MinGW) #include <stdio.h> #include <string.h> #include <ctype.h> struct Word{ char word[20]; int num; } dict[27]; int space_count(char *str){ for (int i = 0; i < strlen(str); i++) if (isspace(str[ i])) return 1; return 0; } int getnum(char* str){ for (int i = 0; i < 27; i++) if ( !strcmp(dict[ i].word, str) ) return dict[ i].num; return -1; } int main(void){ int N, buf1, buf2, result = 0; char str1[20], str2[20], temp[100]; for (int i = 0; i < 9; i++){ dict[ i].num = i+1; dict[ i+9].num = i+11; dict[ i+18].num = (i+1)*10; } for (int i = 0; i < 27; i++) gets(dict[ i].word); scanf("%d ", &N); for (int i = 0; i < N; i++){ gets(temp); buf2 = space_count(temp); if ( (buf2 == 0) && ((buf1 = getnum(temp)) > 0) ) result += buf1; else if (buf2 == 1){ sscanf(temp, "%s %s", str1, str2); if ( ((buf1 = getnum(str1)) > 0) && ((buf2 = getnum(str2)) > 0) ) result += buf1 + buf2; } } printf("%d\n", result); return 0; }



полная версия страницы