2009-05-30 5 views
0

En répondant à this code golf question, j'ai rencontré un problème dans ma réponse.Comparaison de chaînes non reproductibles, force l'échec elsif

Je l'ai testé et je ne peux même pas obtenir ces deux comparaisons pour travailler dans le code, en dépit du fait que l'IRB a le bon comportement. I vraiment besoin d'aide ici.

Voici le code, ci-dessous qui sera une explication du problème.

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 

Le problème se produit dans l'attribution des negate.

Je dois annuler pour être vrai lorsque le caractère juste avant une expression est un tiret, mais la condition ne fonctionne même pas. Les deux n == '-' et n[0] == '-', la forme de la citation n'a pas d'importance, enrouler FAUX à chaque fois. Pourtant, j'ai utilisé cette comparaison exacte et n == '(' fonctionne correctement à chaque fois!

Que se passe-t-il? Pourquoi ne fonctionne pas n == '-', quand n == '(' fait? Ceci est encodé en UTF-8 sans BOM, UNIX linebreaks.

Quel est le problème avec mon code?

Répondre

3

Vous avez:

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

Comme n est toujours une chaîne d'un caractère, si (chars[0] == '(' && n[0] == '-')) est vrai, alors la condition précédente, (!chars[0].nil? && chars[0] != ' ' && n == '-'), sera également vrai. Votre code n'entrera jamais dans la deuxième partie du if si n[0]=='-'.

Si votre ligne p n génère un tiret, assurez-vous qu'il s'agit bien du même caractère que celui que vous recherchez, et non pas du caractère que ressemble à un tiret. Unicode a de nombreux types de tirets, peut-être avez-vous un caractère unicode bizarre dans votre code ou sur votre entrée.

+0

Merci beaucoup, il ne m'était pas venu à l'esprit que la déclaration précédente avait attrapé mon code. Merci pour les yeux frais. –

Questions connexes