Pergunta

Ao responder este código questão golf , deparei com um problema na minha resposta .

Tenho vindo a testar esta e eu não posso mesmo começar estas duas comparações ao trabalho no código, apesar do fato de que o IRB tem o comportamento certo. I realmente precisa de alguma ajuda aqui.

Aqui está o código, abaixo, que será uma explicação do problema.

def solve_expression(expr)
  chars = expr.split '' # characters of the expression
  parts = []  # resulting parts
  s,n = '','' # current characters

  while(n = chars.shift)
    if (s + n).match(/^(-?)[.\d]+$/) || (!chars[0].nil? && chars[0] != ' ' && n == '-') # only concatenate when it is part of a valid number
      s += n
    elsif (chars[0] == '(' && n[0] == '-') || n == '(' # begin a sub-expression
      p n # to see what it breaks on, ( or -
      negate = n[0] == '-'
      open = 1
      subExpr = ''
      while(n = chars.shift)
        open += 1 if n == '('
        open -= 1 if n == ')'
        # if the number of open parenthesis equals 0, we've run to the end of the
        # expression.  Make a new expression with the new string, and add it to the
        # stack.
        subExpr += n unless n == ')' && open == 0
        break if open == 0
      end
      parts.push(negate ? -solve_expression(subExpr) : solve_expression(subExpr))
      s = ''
    elsif n.match(/[+\-\/*]/)
      parts.push(n) and s = ''
    else
      parts.push(s) if !s.empty?
      s = ''
    end
  end
  parts.push(s) unless s.empty? # expression exits 1 character too soon.

  # now for some solutions!
  i = 1
  a = parts[0].to_f # left-most value is will become the result
  while i < parts.count
    b,c = parts[i..i+1]
    c = c.to_f
    case b
      when '+': a = a + c
      when '-': a = a - c
      when '*': a = a * c
      when '/': a = a / c
    end
    i += 2
  end
  a
end

O problema ocorre na atribuição de negate.

Eu preciso negar ser verdadeira quando o personagem pouco antes de uma expressão é um traço, mas a condição não é mesmo trabalhando. Ambos n == '-' e n[0] == '-', a forma de citação não importa, acabam FALSE cada vez. No entanto, eu tenho usado essa comparação exata e n == '(' funciona corretamente cada vez!

O que está acontecendo? Por que não n == '-' trabalho, quando n == '(' faz? Este é codificado em UTF-8 w / o BOM, quebras de linha UNIX.

O que há de errado com o meu código?

Foi útil?

Solução

Você tem:

if (s + n).match(/^(-?)[.\d]+$/) || (!chars[0].nil? && chars[0] != ' ' && n == '-')
      s += n
elsif (chars[0] == '(' && n[0] == '-') || n == '('

Como n é sempre uma string de um único caractere, se (chars[0] == '(' && n[0] == '-')) é verdade, então a condição anterior, (!chars[0].nil? && chars[0] != ' ' && n == '-'), vai também ser verdade. O seu código nunca vai entrar na segunda parte do if se n[0]=='-'.

Se a sua linha p n está a emitir um traço, ter certeza que é exatamente o mesmo personagem que você está procurando, não algum personagem que se parece com um traço. Unicode tem muitos tipos de traços, talvez você tenha um carácter unicode traço estranho em seu código ou em sua entrada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top