Язык Си в примерах/Задача «Расчёт сопротивления схемы»

Опубликовано: 01.10.2018

видео Язык Си в примерах/Задача «Расчёт сопротивления схемы»

Решение задачи на языке C++

Материал из Викиучебника — открытых книг для открытого мира

На данной задаче можно отработать технику разбора простых грамматик.



Параллельно-последовательная схема сопротивлений (ПП-схема) это

параллельно соединнённые ПП-схемы (записывается как "[s1 s2 .. sk]", k = 1, 2, ... ), ИЛИ последовательно соединённые ПП-схемы (записывается как "(s1 s2 ... sm)", m = 1, 2, ..), ИЛИ один резистор (обозначается действительным числом "R").

На рис.1 приведён пример ПП-схемы и её описания в виде скобочной структуры.


Информатика. Язык Си: Массивы в Си. Центр онлайн-обучения «Фоксфорд»

Рисунок 1. Пример ПП-схемы и её описания в виде скобочной структуры.

Запишем грамматику описания ПП-схем в нотации Бэкуса — Наура , расширенной регулярными выражениями:


Информатика. Язык Си: Явное и неявное преобразование типов в Си. Центр онлайн-обучения «Фоксфорд»

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 * ); void read_space () { int c ; do { c = getchar (); } while ( c == ' ' || c == '\n' || c == '\t' ); if ( c != EOF ) ungetc ( c , stdin ); } 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 ) { read_space (); return read_A ( r ) || read_B ( r ) || read_number ( r ); } int main () { double r ; read_S ( & r ); printf ( "%lf \n " , r ); return 0 ; }