ページ 11

電卓作成

Posted: 2020年10月19日(月) 13:05
by txkr
C言語で式を入力すると式の値が出てくるようなプログラミングを作成したいです。とりあえず足し算と掛け算と括弧の3つの演算記号の組み合わせだけで作りたいです。ソースコードを教えていただけると助かります。例:入力3+4(2*6+3) 出力63

Re: 電卓作成

Posted: 2020年10月19日(月) 21:19
by みけCAT
C言語のソースコードを教えてしまうとtxkrさんが作成する余地が無くなってしまいそうなので、
とりあえずPythonで書いてみました。

コード:

import sys

def add(a, b):
    return a + b

def mul(a, b):
    return a * b

def add_num(n):
    return lambda s: s.append(n)

def calc(f):
    def do_calc(s):
        s[-2] = f(s[-2], s[-1])
        s.pop()
    return do_calc

q = sys.stdin.readline().rstrip()

converted_expr = []
op_stack = []

zero = ord('0')

current = -1

prev_kokka = False

for c in q:
    v = ord(c) - zero
    if c == '+':
        if current >= 0:
            converted_expr.append(add_num(current))
            current = -1
        while len(op_stack) > 0 and op_stack[-1][0] >= 0:
            converted_expr.append(calc(op_stack.pop()[1]))
        op_stack.append((0, add))
    elif c == '*':
        if current >= 0:
            converted_expr.append(add_num(current))
            current = -1
        while len(op_stack) > 0 and op_stack[-1][0] >= 1:
            converted_expr.append(calc(op_stack.pop()[1]))
        op_stack.append((1, mul))
    elif c == '(':
        if current >= 0:
            converted_expr.append(add_num(current))
            current = -1
            while len(op_stack) > 0 and op_stack[-1][0] >= 1:
                converted_expr.append(calc(op_stack.pop()[1]))
            op_stack.append((1, mul))
        op_stack.append((-1, None))
    elif c == ')':
        if current >= 0:
            converted_expr.append(add_num(current))
            current = -1
        while len(op_stack) > 0 and op_stack[-1][0] >= 0:
            converted_expr.append(calc(op_stack.pop()[1]))
        op_stack.pop()
    elif 0 <= v and v <= 9:
        if current < 0:
            current = 0
            if prev_kokka:
                while len(op_stack) > 0 and op_stack[-1][0] >= 1:
                    converted_expr.append(calc(op_stack.pop()[1]))
                op_stack.append((1, mul))
        current = current * 10 + v
    else:
        raise Exception("invalid character")
    prev_kokka = c == ')'

if current >= 0:
    converted_expr.append(add_num(current))

while len(op_stack) > 0:
    converted_expr.append(calc(op_stack.pop()[1]))

calc_stack = []

for op in converted_expr:
    op(calc_stack)

if len(calc_stack) != 1:
    raise Exception("invalid expression")

print(calc_stack[0])
デモ

Re: 電卓作成

Posted: 2020年10月20日(火) 11:29
by txkr
返信ありがとうございます。申し訳ないのですが、pythonをかじっていないのでできればC言語で書いていただけたら助かります。申し訳ないですが、よろしくお願いします。

Re: 電卓作成

Posted: 2020年10月20日(火) 19:24
by あたっしゅ
今、気が付いたが

> 例:入力3+4(2*6+3) 出力63

3+4*(2*6+3) じゃなくて 3+4(2*6+3) なんですか ?
4と( の間に、 * は、入らないんですか ?

Re: 電卓作成

Posted: 2020年10月21日(水) 14:04
by txkr
入らないです!普通の数学の式を打ち込む感じです!

Re: 電卓作成

Posted: 2020年10月21日(水) 21:34
by あたっしゅ
 この機会に Python を勉強すればいいだろ。なぜ、それができない。
もしかして、 C 言語の初心者だから、Python を並行して勉強すると混乱する、ということなのか。

 「普通の数学の式を打ち込む感じ」だと、「c言語 電卓 プログラム」とかで検索して出てくるプログラムは、
そのままでは使えない。数字の次に ( が出てきたら、* を突っ込む、という処理を加えれば、いいのか ?

 「c言語 電卓 プログラム」とかで検索した結果は、
1+2
3*4
といった2項の計算しかできないものから、
スタック使って逆ポーランド書法でやるもの、
c++ と boost で木構造つくるもの
等があった。