基本情報技術者試験 整数式を受け取ってその値を返すプログラム
下記の問題のプログラムをCで実装しました。
基本情報技術者試験
平成30年度秋期
午後試験 問8 データ構造及びアルゴリズム 整数式の解析と計算
計算の途中の変数の状態を表示するようにしました。
#include <stdio.h> #include <stdlib.h> void print_status(int *value, char *operator, int *priority, int op_cnt) { int i; printf("value: "); for (i = 0; i < op_cnt + 1; i++) { printf("%d, ", value[i]); } printf("\n"); printf("operator: "); for (i = 0; i < op_cnt; i++) { printf("%c, ", operator[i]); } printf("\n"); printf("priority: "); for (i = 0; i < op_cnt; i++) { printf("%d, ", priority[i]); } printf("\n"); printf("op_cnt: %d\n\n", op_cnt); } int compute(char expression[]) { char operator[100]; int op_cnt, priority[100], value[100]; char chr; int i, ip, nest; // 解析処理 // 下記の変数が設定される // value[] 数値 // operator[] 演算子 // priority[] 演算子の実行の優先度 // op_cnt 演算子の数 op_cnt = 0; value[0] = 0; nest = 0; while (*expression) { chr = *expression; expression++; if (('0' <= chr) && (chr <= '9')) { value[op_cnt] = 10 * value[op_cnt] + atoi(&chr); continue; } if ((chr == '+') || (chr == '-') || (chr == '*') || (chr == '/')) { operator[op_cnt] = chr; if ((chr == '+') || (chr == '-')) { priority[op_cnt] = nest + 1; } else { priority[op_cnt] = nest + 2; } op_cnt++; value[op_cnt] = 0; continue; } if (chr == '(') { nest = nest + 10; continue; } if (chr == ')') { nest = nest - 10; continue; } } print_status(value, operator, priority, op_cnt); // 計算処理 while (op_cnt > 0) { // 優先度が最も高い演算子のインデックスをipに入れる ip = 0; for (i = 1; i < op_cnt; i++) { if (priority[ip] < priority[i]) ip = i; } chr = operator[ip]; switch (chr) { case '+': value[ip] = value[ip] + value[ip + 1]; break; case '-': value[ip] = value[ip] - value[ip + 1]; break; case '*': value[ip] = value[ip] * value[ip + 1]; break; case '/': value[ip] = value[ip] / value[ip + 1]; break; } for (i = ip + 1; i < op_cnt; i++) { value[i] = value[i + 1]; operator[i - 1] = operator[i]; priority[i - 1] = priority[i]; } op_cnt--; print_status(value, operator, priority, op_cnt); } return value[0]; } int main(int argc, char *argv[]) { // 整数式を実行時引数として渡す printf("%d\n", compute(argv[1])); return 0; }
$ ./compute_expression 2*(34-(5+67)/8) value: 2, 34, 5, 67, 8, operator: *, -, +, /, priority: 2, 11, 21, 12, op_cnt: 4 value: 2, 34, 72, 8, operator: *, -, /, priority: 2, 11, 12, op_cnt: 3 value: 2, 34, 9, operator: *, -, priority: 2, 11, op_cnt: 2 value: 2, 25, operator: *, priority: 2, op_cnt: 1 value: 50, operator: priority: op_cnt: 0 50