我的方法无法通过单元测试。我盯着它看了5个小时是徒劳的。有人可以帮我看看它有什么问题吗?
PS:我的代码中的getAllRelations()方法是将格式化的输入分离为字符串ArrayList的arraylists,例如,如果我有这样的格式化输入(我在我的测试用例中使用它不能通过)
String format = "John Doe , Mary Smith" + "\n" + "Brian William , John Doe" + "\n" + "Brian William ,Robert Andrew" + "\n" + "Mary Smith , Max Jackson";
在每一行中,第一个人是第二个人的父母。 getAllRelations()方法将这个格式化的字符串拆分为arraylists,每个列表只包含每行中的两个名称字符串(在名称之前或之后没有空格)作为其元素。例如arraylist1将是一个包含“John”和“Mary Smith”的列表。
这是我的方法,我无法弄清楚什么是错的,我想用这种方法来检查两个人是否共享同一个祖先。
private boolean hasSameAncestor(String person1, String person2){
ArrayList<ArrayList<String>> allRelations = allRelations();
int i = 0;
int j = 0;
String name1 = person1;
String name2 = person2;
String parent1;
String parent2;
for(i = 0, parent1 = ""; i < allRelations.size(); i++){
if(name1.equals(allRelations.get(i).get(1))){
parent1 = allRelations.get(i).get(0);
for(j = 0, name2 = person2, parent2 = ""; j < allRelations.size(); j++){
if(name2.equals(allRelations.get(j).get(1))){
parent2 = allRelations.get(j).get(0);
if(parent2.equals(parent1)){
return true;
}
else{
name2 = parent2;
j = 0;
}
}
}
name1 = parent1;
i = 0;
}
}
return false;
}
我无法通过的测试用例就是这样。
@Test
public void testHasSameAncestor()
FamilyTree familyTree4 = new FamilyTree("John Doe , Mary Smith" + "\n" + "Brian William , John Doe" + "\n" + "Brian William ,Robert Andrew" + "\n" + "Mary Smith , Max Jackson");
assertEquals(true, format.hasSameAncestor("Max Jackson", "Robert Andrew"));
}
我无法弄清楚我的功能有什么问题,有人可以帮帮我吗?非常感谢你。
可以粘贴到eclipse以获得调试帮助的代码
package test;
import java.util.ArrayList;
import java.util.Arrays;
public class Test1 {
String test;
public Test1(String test){
this.test = test;
}
private ArrayList<String> lineRelations(){
int i;
ArrayList<String> lineRelations = new ArrayList<String>();
String[] lines = test.split("\n");
for(i = 0; i < lines.length; i++){
lineRelations.add(lines[i]);
}
return lineRelations;
}
private ArrayList<ArrayList<String>> allRelations(){
int i;
ArrayList<ArrayList<String>> allRelations = new ArrayList<ArrayList<String>>();
ArrayList<String> lineRelations = lineRelations();
for(i = 0; i < lineRelations.size(); i++){
ArrayList<String> eachLine = new ArrayList<String>(Arrays.asList(lineRelations.get(i).split("\\s*,\\s*")));
allRelations.add(eachLine);
}
return allRelations;
}
public boolean hasSameAncestor(String person1, String person2){
ArrayList<ArrayList<String>> allRelations = allRelations();
int i = 0;
int j = 0;
String name1 = person1;
String name2 = person2;
String parent1;
String parent2;
for(i = 0, parent1 = ""; i < allRelations.size(); i++){
if(name1.equals(allRelations.get(i).get(1))){
parent1 = allRelations.get(i).get(0);
for(j = 0, name2 = person2, parent2 = ""; j < allRelations.size(); j++){
if(name2.equals(allRelations.get(j).get(1))){
parent2 = allRelations.get(j).get(0);
if(parent2.equals(parent1)){
return true;
}
else{
name2 = parent2;
j = 0;
}
}
}
name1 = parent1;
i = 0;
}
}
return false;
}
}
测试用例
package test;
import static org.junit.Assert.*;
import test.Test1;
import org.junit.Test;
public class Test1Test {
@Test
public void testHasSameAncestor(){
Test1 test1 = new Test1("John Doe , Mary Smith" + "\n" + "Brian William , John Doe" + "\n" + "Brian William ,Robert Andrew" + "\n" + "Mary Smith , Max Jackson");
assertEquals(true, test1.hasSameAncestor("Max Jackson", "Robert Andrew"));
}
}
答案 0 :(得分:2)
首先找到两个人的基本祖先,然后比较它们。
请检查:)
public boolean hasSameAncestor(String person1, String person2) {
ArrayList<ArrayList<String>> allRelations = allRelations();
int i = 0;
String name1 = person1;
String name2 = person2;
String parent1;
String parent2;
//Find first person's ancestor
for (i = 0, parent1 = ""; i < allRelations.size(); i++) {
if (name1.equals(allRelations.get(i).get(1))) {
parent1 = allRelations.get(i).get(0);
name1 = parent1;
i = -1; // because i will increase before start new loop
}
}
//Find second person's ancestor
for (i = 0, parent2 = ""; i < allRelations.size(); i++) {
if (name2.equals(allRelations.get(i).get(1))) {
parent2 = allRelations.get(i).get(0);
name2 = parent2;
i = -1;
}
}
System.out.println(parent1);
System.out.println(parent2);
if (parent1.equals(parent2)) {
return true;
}
return false;
}
祝福。
答案 1 :(得分:1)
首先,您使用的数据结构对于此类应用程序来说非常糟糕。您应该为您的族树构建一个实际的数据结构,而不是将所有内容打包成一个字符串,然后将字符串拆分并以双循环方式处理它。
在信息学中,树是您想要用于此任务的结构。树有两种不同的对象:
1) A Node, which has two children, that are also Nodes.
2) A Leaf, which has no children.
您可以使用此节点对族谱进行建模,然后应用已知的众多树算法之一。 (类似的问题是Intersection of 2 binary search trees)
更具体一点:模型中的每个人都会将另外两个人定义为他们的父母。叶子是没有(已知)父母的人。然后,您可以运行一个算法,该算法计算两个二叉树的交集。如果交叉点为空,则它们没有共同的祖先。
答案 2 :(得分:1)
你的内部循环始终以1开始。
使i = -1,j = -1而不是循环中的0将解决。
答案 3 :(得分:1)
assertEquals(false, format.hasSameAncestor("Max Jackson", "Robert Andrew"));
assertEquals(true, format.hasSameAncestor("John Doe", "Robert Andrew"));
答案 4 :(得分:1)
你的关系是从右到左,对吗?
所以Max与玛丽和玛丽与约翰有关。罗伯特只与布莱恩有关。他不在右手边。但你也想检查另一个方向(?),所以Brian也和John有关,他们都有相同的祖先。但这很不寻常。
使用散列图检查此解决方案,并使用从左(键)到右(值)的关系进行递归搜索:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class Test {
private String test;
private HashMap<String, String> allRelations;
private ArrayList<String> ancestors;
public Test(String test){
this.test = test;
allRelations = allRelations();
ancestors= new ArrayList<String>();
}
private ArrayList<String> lineRelations(){
int i;
ArrayList<String> lineRelations = new ArrayList<String>();
String[] lines = test.split("\n");
for(i = 0; i < lines.length; i++){
lineRelations.add(lines[i]);
}
return lineRelations;
}
private HashMap<String, String> allRelations(){
int i;
HashMap<String, String> allRelations = new HashMap<String, String>();
ArrayList<String> lineRelations = lineRelations();
for(i = 0; i < lineRelations.size(); i++){
allRelations.put(Arrays.asList(lineRelations.get(i).split("\\s*,\\s*")).get(0), Arrays.asList(lineRelations.get(i).split("\\s*,\\s*")).get(1));
}
return allRelations;
}
public boolean hasSameAncestor(String person1, String person2){
if (allRelations.containsKey(person1)){
if (ancestors.contains(allRelations.get(person1))){
if (allRelations.containsKey(person2)){
if (ancestors.contains(allRelations.get(person2))){
return true;
} else if (allRelations.containsKey(allRelations.get(person2))){
return hasSameAncestor(person1, allRelations.get(person2));
} else {
return false;
}
} else {
return false;
}
} else {
ancestors.add(allRelations.get(person1));
if (allRelations.containsKey(allRelations.get(person1))){
return hasSameAncestor(allRelations.get(person1), person2);
} else if (allRelations.containsKey(person2)) {
return hasSameAncestor(person1,allRelations.get(person2));
} else {
return false;
}
}
} else {
return false;
}
}
}
对于
,返回trueTest test1 = new Test("a1 , b1" + "\n" + "b1 , c1" + "\n" + "a2 , b2" + "\n" + "b2 , c1" + "\n" + "a3 , c3");
System.out.println(test1.hasSameAncestor("a1", "a2"));
,
为假System.out.println(test1.hasSameAncestor("a1", "a3"));
问候