2014-09-30 182 views
-1

我的任務是以字符串的形式接受數學運算並以整數形式返回答案。操作順序也被忽略,數學運算必須從左到右解決。爲什麼我的'while'循環沒有返回值?

我的代碼可能可能更短/更簡單,但這是我想出的。我的策略是遍歷字符串中的每個字符,直到我碰到一個運算符(+, - ,x,/)。然後運算符之前的數字串變成一個整數。操作員被存儲爲變量c,以便可以使用當前編號和遇到的下一個編號(c = 1表示加法等)完成操作。

當我運行程序時,它應該打印變量total,但不打印任何東西。 return語句是否退出當前的if語句或退出while循環?問題是別的嗎?

def compute(e): 
    a=0 #starting index used to check specific characters in string 
    b=0 #to keep track of index after last operator 
    l=len(e) #length of e to use for while loop 
    st="" 
    total=0 #result of all previous calculations 
    count=0 #keeps track of number of operators passed 
    c=0 #Used to keep track of what operator was last passed 
     #c=1 is addition 
     #c=2 is subtraction 
     #c=3 is multiplication 
     #c=4 is division 
    while l>0: 
     if e[a].isdigit(): 
      return 
     elif e[a]=="+" or e[a]=="-" or e[a]=="x" or e[a]=="/": #When an operator is detected in string 
      st=e[b:a] #To combine all numbers between two operators into one string 
      count=count+1 #to keep track of number of operators passed 
      b=a+1 #now b is the index after the last operator 
      if count==1: #This is the first operator encountered in string 
       total=int(st) #The string is stored as total because this is the first integer stored 
      else: 
       num=int(st) #The string of numbers is stored as num instead of total 
      if count==1: #This means this is the first operator and there should not be an operation done yet 
       return 
      elif c==1: 
       total=total+num 
      elif c==2: 
       total=total-num 
      elif c==3: 
       total=total*num 
      elif c==4: 
       total=total/num 
      if e[a]=="+": 
       c=1 
      elif e[a]=="-": 
       c=2 
      elif e[a]=="x": 
       c=3 
      elif e[a]=="/": 
       c=4 
     else: 
      return None 
     a=a+1 
     l=l-1 
    print(total) 

compute("22-11x4") 
input("Wait") 
+0

return語句退出整個功能,它打破了任何和所有的循環。 – BrenBarn 2014-09-30 04:11:05

+0

@BrenBarn所以可以放置在剛剛脫離當前if語句的返回語句的位置? – krzy122 2014-09-30 04:14:40

+0

使用** continue **語句在while循環中跳過其餘的執行而不是返回語句 – 2014-09-30 04:18:46

回答

-1

我會指出一些有助於您解決此問題的方法。首先,像許多人指出return語句突破了該函數,因此不應該在while循環中使用。如果需要,將它們替換爲breakcontinue。其次,這段代碼:

if e[a].isdigit(): 
     return 

沒有必要我覺得。由於無論如何循環都會繼續,無論e[a]的值是多少,並且該值都在total變量中不斷積累。

第三,如果我沒有錯,則將操作符分配給整數。雖然這可以取消,但是您在分配這些整數代碼之前使用這些整數代碼執行計算,因爲您在更新total變量後執行檢查以將值分配給c。因此,我認爲只要您輸入elif區塊,在您檢查當前字符是否爲操作員的情況下,您的第一步應該是爲c指定適當的值並進行必要的計算。

喜歡的東西:

elif e[a]=="+" or e[a]=="-" or e[a]=="x" or e[a]=="/": #When an operator is detected in string 
     st=e[b:a] #To combine all numbers between two operators into one string 
     count=count+1 #to keep track of number of operators passed 
     b=a+1 #now b is the index after the last operator 
     if count==1: #This is the first operator encountered in string 
      total=int(st) #The string is stored as total because this is the first integer stored 
     else: 
      num=int(st) #The string of numbers is stored as num instead of total 

     #Assign operator values 
     if e[a]=="+": 
      c=1 
     elif e[a]=="-": 
      c=2 
     elif e[a]=="x": 
      c=3 
     elif e[a]=="/": 
      c=4 

     #Perform arithmetic operation 
     if count !=1: #Not the first operator, we can accumulate the values 
      if c==1: 
      total=total+num 
      elif c==2: 
      total=total-num 
      elif c==3: 
      total=total*num 
      elif c==4: 
      total=total/num 

我已經重構你elif塊只是一點點。我已經取消了return聲明,並在我們進行計算之前執行了檢查。實際上,這是您應該這樣做的唯一檢查,因此可以刪除最外面的ifelse語句,並且可以將return刪除,並且只需執行一條if語句即可安全替換。我希望它能讓你對代碼有一定的瞭解,並讓你開始朝正確的方向發展。

+0

你能解釋爲什麼你投下我的答案嗎? – 2014-09-30 05:33:07

+0

我沒有downvote它。我看到你不需要'isdigit()'的觀點,它會繼續下去,因爲這個角色不是操作員。我在做操作後分配'c'值的原因是每次遇到操作員時,都需要找到該操作員後面的數字,並將其與操作員之前的數字一起使用。所以當它遇到一個操作符時,它將取得它之前的數字,並使用存儲的'c'值來執行最後一次遇到的操作符的操作。在完成操作之後分配'c',以便它可以在下一個完整號碼 – krzy122 2014-09-30 16:46:47

0

下面是一個例子,我用一種不同的方法解決底層問題。我的'calculate'函數將字符串分爲「非數字的東西」(re.split(r'(\D+)', string)),存儲分割的東西);然後我們走結果列表(for item in re.split(r'(\D+)', string):)。

如果是一串連續的數字(if re.match(r'\d+', item):),我們會將它附加到collections.deque();如果是空格(if re.match(r'\s+', item):),我們會將其丟棄(continue)。否則,我們假設它是一個運算符,它只是附加到operators列表中(特殊情況下爲x,我們將其轉換爲*--這在我的角色中完全是一種表達)。

我定義了一個lambdas字典(doop,'do operations'),其中鍵是我支持的運算符,表達式是要執行的數學運算。現在剩下的就是遍歷operators列表(for op in operators),爲該運算符找到正確的lambda(doop[op]()),然後調用它 - 在操作數deque(operands.popleft())上傳遞兩個「top」值,將結果向右回到列表頂部,以便下一個operator消耗(operands.appendleft())。

我的簡單示例無法處理很多邊緣情況,它顯然不知道運算符優先級(但您說它不應嘗試應用該方法)。我只是想給你一個替代的方法,可能會讓你的想法走上不同的道路 - 也許比所有的if/elsif/else更容易維護。

import collections 
import re 

doop = { 
    '+': lambda x,y: x+y, 
    '*': lambda x,y: x*y, 
    '-': lambda x,y: x-y, 
    '/': lambda x,y: x//y 
} 

def calculate(string): 
    operands = collections.deque() 
    operators = [] 
    for item in re.split(r'(\D+)', string): 
     if re.match(r'\d+', item): 
      operands.append(int(item)) 
      continue 
     if re.match(r'\s+', item): 
      continue 
     else: 
      if item == 'x': 
       item = '*' # *shrug* 
      operators.append(item) 
    for op in operators: 
     operands.appendleft(doop[op](operands.popleft(),operands.popleft())) 
    result = operands.pop() 
    print("Calculated %s to be %s" % (string, result)) 
    return result 


strings = ["15+2*3-7", "22-11x4"] 
for string in strings: 
    calculate(string) 
+0

中使用。感謝您的輸入。我的代碼中的'if' /'else'語句有點多。我明白你在說什麼,但是我的代碼看起來有點太複雜,我目前正在使用cs1。不過感謝您的幫助! – krzy122 2014-09-30 16:52:36

+0

我想盡可能多 - 我試圖提供一個答案,可以讓您對一些想法進行很好的調查,以確保您隨着課程的繼續而感到滿意。祝你好運! – TML 2014-09-30 17:08:09

1

試試這個代碼:

def compute(e): 
    l=len(e) 
    seperate=[] 
    indexf=0 
    indexl=0 
    count=1 
    total=0 
    num=0 

    for i in range(0,l): 
     if (e[i].isdigit()): 
      indexl=indexl+1 
     else: 
      num=e[indexf:indexl] 
      indexf=indexl+1 
      indexl=indexf 
      seperate.append(num) 
      seperate.append(e[i]) 
    num=e[indexf:indexl+1] 
    seperate.append(num) 

    l=len(seperate) 

    for i in range(0,l): 
     if (count==1): 
      total=int(seperate[i]) 
      count=count+1 
     else: 
      if (not(seperate[i].isdigit())): 
       if (seperate[i]=="+"): 
        total=total+int(seperate[i+1]) 
       elif (seperate[i]=="-"): 
        total=total-int(seperate[i+1]) 
       elif (seperate[i]=="*") or (seperate[i]=="X")or(seperate[i]=="x"): 
        total=total*int(seperate[i+1]) 
       elif (seperate[i]=="/"): 
        total=total/int(seperate[i+1]) 

    print("Resault is %d ,Have a good time" %(total)) 

st=input("Please insert your expression :") 
compute(st)