0

ねえ、今私のプログラムの最後の仕上げをしていて、私は最も奇妙なバグに遭遇しました.共通の文字列によって。

これは kruskals サイクル チェッカー用なので、それよりも少し複雑ですが、それがこのエラーの基本です。いくつかの手動の system.out デバッグを追加し、最も奇妙なことを教えてくれました。たとえば、これはそのベースです。 label1 と label1 を比較しますが、1 1 1 2 2 1 2 2 に対して繰り返されます

private static ArrayList<Graph> caseForConnection(
        Connection consideredConnection, ArrayList<Graph> subTrees)
        throws Exception {
    ArrayList<Graph> ret = new ArrayList<Graph>();
    System.out.println("Considering connection " +consideredConnection.getSaveDetails()[1] +consideredConnection.getSaveDetails()[2] + "  "+consideredConnection.getSaveDetails()[3]);
    String label1 = consideredConnection.getNode(1).getLabel();
    String label2 = consideredConnection.getNode(2).getLabel();
    for (Graph x : subTrees) {
        for (Connection c : x.getConnectionList()) {
            System.out.println("Comparing to connection "+  c.getSaveDetails()[1] +c.getSaveDetails()[2] +"  " +c.getSaveDetails()[3]);
            if (c.getNode(1)
                    .getLabel()
                    .equalsIgnoreCase(label1)) {
                if (ret.contains(x)) {
                    System.out.print(("Found " + c.getNode(1)
                            .getLabel() +" is the same as " + label1+ " And this is twice"));
                    throw new Exception("Cycle Found");
                }
                System.out.print(("Found " + c.getNode(1)
                        .getLabel() +" is the same as " + label1));
                ret.add(x);
            } else if (c
                    .getNode(1)
                    .getLabel()
                    .equalsIgnoreCase(label2)) {
                if (ret.contains(x)) {
                    System.out.print(("Found " + c.getNode(1)
                            .getLabel() +" is the same as " + label1+ " And this is twice"));
                    throw new Exception("Cycle Found");
                }
                System.out.print(("Found " + c.getNode(1)
                        .getLabel() +" is the same as " + label2));
                ret.add(x);
            }
            if (c.getNode(2)
                    .getLabel()
                    .equalsIgnoreCase(label1)) {
                if (ret.contains(x)) {
                    System.out.print(("Found " + c.getNode(1)
                            .getLabel() +" is the same as " + label1+ " And this is twice"));
                    throw new Exception("Cycle Found");
                }
                System.out.print(("Found " + c.getNode(2)
                        .getLabel() +" is the same as " + label1));
                ret.add(x);
            } else if (c
                    .getNode(2)
                    .getLabel()
                    .equalsIgnoreCase(label2)) {
                if (ret.contains(x)) {
                    System.out.print(("Found " + c.getNode(1)
                            .getLabel() +" is the same as " + label1+ " And this is twice"));
                    throw new Exception("Cycle Found");
                }
                System.out.print(("Found " + c.getNode(2)
                        .getLabel() +" is the same as " + label2));
                ret.add(x);
            }
        }
    }
    return ret;
}

奇妙なことは、私のコンソールがこれを出力したことです

Found C は B と同じです Found D は A と同じです

接続 AC BC BD AD CG BF GF CF を通過すると、label1 は a になり、最初のラベルは 2 c になります。これはこれら 2 つのみで発生し、もちろん無効な結果をもたらします。

4

1 に答える 1

0

あなたのコードは非常に反復的であるため、そのようなクレイジーなバグにさらされています. 次の追加を行ってみませんか。

ノード内:

String normLabel() { return getLabel().toUpperCase(); }

接続:

public boolean matches(Connection other) {
  final String this1 = getNode(1).normLabel(), this2 = getNode(2).normLabel(),
               other1 = other.getNode(1).normLabel(), 
               other2 = other.getNode(2).normLabel();
    return this1.equals(other1) || this2.equals(other1) ||
           this1.equals(other2) || this2.equals(other2);
  }

次に、メイン コードを次のように折りたたむことができます。

private static List<Graph> caseForConnection(
    Connection consideredConnection, ArrayList<Graph> subTrees)
{
  final List<Graph> ret = new ArrayList<Graph>();
  for (Graph g : subTrees) {
    for (Connection c : g.getConnectionList()) {
      if (c.matches(consideredConnection)) {
        if (ret.contains(g)) throw new RuntimeException("Cycle Found");
        ret.add(g);
      }
    }
  }
  return ret;
}

バグが蒸発する可能性は十分にありますが、蒸発しなくても追跡はずっと簡単です。

于 2012-04-22T21:04:06.793 に答える