所以我试图重新定义字符串,使其表现得像代数中的表达式一样,比如“x”+“1”应该返回“x + 1”而不是“x1”,“x - 1”*“x + 1”应该返回“x² - 1”,而不是像我们处理多项式那样的未定义和类似的东西。所以我做了一些很好的方法来处理简单的操作,但有一件事我不知道。我一直在调试我定义的String::simplify方法,当在程序中使用时,它总是显示一些错误。可疑的方法:String::simplify
,String::simplify2
& String::minus
错误示例:puts ("x - 1"*"x + 1").simplify
=〉它在String::minus
方法中的第138行产生一个错误,说nil与2的比较失败
希望它能更清楚地识别逻辑或其他地方的故障
class String
@@powers = %w(⁻ ˙ ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹)
@@store = Hash[(["-","."]+[*"0".."9"]).zip @@powers]
@@reply = "Sorry ,super strings can't tolerate your madness"
def monomial?;self.terms.size == 1end
def polynomial?;!self.monomial?end
def * b #multiplication
if(self.polynomial? or b.polynomial?)
s = []
self.terms.each do |i|
b.terms.each do |j|
q = i._ j
q.end_with?("x¹") ? s << q.chomp("¹") : s << q
end
end
return s.join " + "
end
self._ b
end
def _ b #multiplication of two terms
@negative = 1
@negative *= -1 if self.include? "-"
@negative *= -1 if b.include? "-"
self.gsub!("x","x¹") if self.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).empty?
b.gsub!("x","x¹") if b.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).empty?
self.gsub!("x","1x") if self.scan(/\d+/).empty?
b.gsub!("x","1x") if b.scan(/\d+/).empty?
m = "#{@negative}".scan(/\D+/).join
x = "#{self.scan(/\d+/).join.to_i * b.scan(/\d+/).join.to_i}x#{(self.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).join.unsup.to_i + b.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).join.unsup.to_i).to_s.sup}".gsub(/(\D*)(1x)/,"\1x")
if x.scan(/\d+/).empty?
x.gsub! "x⁰","1"
else
x.gsub! "x⁰",""
end
return "0" if (m+x) == "-0"
return m+x
end
def sup;self.gsub /\S/,@@store;end #from normal to supersrcipt string
def unsup #from superscript to normal string
self.gsub /[⁻⁰¹²³⁴⁵⁶⁷⁸⁹]/,@@store.invert
end
def ** n;([self]*n).reduce :*end #exponentiation of expression
def degree #degree of polynomial
z = self.dup
z.gsub!("x","x¹") if z.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).empty?
z.terms.map{_1.scan(/[⁰¹²³⁴⁵⁶⁷⁸⁹]+/).join.unsup.to_i}.max
end
def a b #addition of two terms
self.gsub!("x","1x") if self.scan(/\d+/).empty?
b.gsub!("x","1x") if b.scan(/\d+/).empty?
if self.degree == b.degree
x = "#{self.scan(/\d+/).join.to_i + b.scan(/\d+/).join.to_i}x#{b.degree.to_s.sup}"
if x.scan(/\d+/).empty?
x.gsub! "x⁰","1"
else
x.gsub! "x⁰",""
end
x.chomp!("¹") if x.end_with? "x¹"
return x
end
return (a + " + " + b).gsub "+ -","-"
end
def terms;self.gsub("-","+ -").split " + "end #to get the terms of an expression in array
def simplify #to simplify the given expression
return self.simplify2 unless self[1..].include? "-"
a = self.terms
p = a.reject{_1[0] == "-"}.join(" + ").gsub("+ -","-")
n = (a.select{_1[0] == "-"}).map{_1[1..]}.join(" + ").gsub("+ -","-")
p.minus n
end
def simplify2 #to simplify the expression containing only positive sign terms
a = self.terms
e = a.map &:degree
ex = self.ex
h = Hash[ex.zip([[]]*a.size)]
a.size.times{h[e[_1]] += [_1]}
s = []
for i in ex.sort.reverse
s << h[i].map{a[_1]}.reduce(:a)
end
s.join(" + ").gsub "+ -","-"
end
def add b #addition of two expressions
(self + " + " + b).gsub("+ -","-").simplify2
end
def describe #describing the type of polynomial
"Yep,so #{self} is degree #{self.degree} polynomial"
end
def coeff #to get the coefficient of a term
return @@reply if self.polynomial?
self.gsub! "x","1x" if self.scan(/\d+/).empty?
self.scan(/-*\d+/).join.to_i
end
def coeffs #to get the coefficients of the terms in array
return @@reply if self.monomial?
self.terms.map{_1.gsub! "x","1x" if _1.scan(/\d+/).empty?;_1.scan(/-*\d+/).join.to_i}
end
def m b #to subtract two terms
if self.degree == b.degree
c,d = self.coeff - b.coeff,b.degree
return "0" if c.zero?
if d.zero?
return "#{c}x#{b.degree.to_s.sup}".gsub "x⁰",""
elsif d == 1
return "#{c}x#{b.degree.to_s.sup}".gsub "x¹","x"
end
return "#{c}x#{b.degree.to_s.sup}"
end
(self + " - " + b).gsub "- -","+"
end
def - b
return @@reply if self.polynomial? or b.polynomial?
self.m b
end
def minus b #subtraction of two expressions
a,b = self.simplify2,b.simplify2
s = []
e1,e2 = a.terms.size,b.terms.size
e3,e4 = a.terms.map(&:degree),b.terms.map(&:degree)
m = [a.degree,b.degree].max
h1 = Hash[[*m.downto(0)].zip([[]]*(m+1))]
h2 = Hash[[*m.downto(0)].zip([[]]*(m+1))]
e1.times{h1[e3[_1]] += [_1]}
e2.times{h2[e4[_1]] += [_1]}
m.downto(0){
if h1[_1].empty? && h2[_1].empty?
#shoot the user
elsif h1[_1].empty?
s << "-#{b.terms[h2[_1][0]]}"
elsif h2[_1].empty?
s << "#{a.terms[h1[_1][0]]}"
else
s << a.terms[h1[_1][0]].m(b.terms[h2[_1][0]])
end
}
s.join(" + ").gsub("+ -","-").gsub(/[+-] 0 /,"").terms.join(" + ").gsub "+ -","- "
end
def ex;self.terms.map(&:degree).uniq;end
def negative?;self[0] == "-"end #checking whether the term is negative or not
def positive?;!self.positive?end #checking whether the term is positive or not
end
class Array
def form #defining this method to convert the array returned by terms to reform the expression
self.join(" + ").gsub "+ -","-"
end
end
1条答案
按热度按时间mznpcxlj1#
给出示例时出错:
puts ("x - 1"*"x + 1").simplify
=〉它在String::minus
方法的第138行显示一个错误,说nil与2的比较失败方法
*
与return s.join " + "
产生x² + x + -x + -1
;给定此,方法simplify
得到a = self.terms
为x²
x
+ -x
+ -1
(由于terms;self.gsub("-","+ -")
添加了额外的+
,然后.split " + "
),因此n = (a.select{_1[0] == "-"})…
在p.minus n
处为空(由于没有以-
开头的项);方法minus
withm = [a.degree,b.degree].max
其中b
是实际参数n
最终失败,因为b.degree
为空字符串生成nil
。那么,应该为它做些什么呢?
为了解决在不前置
+
的情况下拆分为加法项的问题,您可以更改terms
: