4

私のメソッドは単体テストに合格できません。無駄に5時間見つめました。誰かが私に何が問題なのかを理解するのを手伝ってもらえますか?

PS: 以下の私のコードの getAllRelations() メソッドは、フォーマットされた入力を文字列の ArrayList の配列リストに分離することです。たとえば、このようなフォーマットされた入力がある場合(合格できなかったテストケースで使用しました)

String format = "John Doe , Mary Smith" + "\n" + "Brian William , John Doe" + "\n" + "Brian William ,Robert Andrew" + "\n" + "Mary Smith , Max Jackson";

各行で、最初の人は 2 番目の人の親です。getAllRelations() メソッドは、このフォーマットされた文字列を配列リストに分割します。各リストには、各行の要素として 2 つの名前文字列 (名前の前後にスペースなし) のみが含まれます。たとえば、arraylist1 は「John」と「Mary Smith」を含むリストになります。

何が問題なのかわからなかった私の方法は次のとおりです。この方法を使用して、2人が同じ祖先を共有しているかどうかを確認したいと思います。

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"));
    }
}
4

5 に答える 5

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;
    }

幸運をお祈りしています。

于 2012-11-19T09:33:03.797 に答える
1

「マックス・ジャクソン」と「ロバート・アンドリュー」は祖先が異なります。「ジョン・ドウ」と「ロバート・アンドリュー」は同じ祖先を共有しています。以下に示すように条件を置き換えて確認します

assertEquals(false, format.hasSameAncestor("Max Jackson", "Robert Andrew"));
assertEquals(true, format.hasSameAncestor("John Doe", "Robert Andrew"));
于 2012-11-19T09:23:20.083 に答える
1

まず第一に、あなたが使用しているデータ構造は、この種のアプリケーションにとってはひどいものです。すべてを文字列にパックしてから、文字列を分割して doubled-for ループで処理する代わりに、家系図の実際のデータ構造を構築する必要があります。

情報学では、ツリーはこのタスクに使用したい種類の構造です。ツリーには、次の 2 種類のオブジェクトがあります。

1) A Node, which has two children, that are also Nodes.
2) A Leaf, which has no children.

このノードを使用して家系図をモデル化し、既知の多数のツリー アルゴリズムの 1 つを適用できます。(これに対する同様の質問は、2 つの二分探索木の交差です)

より具体的に言うと、モデル内の各人物には、両親として定義された他の 2 人がいます。リーフとは、(既知の) 親を持たない人物です。次に、2 つのバイナリ ツリーの交点を計算するアルゴリズムを実行できます。交差点が空の場合、共通の祖先はありません。

于 2012-11-19T08:42:55.440 に答える
1

内部ループは常に 1 から始まります。

ループ内で 0 の代わりに i = -1、j = -1 にすると解決します。

于 2012-11-19T09:21:15.627 に答える
1

あなたの関係は右から左ですよね?

したがって、マックスはメアリーに、メアリーはジョンに関連しています。ロバートはブライアンとのみ関係があります。彼は右側にいません。しかし、他の方向も確認したいので (?)、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;
        }       
    }
}

これは true を返します

Test test1 = new Test("a1 , b1" + "\n" + "b1 , c1" + "\n" + "a2 , b2" + "\n" + "b2 , c1" + "\n" + "a3 , c3");
System.out.println(test1.hasSameAncestor("a1", "a2"));

および false の場合

System.out.println(test1.hasSameAncestor("a1", "a3"));

よろしく

于 2012-11-19T12:55:42.413 に答える