作为筛选面试的一部分,我得到了以下问题:
编写一个函数,该函数接收三角形边长的三个整数输入,并返回四个值中的一个以确定三角形类型(1 =斜角,2 =等腰,3 =等边,4 =误差)。假设另一个开发人员编写了该函数,为该函数生成测试用例。
我的回答是:
#define ERROR 4
#define EQUILATERAL 3
#define ISOSCELES 2
#define SCALENE 1
int detemineTriangle(int x, int y, int z)
{
if((x<=0) || (y<=0) || (z<=0))
return ERROR;
if((x==y) || (x==z) || (y==z))
{
if((x==y) && (y==z))
return EQUILATERAL;
else
return ISOSCELES;
}
return SCALENE;
}
测试案例:
detemineTriangle (0,0,0); //error
detemineTriangle (2,2,2); //equilateral
detemineTriangle (3,3,1); //isosceles
detemineTriangle (1,3,3); //isosceles
detemineTriangle (3,1,3); //isosceles
detemineTriangle (1,2,3); //scalene
detemineTriangle (-1,2,3); //error scalene
detemineTriangle (1,-2,3); //error scalene
detemineTriangle (1,2,-3); //error scalene
detemineTriangle (-2,-2,-2); //error equilateral
detemineTriangle (-2,5,-2); //error isosceles
detemineTriangle (-2,-2,5); //error isosceles
detemineTriangle (5,-2,-2); //error isosceles
//looking for overflows/underflows
detemineTriangle (INT_MAX,INT_MAX,INT_MAX);
detemineTriangle (INT_MAX,1,1);
detemineTriangle (1,INT_MAX,1);
detemineTriangle (1,1,INT_MAX);
detemineTriangle (-INT_MAX,-INT_MAX,-INT_MAX);
detemineTriangle (-INT_MAX,1,1);
detemineTriangle (1,-INT_MAX,1);
detemineTriangle (1,1,-INT_MAX);
//boundary tests
detemineTriangle(1,1,1)
detemineTriangle(0,0,0)
detemineTriangle(-1,-1,-1)
detemineTriangle (0,10,10);
detemineTriangle (1,10,10);
detemineTriangle (-1,10,10);
detemineTriangle (10,0,10);
detemineTriangle (10,1,10);
detemineTriangle (10,-1,10);
detemineTriangle (10,10,0);
detemineTriangle (10,10,1);
detemineTriangle (10,10,-1);
//checking thread safety
a =detemineTriangle (10,10,10);
b =detemineTriangle (10,10,10);
//a==b function does not appear to depend on global or static variables
你觉得这个答案有什么问题吗? 提前谢谢。
答案 0 :(得分:5)
你也应该检查边长。如您所知,2边的总长度必须大于最后边的长度。 所以你也应该检查一下这样的东西:
if(x+y<=z || x+z<=y || z+y<=x)
return ERROR;
UPD:以下是完整解决方案(包括溢出检查):
inline bool isSidesOverflow(int a, int b)
{
return b > INT_MAX - a;
}
int detemineTriangle(int x, int y, int z)
{
if((x<=0) || (y<=0) || (z<=0)) return ERROR;
// If all sides are equal and greater than 0 - no need to check overflow and validness.
if(x == y && y == z) return EQUILATERAL;
//Check overflow now
if(isSidesOverflow(x,y) || isSidesOverflow(x,z) || isSidesOverflow(y,z)) return ERROR;
//Check if it's valid triangle
if(x+y<=z || x+z<=y || z+y<=x) return ERROR;
if((x==y) || (x==z) || (y==z)) return ISOSCELES;
return SCALENE;
}
(没有编译,可以通过评论报告错误)
答案 1 :(得分:1)
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
// define the data type "triangletype" with {values}
enum triangleType { scalene, isosceles, equilateral, noTriangle };
// Prototype function which returns the position of triangleType{value}
// Example: Scalene = 0, isosceles = 1, etc. These are zero indexed.
triangleType triangleShape(double a, double b, double c);
// Prototype function which takes the integer value of the
// triangle type and outputs the name of triangle
string shapeAnswer(int value);
int main() {
double inputA;
double inputB;
double inputC;
cout << "To determine whether a triangle is either:" << endl;
cout << setw(50) << " - Scalene" << endl; // Unequal in length
cout << setw(52) << " - Isosceles" << endl; // Two sides equal length
cout << setw(54) << " - Equilateral" << endl; // All sides equal
cout << setw(57) << " - Not a triangle" << endl;
cout << "Enter side A: ";
cin >> inputA;
cout << "Enter side B: ";
cin >> inputB;
cout << "Enter side C: ";
cin >> inputC;
cout << "The triangle is " << shapeAnswer(triangleShape(inputA, inputB, inputC)) << endl;
}
triangleType triangleShape(double a, double b, double c) {
triangleType answer;
if ( c >= (a + b) || b >= (a + c) || a >= (b + c) ) {
answer = noTriangle;
}
else if (a == b && b == c) {
answer = equilateral;
}
// Test the 3 options for Isosceles equality
else if ( (a == b) && (a != c) || (b == c) && (b != a) || (a == c) && (a != b) ) {
answer = isosceles;
}
else {
answer = scalene;
}
return answer;
}
string shapeAnswer(int value) {
string answer;
switch (value) {
case 0:
answer = "Scalene";
break;
case 1:
answer = "Isosceles";
break;
case 2:
answer = "Equilateral";
break;
case 3:
answer = "Not a triangle";
break;
default:
break;
}
return answer;
}
答案 2 :(得分:0)
我会将测试分成几个测试用于测试不同错误的测试用例。这样,您现在不仅可以使函数determineTriangle
不正确,而且还可以解决它有什么问题。
我想说使用第三方库进行测试(例如CXXTest或谷歌测试框架)将是一个优势。大多数此类框架提供了可用于验证的不同断言函数。
我能想到的另一个改进是在所有可能的排列中测试每个三元组 - 函数的结果应该是相同的(所以也许写一个辅助函数testTiplet(int sidea, int sideb, itn sidec, int expectedType))
。
编辑:我的回答只是建议你如何改进测试部分。 Sat在他/她的回答中提到了一个重要的实施流程。
答案 3 :(得分:0)
我会将评论转换为答案。
您还应该测试三边的长度是否有效。一般规则是longest_size < shortest_side + median_side
。
对此的测试可能是:
detemineTriangle(1, 1, 100);
除此之外,您可以通过执行其他人建议的操作来使测试更加稳固,例如测试所有参数的排列(@Ivaylo)。
答案 4 :(得分:0)
我最近在解决这个问题。
这就是我解决它的方法。
int detemineTriangle(int x, int y, int z)
{
if (x <= 0 || y <= 0 || z <= 0 )
return ERROR;
else
if (z >= (x + y) || y >= (x + z) || x >= (y + z) )
return ERROR;
else if (x == y && y == c)
return EQUILATERAL;
else if ( ( (x == y) && (x != z) ) || ( (y == z) && (y != x) ) )
return ISOSCELES;
else
return SCALENE;
}
第一个if语句限定输入以确保值大于1。第二个if语句限定输入是否为有效三角形(两边加在一起必须大于第三边)。第三个if语句查找x = y和y = z,这意味着x = z。第四个if语句看起来是双方相等但第三方不是。结论性的else语句只返回scalene,但如果你愿意,可以测试它。