Язык Си в примерах/Задача «Расчёт сопротивления схемы»: различия между версиями
Содержимое удалено Содержимое добавлено
Удалено содержимое страницы |
Striker (обсуждение | вклад) м Отмена правки 66983 участника 93.157.232.49 (обсуждение) |
||
Строка 1: | Строка 1: | ||
{{Содержание «Язык Си в примерах»}} |
|||
На данной задаче можно отработать технику разбора простых грамматик. |
|||
Параллельно-последовательная схема сопротивлений (ПП-схема) это |
|||
:*параллельно соединнённые ПП-схемы (записывается как "[s1 s2 .. sk]", k = 1, 2, ... ), |
|||
:ИЛИ |
|||
:*последовательно соединённые ПП-схемы (записывается как "(s1 s2 ... sm)", m = 1, 2, ..), |
|||
:ИЛИ |
|||
:*один резистор (обозначается действительным числом "R"). |
|||
На рис.1 приведён пример ПП-схемы и её описания в виде скобочной структуры. |
|||
[[Изображение:PS-sample.png]] |
|||
Рисунок 1. Пример ПП-схемы и её описания в виде скобочной структуры. |
|||
Запишем грамматику описания ПП-схем в [[:w:Форма Бэкуса — Наура|нотации Бэкуса — Наура]], расширенной регулярными выражениями: |
|||
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 |
|||
<source lang="c"> |
|||
#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; |
|||
} |
|||
</source> |
|||
[[Категория:Язык Си в примерах|Задача «Расчёт сопротивления схемы»]] |
Версия от 18:26, 13 сентября 2011
- Компиляция программ
- Простейшая программа «Hello World»
- Учимся складывать
- Максимум
- Таблица умножения
- ASCII-коды символов
- Верхний регистр
- Скобочки
- Факториал
- Степень числа
- Треугольник Паскаля
- Корень уравнения
- Система счисления
- Сортировка
- Библиотека complex
- Сортировка на основе qsort
- RPN-калькулятор
- RPN-калькулятор на Bison
- Простая грамматика
- Задача «Расчёт сопротивления схемы»
- Простая реализация конечного автомата
- Использование аргументов командной строки
- Чтение и печать без использования stdio
- Декодирование звукозаписи в формате ADX
- Другие примеры
На данной задаче можно отработать технику разбора простых грамматик.
Параллельно-последовательная схема сопротивлений (ПП-схема) это
- параллельно соединнённые ПП-схемы (записывается как "[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) {
return read_A(r) || read_B(r) || read_number(r);
}
int main() {
double r;
read_S(&r);
printf("%lf\n", r);
return 0;
}