function VBA xét loại tam giác

Liên hệ QC

nguyetthu07

Thành viên mới
Tham gia
20/2/21
Bài viết
1
Được thích
0
Mình xin hỏi nên sửa lỗi function này thế nào với ạ?
Đề bài là: Tạo function nêu loại tam giác từ ba cạnh cho trước (trong 3 loại hoặc cân- isosceles, đều-equilateral, khác-scalene)
Nếu mình làm như sau:

Function triangle(a As Double, b As Double, c As Double) as String

If a = b Or b = c Or a = c Then
triangle = "isosceles"

ElseIf a = b = c Then
triangle = "equilateral"

Else
triangle = "scalene"

End If

End Function

Thì khi thử 3 cạnh bằng nhau kết quả sẽ không ra equilateral mà vẫn là isosceles, lỗi này nên sửa thế nào ạ?
Mình cảm ơn trước ạ.
 
Bạn đăng bài sai đề mục
PHP:
Function triangle(aA As Double, bB As Double, cC As Double) As String
If (aA = bB And aA <> cC) Or (bB = cC And aA <> bB) Or (aA = cC And aA <> bB) Then
    triangle = "isosceles"
ElseIf aA = bB And bB = cC Then
    triangle = "equilateral"
Else
    triangle = "scalene"
End If
End Function
 
Mình xin hỏi nên sửa lỗi function này thế nào với ạ?
Đề bài là: Tạo function nêu loại tam giác từ ba cạnh cho trước (trong 3 loại hoặc cân- isosceles, đều-equilateral, khác-scalene)
Nếu mình làm như sau:



Thì khi thử 3 cạnh bằng nhau kết quả sẽ không ra equilateral mà vẫn là isosceles, lỗi này nên sửa thế nào ạ?
Mình cảm ơn trước ạ.
Không có biểu thức luận lý "a = b = c ", cần tách thành "a = b And b = c "
Về logic sai, không cân đương nhiên không đều nên biểu thức ElseIf "đều" không bao giờ thỏa

Mã:
Function triangle(a As Double, b As Double, c As Double) As String
  If a = b And b = c Then
    triangle = "equilateral"
  ElseIf a = b Or b = c Or a = c Then
    triangle = "isosceles"
  Else
    triangle = "scalene"
  End If
End Function
 
Mình xin hỏi nên sửa lỗi function này thế nào với ạ?
Đề bài là: Tạo function nêu loại tam giác từ ba cạnh cho trước (trong 3 loại hoặc cân- isosceles, đều-equilateral, khác-scalene)
Nếu mình làm như sau:



Thì khi thử 3 cạnh bằng nhau kết quả sẽ không ra equilateral mà vẫn là isosceles, lỗi này nên sửa thế nào ạ?
Mình cảm ơn trước ạ.
Đây là do thứ tự kiểm tra của hàm.
Hàm của bạn xét điều kiện cân đầu tiên, tam giác đều đương nhiên là thỏa mãn điều kiện cân => hàm trả về kết quả đầu tiên thỏa mãn.
Có lẽ xét điều kiện đều trước điều kiện cân là được.
---
Biểu thức "ElseIf a = b = c Then" có lẽ cần sửa thành "a=b and b=c then"
 
Trường hợp 3 cạnh không ráp được thành 1 tam giác thì sao. VD: 1,1,3. Như những code bên trên thì ra tam giác cân.
 
Ngoài ra, còn thiếu tam giác vuông cân (nửa hình vuông) và tam giác vuông.
 
Mình bổ sung thêm các điều kiện
PHP:
Function TamGiac(a As Double, b As Double, c As Double) As String
  Dim xMin#, xMax#, xMid#
  xMin = Application.Min(a, b, c)
  xMax = Application.Max(a, b, c)
  xMid = a + b + c - (xMin + xMax)
  If xMin + xMid <= xMax Then
    TamGiac= "khong tao duoc tam giac"
  ElseIf xMin = xMax Then
    TamGiac= "tam giac deu"
  ElseIf xMin = xMid And xMax = Sqr(2) * xMid Then
    TamGiac= "tam giac vuong can"
  ElseIf xMin = xMid Or xMax = xMid Then
    TamGiac= "tam giac can"
  ElseIf xMin * xMin + xMid * xMid = xMax * xMax Then
    TamGiac= "tam giac vuong"
  Else
    TamGiac= "tam giac thuong"
  End If
End Function

Sub Test()
  Debug.Print TamGiac(5, 4, 3)
End Sub
 
Các code trên đều thiếu từ căn bản:
Trong lập trình, hai số thực (Float/Single/Double) không thể so sánh đơn giản với toán tử = , người lập trình chỉ có thể coi như chúng bằng nhau với một sai số rất nhỏ.
 
Mình xin hỏi nên sửa lỗi function này thế nào với ạ?
Đề bài là: Tạo function nêu loại tam giác từ ba cạnh cho trước (trong 3 loại hoặc cân- isosceles, đều-equilateral, khác-scalene)
Nếu mình làm như sau:

Function triangle(a As Double, b As Double, c As Double) as String
If a = b Or b = c Or a = c Then
triangle = "isosceles"
ElseIf a = b = c Then
triangle = "equilateral"
Else
triangle = "scalene"
End If
End Function

Thì khi thử 3 cạnh bằng nhau kết quả sẽ không ra equilateral mà vẫn là isosceles, lỗi này nên sửa thế nào ạ?
Mình cảm ơn trước ạ.

Giải thích chỗ sai:

1. Về lô gic thì bạn sai ở hai chỗ tô đỏ. Lô gic của bạn là "nếu không cân thì thử xem có đều?"
Tam giác đều cũng là tam giác cân cho nên bạn không thể xét bằng lô gic như trên.
Lô gic đúng phải là xét xem có cân hay không, nếu cân thì xét tiếp xem có đều hay không
If (thoả điều kiện cân) Then
. If (thoả diều kiện đều) Then
. . Đều
. Else
. . Cân
. End If
Else
. Không cân
End If

2. Về ngữ pháp (code) thì bạn sai ở chỗ tôi tô đỏ thứ hai. Bạn cần nắm vững điều sau:
- Trong VBA, một biểu thức chỉ có thề chứa tối đa hai vế và một toán tử. Điều này áp dụng cho cả biểu thức so sánh (so sánh a = b)
Nếu biểu thức có nhiều hơn hai vế và/hoặc nhiều hơn một toán tử thì VBA sẽ tự phân chúng thành biểu thức con cho đến khi nào thoả các điều kiện trên.
a = b = c là một biểu thức có 2 toán tử và 3 vế.
VBA sẽ tách nó thành tối thiểu hai biểu thức. Biểu thức con là b = c (phép so sánh), và biểu thức còn lại là a = kết quả của biểu thức con (so sánh lần nữa)
nếu b = c thì kết quả phép so sánh là True, đem True so sánh với a (số) thì VBA sẽ ép kiểu True thành -1; và tuỳ theo a có bằng -1 hay không mà có kết quả cuói cùng.

Túm lại, a = b = c là một cách diễn tả của toán học, khi vào lập trình thì nên nhớ rằng ngôn ngữ lập trình không nhất thiết phải theo như vậy.
 
Đây là bài tập. Người ra bài chủ yếu chỉ thử thách trình độ xét lô gic lồng nhau giữa tam giác đều và cân.
Nếu ở trình độ hiểu biết về hệ nhị phân thì có thể làm như sau:

Function CoiNhuBang(a As Double, b As Double) As Boolean
CoiNhuBang = Abs(a - b) <= 1E-15
End Function

Function TamGiac(a As Double, b As Double, c As Double) as String
' thử điều kiện tam giác
If (a+b) <= c Or (a+c) <= b Or (b+c) <= a Then
TamGiac = "chả phải tam giác"
Exit Function
End If
' đặt a=b là bit 1, a=c là bit 2, b=c là bit 4
Select Case (-CoiNhuBang(a, b))*1 And (-CoiNhuBang(a, c))*2 And (-CoiNhuBang(b, c))*4
Case 0 ' chả cạnh nào bằng cạnh nào
TamGiac = "méo"
Case 7 ' cả 3 điều kiện trên đều thoả
TamGiac = "đều"
Case Else
TamGiac = "cân"
End Select
End Function

Chú:
CoiNhuBang trả về True/False. Đem đổii dấu (đặt dấu trừ ở trước) thì ra 1/0. Đem nhân 1/2/4 thì ra 1/2/4/0.
Ba trị trên đem And với nhau thì kết quả sẽ là từ 0 đến 7.
Tuy nhiên vì lô gic bài này (a = b và a = c thì b = c) cho nên các trường hợp 3 (1 và 2), 5 (1 và 4), 6 (2 và 4) sẽ tự động thành 7
 
CoiNhuBang trả về True/False. Đem đổii dấu (đặt dấu trừ ở trước) thì ra 1/0. Đem nhân 1/2/4 thì ra 1/2/4/0.
Ba trị trên đem And với nhau thì kết quả sẽ là từ 0 đến 7
Em có thử thì 1 AND 2 ra kết quả = 0. Dùng phép OR (hoặc phép cộng) thì ra kết quả đúng.
 
1) Phải đặt điều kiện a, b, c phải lớn hơn 0
2) Xét tam giác cân, (dễ)
3) Xét tam giác đều, (dễ)
4) Xét tam giác vuông: a2 + b2 = c2 (số 2 là bình phương - định lý Pytago)
5) Các tam giác còn lại.
 
Em có thử thì 1 AND 2 ra kết quả = 0. Dùng phép OR (hoặc phép cộng) thì ra kết quả đúng.
Tôi chủ quan nên quên, + so với Or, * với And.
4) Xét tam giác vuông: a2 + b2 = c2 (số 2 là bình phương - định lý Pytago)
Nếu thêm vuông thì thêm bit 8.

Tuy nhiên, thêm chuyện này thì hơi rắc rối. Người ra bài tập này sẽ đòi hỏi cách lô gic tối ưu nhất - làm toán ít nhất.
Điển hình. Nếu đã đều rồi thì không thể vuông, và ngược lại -> cái nào xét trước. Nếu cân thì muốn xét vuông chỉ cần con toán a nhân căn hai, không phải qua py-ta-go.

Rốt lại, nếu phải xét đủ thứ thì sắp xếp lại theo thứ tự Mx, Me, Mn như bài #7
 
Em có thử thì 1 AND 2 ra kết quả = 0. Dùng phép OR (hoặc phép cộng) thì ra kết quả đúng.
Phép AND với các giá trị kiểu số nguyên cho kết qủa AND theo từng Bit tương ứng.
Ví dụ 5 = 101 (hệ 2), 6 = 110 (hệ 2) thì AND Bit hàng đơn vị và hàng chục = 0, Bit hàng trăm = 1. Do đó kết quả = 100 (hệ 2) = 4.
Tương tự các phép OR (chưa tìm hiểu kỹ phép toán XOR)
Trong phép thử của bạn 1 =01 (hệ 2), 2=10 (hệ 2) thì 1 AND 2 = 00=0, 1 OR 2 = 11=3. Nếu các số viết theo hệ đếm 2 có "đối nhau" trừ những số không( ở cuối như 100 (4) và 010 (2) thì OR giống như phép cộng (110 = 6)
 
Phép AND với các giá trị kiểu số nguyên cho kết qủa AND theo từng Bit tương ứng.
Ví dụ 5 = 101 (hệ 2), 6 = 110 (hệ 2) thì AND Bit hàng đơn vị và hàng chục = 0, Bit hàng trăm = 1. Do đó kết quả = 100 (hệ 2) = 4.
Tương tự các phép OR (chưa tìm hiểu kỹ phép toán XOR)
Trong phép thử của bạn 1 =01 (hệ 2), 2=10 (hệ 2) thì 1 AND 2 = 00=0, 1 OR 2 = 11=3. Nếu các số viết theo hệ đếm 2 có "đối nhau" trừ những số không( ở cuối như 100 (4) và 010 (2) thì OR giống như phép cộng (110 = 6)
Người viết bài #11 biết luật này. Người ta chỉ nhắc tôi điểm sai ở bài #10.

Khi viết bài #10, tôi đã chủ quan cho nên quên mất luật căn bản của con toán "bit tiêu biểu" (bit representative):
- khi tính thì dùng OR, khi xét thì dùng AND
 
Web KT
Back
Top Bottom