2014-05-08 89 views
0

爲什麼我會爲以下代碼弄虛作假?初學者紅寶石流量控制

def test(s) 
    tester = s.split(//) 
    for char in tester 
     if char != 1 or char != 0 
      return false 
     end 
    end 
    return true 
end 

puts test("11111000") 
# => false 

預先感謝您的回答!

回答

2

你在做什麼這裏充滿了簡單的錯誤,假設大概帶來了來自其他語言。

for聲明很少使用。相反,你只是迭代:

tester.each do |char| 
    # ... 
end 

其次,字符串和數字是不等價的,永遠不會自動轉換。你必須明確:

if (char == '1' or char == '0') 
    # ... 
end 

此外,你有一個邏輯錯誤,你在哪裏測試錯誤的方式。這兩個條件永遠不會同時發生,因爲沒有可以通過兩個測試的角色。任何通過的東西都會自動失敗。

你想要什麼,而不是:

unless (char == '1' or char == '0') 
    # ... 
end 

在最後,不過,如果你只是測試,看看這個字符串包含專門10然後只使用一個簡單的正則表達式:

def test(s) 
    !!s.match(/\A[01]*\z/) 
end 

!!雙負號是將潛在的正則表達式匹配轉換爲簡單的truefalse值。這就是你需要的。 \A\z分別用於定義字符串的「開始」和「結束」。如果你不熟悉正則表達式,你應該花一些時間瞭解它們,因爲它們非常強大,並且可以非常簡單地執行這些任務。

+1

'\ Z'有點棘手。 '\ z'是'\ A'的簡單對應。 – sawa

+0

好點。編輯。 – tadman

5

這是因爲char != 1 or char != 0總是true。不管char是什麼,它不能同時是10


以下僅基於對OP代碼目的的猜測。如果目的是檢查是否s包括什麼,但"1""0",那麼,我會做:

s !~ /[^01]/ 
+2

另外'0'和''0''不是一回事,所以這段代碼首先不起作用。 – tadman

1

char是一個字符串,所以它永遠不會等於或者10 - 僅"1""0"

該代碼將工作:

def test(s) 
    tester = s.split(//) 
    for char in tester 
     if char != '1' and char != '0' 
      return false 
     end 
    end 
    return true 
end 

puts test("11111000") 
# => true 
puts test("111110002") 
# => false 

一個更簡潔的方式做同樣的將是

def test(s) 
    s =~ /^[10]*$/ 
end 
+1

@sawa - 當然它是相關的 - 即使他將_or_更改爲_and_ –

+1

@sawa,OP代碼將始終返回false。實際的解決方案是這個和您的答案的總和。 :) – BroiSatse

+0

@sawa - 我可以說你的解決方案相同。我看到你已經寫完了,我選擇不重複你所說的話。我添加了工作代碼示例,其中包含我們觀察結果的解決方案(您似乎忽略了這一點)。 –

-1

我真的不知道這是什麼代碼是應該做的,但你已經使用一些結構,即(即使它們是可用的)將不被視爲紅寶石路:

  • 你已經使用or代替|| - or通常用於流量控制的符號,並具有非常低的優先級
  • 你已經使用for ... in ...代替迭代
  • 你明確地嘗試返回true/false,同時可以通過使用正確的迭代器以更簡潔的方式完成。

解決方案更易於閱讀和理解可能會看起來更像是:

def test(s) 
    s.split(//).any? { |char| char != 1 || char != 0 } 
end 

請注意,有更多的問題與您的代碼(比較數字的字符串和使用條件,始終是真實的)指出由他人。

+1

這將始終返回true – BroiSatse

+0

就像原始代碼一樣,這可能比使用非ruby方式編寫更多的問題。 – samuil

2

如果你嘗試檢查一個字符串僅由1和0組成,你可以做:

def test(s) 
s.scan(/[^0-1]/).length == 0 
end 

puts test("11111000") # => true 
puts test("1234") # => false 
puts test("234") # => false 
+0

'puts test('1110001222334466')#=> true'! – BroiSatse

+0

對。我不確定這裏的目標是什麼。我只是說,如果目標是要查看字符串CONTAINS 1或0 - 我發佈的內容是否會做。 – Kalman

+0

@BroiSatse - 我編輯我的答案只檢查1秒和0。 – Kalman