2016-10-18 2 views
2

그래서 저는이 사이트 (오늘)와 Ruby 프로그래밍 언어 (3 일 전)에 익숙하지 않으므로 두려워하지 마십시오. 내 코드를 찢어 버려라. 나는 배우고 더 잘하기 위해 노력하고있다.루비 계산기 - 올바르게 저장되지 않는 해시

기본적으로 나는 사용자로부터 간단한 수학 문제 (또는 수학 문제의 문자열)를 읽고 방정식을 풀 수있는 콘솔 계산기를 만들고 있습니다. 그것은 작업 순서 나 아무것도 (아직) 사용하지 않으며, 내가 알 수없는 이상한 버그를 제외하고 기본적으로 작동합니다.

Userinput = "1 + 2 + 3 - 4" 
# First I split the user input into an array of stirngs and then loop over the 
# array of strings and depict whether a string is a key or hash (see code below) 

# program should store these characters in a hash like so.. 
hash = { nil=>1, "+"=>2, "+"=>3, "-"=>4 } 

그런 다음 해시 키를 사용하여 다음에 더하기, 빼기, 곱하기 또는 나누기 여부를 결정합니다.

모든 것이 잘 작동합니다. 즉, 2 개 이상의 작업 (예 : 1 + 2 - 0 + 3)에서 문제가 발생하면 프로그램에서 일부 키와 연산자를 임의로 삭제합니다. 나는 패턴을 찾기 위해 다른 예제를 시도해 왔지만 소스를 찾을 수 없다. 아래에서는 문제의 예제와 출력, 해시 자체 및 전체 소스 코드를 게시합니다. 도움이나 비평에 미리 감사드립니다!

예 형식

프로그램 입력 (사용자 프롬프트, 사용자 입력) - 프로그램 출력 (식의 합) - 실행

예 1

끝에 해시

수학 문제 유형 (예 : 40/5) : 40/5 + 2 - 5 * 5 - 5 * 5 - 100

-450

{닐 => 40, "/"=> 5, "+"= "2"- "="100 "*"=> 5}

예 2

수학 문제를 입력하십시오 (예 : 5분의 40) : 1 + 2 - 0 + 3

4

{전무 = "1"+ "=> 3,"- "=> 0}

예 3

형 수학 문제 (예 5분의 40.) : 10 - 5 * 2 + 8 + 2

12

{닐 => 10, "-"= "5"* "=> 2,"+ "=> 2}

소스 코드 : main.rb

=begin 

    main.rb 
    Version 1.0 
    Written by Alex Hail - 10/16/2016 

    Parses a basic, user-entered arithmetic equation and solves it 

=end 

@operationsParser = "" # global parser 
@lastKeyAdded = "" 

private 
def appointType(sv) 
    if sv =~ /\d/ 
     sv.to_i 
    else 
     sv 
    end 
end 

private 
def operate(operations) 
    sum = 0 
    operations.each do |k, v| 
    if k.nil? 
     sum += v 
    else 
     case k 
     when '+' then sum += v 
     when '-' then sum -= v 
     when '*' then sum = sum * v 
     when '/' then sum = sum/v 
     else 
     end 
    end 
    end 
    sum 
end 

private 
def solveEquation 
    print "Type a math problem (ex. 40/5): " 
    userInput = gets.chomp 

    #array to hold all numbers and their cooresponding operation 
    operations = {} # <== Empty hash 

    #split the user input via spaces 
    @operationsParser = userInput.split(" ") 

    #convert numbers into numbers store operators in hash (nil => 40, "/" => 5) -- would be 40/5 
    @operationsParser.each do |stringValue| 
    if appointType(stringValue).is_a? Integer 


    operations[@lastKeyAdded != "" ? @lastKeyAdded : nil] = appointType(stringValue) 

    else #appointType will return a string by default 
     keyToAdd = appointType(stringValue) 
     @lastKeyAdded = keyToAdd 
    end 
    end 

    #check if operators(+, *, -, /, or nil) in the keys are valid, if not, error and exit, if so, operate 
    operations.each do |k,v| 
    case k 
     when '+' 
     when '-' 
     when '*'  
     when '/' 
     when nil 
     else 
     # Exit the program if we have an invalid operator in the hash 
     puts "Exiting program with error - Invalid operator used (Only +, -, *,/please)" 
     return 
    end 
    end 

    sum = operate(operations) 


    puts sum, operations 
end 

solveEquation 
+0

처럼 보일 것입니다. 해시는 키당 하나의 인스턴스로 제한되므로 토큰이 두 번 나타나면 해시가 중단됩니다. 배열은 어떻습니까? – tadman

+0

오, 당신이 아주 옳습니다! 어리석은 .. 아마 배열을 사용하여 그 방식으로 파싱 할 수 있습니다. 감사!! –

+1

배열에서 [Polish notation] (https://en.wikipedia.org/wiki/Polish_notation)으로 시퀀스를 변환 할 수 있습니다. 예를 들어 '2 + 3 * 4-1'은'[ '-', [ '+', 2, [ '*', 3, 4]], 1]. – tadman

답변

2

문제가 당신이 정의에 의해 해시는 항상 값에 매핑 할 고유 키의 집합을 유지해야하고, 선택한 데이터 구조입니다 그래서 좋아.이제 해시를 사용하여 죽은 경우해볼 수있는 방법은 모든 키를 빈 배열에 매핑 한 다음 숫자 값을 추가하여 각 배열에있는 모든 값에 해당 연산을 처리하는 것입니다 (조작 순서를 무시하고 있기 때문에) 당신이 당신의 배열을 처리 할 때

h = Hash.new([]) #to set the default value of each key to an empty arrary 

그런 다음 당신은`{ "+"=> 1, "+"=> 2}`, 그것은 불가능 할 수 없습니다이

{nil =>[1], '+' => [1, 2, 3], '-' => [3, 7], '*' => [4, 47], '/' => [3, 5]} 
+0

누군가가 내 원래의 게시물에 대한 의견에 내 질문에 대답했지만 이것은 또한 도움이되었다. –

+0

당신의 지식을 추구하는 데 좋은 행운이 좋은 excise입니다. –