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

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
мНет описания правки
м Поправил программу
Строка 40: Строка 40:
int read_A(double*);
int read_A(double*);
int read_B(double*);
int read_B(double*);
int read_space() {
void read_space() {
int c ;
int c ;
do { c = getchar(); } while ( c==' ' || c=='\n' || c=='\t' );
do { c = getchar(); } while ( c==' ' || c=='\n' || c=='\t' );
if( c != EOF ) ungetc(c, stdin);
}
}
int read_number(double *r) {
int read_number(double *r) {

Версия от 08:45, 5 июля 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*);
   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) {
       return read_A(r) || read_B(r) || read_number(r);
   }
   int main() {
       double r;
       read_S(&r);
       printf("%lf\n", r);
       return 0;
   }