1

クラスでは、LSHIFT、RSHIFT、LCIRC、RCIRC、AND、XOR、OR という基本的な関数から始めて、ビット文字列フリックについて学び始めました。その後、突然、ビット文字列式を解析して評価する Python プログラムを作成するタスクが与えられました。ビット文字列式を手作業で解決するのはかなり簡単だと思いますが、Python を使用してビット文字列式を効率的に解析および評価する方法をよく理解していません。以下に必要なすべての関数を定義しました。これらは単一演算子式 (つまり、LCIRC 4 0010) で機能しますが、今のところ、複数演算子式 (つまり、LCIRC 3 LCIRC 3 0010) を解析する方法に完全に行き詰まっています。

import collections 
commands = ["LCIRC","RCIRC"] 
i = 0 
parse = input("Enter a string here to be evaluated. Use bitstrings only, as this program cannot catch any exceptions otherwise. -->").upper().replace("AND","&").replace("OR","|").replace("XOR","^").replace("NOT","~").split(" ") 
#parsing the function 

def lcirc(circ,operand): 
    circ = int(parse[i+1]) 
    operand = list(parse[i-1]) 
    parse.pop(i);parse.pop(i);parse.pop(i); 
    length = len(operand) 
    circ = circ % length 
    operand = operand[circ % length:]+ operand[:circ % length]                       
    operand = "".join(operand) 
    return operand 

def rcirc(Rcirc,operand): 
    Rcirc = int(parse[i+1]) 
    operand = list(parse[i-1]) 
    parse.pop(i);parse.pop(i);parse.pop(i); 
    length = len(operand) 
    Rcirc = Rcirc % length 
    operand = operand[-Rcirc % length:]+ operand[:-Rcirc % length]                       
    operand = "".join(operand) 
    return operand

def rshift(shift,operand): 
    shift = parse[i+1] 
    operand = list(parse[i+2]) 
    parse.pop(i);parse.pop(i);parse.pop(i); 
    print(operand) 
    length = len(operand) 
    if int(shift) >= len(operand): 
        for a in range(0,len(operand)): 
            operand.insert(0,"0") 
    if int(shift) < len(operand): 
        for a in range(0,int(shift)):
            operand.insert(0,"0") 
    operand = operand[:length] 
    operand = "".join(operand) 
    return operand 

def lshift(shift,operand):
    shift = parse[i+1]
    operand = list(parse[i+2])
    parse.pop(i);parse.pop(i);parse.pop(i);
    length = len(operand)
    if int(shift) >= len(operand):
        for a in range(0,len(operand)):
            operand.insert(length,"0")
    if int(shift) < len(operand):
        for a in range(0,int(shift)):
            operand.insert(length,"0")
    operand = operand[-length:]
    operand = "".join(operand)
    return operand

def and(op1, op2): #operand1, operand2
    return str(bin(int(op1,2) & int(op2,2))).replace("0b","")

def xor(op1, op2): #operand1, operand2
    return str(bin(int(op1,2) ^ int(op2,2))).replace("0b","")

def or(op1, op2): #operand1, operand2
    return str(bin(int(op1,2) | int(op2,2))).replace("0b","")

def evaluate(): 
    #parsing and evaluating the expression, insert code here.
    i = 0


while True: 
    if "LCIRC" not in parse and "RCIRC" not in parse and "RSHIFT" not in parse and "LSHIFT" not in parse and "~" not in parse and "|" not in parse and "&" not in parse and "^" not in parse: 
        break 
    else: 
        evaluate() 

print("Your answer is --> " +"".join(parse)) 

このプログラムは、次のような入力を受け取ることができる必要があります。

>>> LCIRC 1 0010
>>> Your answer is --> 0100
>>> LCIRC 1 LCIRC 1 0010
>>> Your answer is 1000
4

2 に答える 2

0

再帰または逆ポーランド記法のいずれかのタスクのようです

maxsplit引数で文字列分割メソッドを使用する私の簡単なアプローチ:

def evaluate(s):
    cmd, arg1, arg2 = s.split(None, 2)
    if ' ' in arg2:
        arg2 = evaluate(arg2)
    return command(arg1, arg2) # TODO: call correct function with correct arguments

def command(a1, a2):
    print a1, a2
于 2015-04-07T21:16:07.663 に答える
0

問題の説明を正しく理解していると仮定すると (2 番目のサンプル出力は 1000 になるはずですか?)、問題を解決する 2 つの方法を考えることができます。

1) 右から左に評価します。循環シフトのように、単一の変量関数呼び出しのみを見ている場合は、最も内側 (最も右側) の式を最初に評価するだけで問題ありません。

2)再帰を使用します。これは基本的に次のような形式になります (疑似コードを許してください)。

def handleExpression(str):
    #assuming str is of form of parse
    #if two sided operator
    if(typeof str[0] == number)
        #Find base operator and the two expressions which represent its arguments.
        #^^Format the arguments in the form of parse
        #(You can think of this in terms of parentheses: for every open parenthesis, you need a closing parenthesis.
        #So, you can just keep track of open and close "parentheses" until you reach an operand with a balance of "parentheses")
        operation = #xor, and, etc.
        return operation(handleExpression(leftSide), handleExpression(rightSide))
    else #some kind of shift
        #whatever code

明らかに、私はこのコードに大量の穴を残しましたが、結局のところ、これは割り当てではないでしょうか? :) これが、これがどのように機能するかについて考え始めるのに役立つことを願っています.

于 2015-04-07T21:09:05.560 に答える