Язык Си в примерах/Задача «Расчёт сопротивления схемы»: различия между версиями
Содержимое удалено Содержимое добавлено
Greck (обсуждение | вклад) мНет описания правки |
Greck (обсуждение | вклад) мНет описания правки |
||
Строка 12: | Строка 12: | ||
[[Изображение:PS-sample.png]] |
[[Изображение:PS-sample.png]] |
||
Рисунок 1. Пример ПП-схемы и её описания в виде скобочной структуры. |
|||
⚫ | |||
⚫ | |||
S ::= A | B | number. |
S ::= A | B | number. |
||
A ::= '(' S+ ')' . |
A ::= '(' S+ ')' . |
||
Строка 18: | Строка 20: | ||
number ::= digit+ ('.' digit+ )? . |
number ::= digit+ ('.' digit+ )? . |
||
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' . |
digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' . |
||
*Вход. Строчка с описанием схемы. |
*Вход. Строчка с описанием схемы. |
||
Строка 25: | Строка 26: | ||
*Выход. Значение сопротивления схемы (с точностью до 0.1%). |
*Выход. Значение сопротивления схемы (с точностью до 0.1%). |
||
Вход#1 Выход#1 |
Вход#1 Выход#1 |
||
Строка 35: | Строка 35: | ||
Вход#3 Выход#3 |
Вход#3 Выход#3 |
||
(3 0 1) 4 |
(3 0 1) 4 |
||
#include <stdio.h> |
#include <stdio.h> |
Версия от 10:21, 15 мая 2006
На данной задаче можно отработать технику разбора простых грамматик.
Параллельно-последовательная схема сопротивлений (ПП-схема) это
- параллельно соединнённые ПП-схемы (записывается как "[s1 s2 .. sk]", k = 1, 2, ... ),
- ИЛИ
- последовательно соединённые ПП-схемы (записывается как "(s1 s2 ... sm)", m = 1, 2, ..),
- ИЛИ
- один резистер (обозначается действительным числом "R").
На рис.1 приведён пример ПП-схемы и её описания в виде скобочной структуры.
Рисунок 1. Пример ПП-схемы и её описания в виде скобочной структуры.
Запишем грамматику описания ПП-схем в нотации w:en:BNF, расширенной регулярными выражениями:
S ::= A | B | number. A ::= '(' S+ ')' . B ::= '[' S+ ']' . number ::= digit+ ('.' digit+ )? . digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
- Вход. Строчка с описанием схемы.
Значения сопротивлений — действительные числа из отрезка [0, 100000]. Размер входа не превосходит 200000 байт.
- Выход. Значение сопротивления схемы (с точностью до 0.1%).
Вход#1 Выход#1 [2 2 2] 0.6666667
Вход#2 Выход#2 ([1 1] 0.5 [3.2 (1 1)]) 2.230769
Вход#3 Выход#3 (3 0 1) 4
#include <stdio.h> int read_S(double*); int read_A(double*); int read_B(double*); int read_space() { int c ; do { c = getchar(); } while ( c==' ' || c=='\n' || c=='\t' ); } int read_number(double *r) { return ( scanf("%lf", r) == 1 ); } int read_A(double *r) { int c; if( (c=getchar()) == '(') { double q; *r = 0; if( ! read_S(r) ) return 0; while( read_S(&q) ) { *r += q; } if( (c=getchar()) == ')') { return 1; } else { return 0; } } else { ungetc(c, stdin); return 0; } } int read_B(double *r) { int c; if( (c=getchar()) == '[' ) { double q; *r = 0; if( ! read_S(r) ) return 0; *r = 1 / *r; while( read_S(&q) ) { if(q != 0) *r += 1 / q; } *r = 1 / *r; if( (c=getchar()) == ']' ) { return 1; } else { return 0; } } else { ungetc(c, stdin); return 0; } } int read_S(double *r) { return read_A(r) || read_B(r) || read_number(r); } int main() { double r; read_S(&r); printf("%lf\n", r); return 0; }