Estuve investigando Ruby y sentí que estaba aprendiendo bastante. Actualmente estoy tratando de resolver el algoritmo de paréntesis balanceados pero tengo problemas con una condición. Esto es lo que tengo:
def balanced?(list_of_brackets) if list_of_brackets.length % 2 != 0 false else stack = [] bracket_sets = { '{' => '}', '[' => ']', '(' => ')' } list_of_brackets.chars do |bracket| if bracket == "{" or "[" or "(" puts "#{bracket} is an opening bracket" else puts "#{bracket} is a closing bracket" end end end stack.empty? end puts balanced?('{}()[]')El resultado que obtengo es:
{ is an opening bracket } is an opening bracket ( is an opening bracket ) is an opening bracket [ is an opening bracket ] is an opening bracketLos paréntesis de cierre de alguna manera superan la primera condición. Me estoy perdiendo algo aquí, pero no puedo detectarlo. Tal vez otro par de ojos pueda ayudarme aquí. Agradecería cualquier ayuda y/o consejo!
Esta
if bracket == "{" or "[" or "(" es básicamente verificar si el corchete es igual a "{" o si "[" es verdadero o "(" es verdadero, te perdiste el bracket == para el resto de ellos. Es por eso que toman la rama if y obtienes todos ellos son paréntesis de apertura La solución para ese problema es comparar cada uno de ellos:
if bracket == "{" || bracket == "[" || bracket == "(" ... PD: asegúrese de no confundir OR con || , tienen diferente procedencia.
La sentencia if bracket == "{" or "[" or "(" necesita tener un bracket == X para cada condición or en la sentencia. Cambio:
if bracket == "{" or "[" or "("para
if bracket == "{" or bracket == "[" or bracket == "("... y eso debería funcionar. El código completo sería:
def balanced?(list_of_brackets) if list_of_brackets.length % 2 != 0 false else stack = [] bracket_sets = { '{' => '}', '[' => ']', '(' => ')' } list_of_brackets.chars do |bracket| if bracket == "{" or bracket == "[" or bracket == "(" puts "#{bracket} is an opening bracket" else puts "#{bracket} is a closing bracket" end end end stack.empty? end puts balanced?('{}()[]')Usaré el término cerramientos para referirme a los paréntesis ( '(' y ')' ), corchetes ( '[' y ']' ) y llaves ( '{' y '}' ). Una cadena de recintos está balanceada si:
Por ejemplo, '([{}])' está bien anidado mientras que '([{]})' no lo está, ya que la cadena que separa el par coincidente, '[' y ]' , es decir, '{' , no es un par emparejado.
Si, en el código de la pregunta, la longitud de la cadena es par, la stack se inicializa en una matriz vacía que nunca cambia, entonces el valor de retorno stack.empty? siempre será true . Por ejemplo, balanced?(')[') #=> true . Necesitas algo como lo siguiente.
RIGHT_ENCLOSURE_PAIRS = { '}'=>'{', ']'=>'[', ')'=>'(' } RIGHT_ENCLOSURES = RIGHT_ENCLOSURE_PAIRS.keys def balanced?(str) stack = [] str.each_char do |c| if RIGHT_ENCLOSURES.include?(c) return false if stack.empty? || stack.last != RIGHT_ENCLOSURE_PAIRS[c] stack.pop else stack << c end end stack.empty? end balanced? '{}()[]' #=> true balanced? '([{}])' #=> true balanced? '([{}]{})' #=> true balanced? '((([[[{{{}}}]]])))' #=> true balanced? '{[]' #=> false balanced? '{{(([[' #=> false balanced? '{()[{]}(([]))' #=> falseInicialmente tenía la siguiente cláusula de protección como la primera línea del método.
return false if str.length.odd?Sin embargo, después de reflexionar, lo eliminé, ya que el tiempo empleado en ejecutarlo innecesariamente para cadenas con números pares de recintos probablemente fue mucho mayor que el tiempo ahorrado para cadenas con números impares de recintos.
No he incluido declaraciones put como puts puts "#{c} is an opening enclosure" , ya que normalmente solo se usarían para la depuración, pero, por supuesto, podrían agregarse si se desea, en cuyo caso podría ser más útil escribir
ENCLOSURE_TYPE = { '('=>'left parenthesis', ')'=>'right parenthesis', '['=>'left bracket', ']'=>'right bracket', '{'=>'left brace', '}'=>'right brace' } puts "#{c} is a #{ENCLOSURE_TYPE[c]}"Otros abordaron el problema de la sintaxis, pero si desea deshacerse de las comparaciones redundantes con bracket , aquí hay otro enfoque más simplificado que quizás desee considerar:
["{", "[" , "("].include? bracket Esto coloca todas las cadenas deseadas en una sola array y luego prueba para ver si bracket está incluido en esa matriz. O incluso podría tomar su hash bracket_sets existente y probar para ver si su soporte está incluido en las keys de ese grupo...
bracket_sets.key?(bracket)