0

モールス符号に変換するプログラム、またはその逆のプログラムを作成しています。コードまたは関連する値をより効率的に検索するためにツリーを使用します。Morse および関連する値は、ファイルから静的配列に読み込まれます。インデックス 0 は他のすべてのサブツリーのルートであり、実際には左側のサブツリー (index[1]) と右側のサブツリー (index[16]) にリンクするダミー ノードです。

ノードを読み込んだ後、静的配列をループして子ノードをリンクし、ノードを割り当てます。インデックス [2] - [16] は、左のサブツリーを保持します。インデックス [17] - (alphaTree.length - 1) は、右側のサブツリーを保持します。

私の問題は次のとおりです。すべての子ノードを割り当てようとすると、それらのいくつかを印刷するとnullになります。ノード自体は null ではなく、子だけです。

パターンに気付きましたが、それを修正する方法がわかりません。

以下はサンプル出力です。出力は大きいので、省略しましたが、意味がわかるように十分に残しました。

Element left 0: -, t
Element right 0: *, e
Element left 1: null
Element right 1: null
Element left 2: --, m
Element right 2: null
Element left 3: null
Element right 3: -*, n
Element left 4: ---, o
Element right 4: null
Element left 5: null

. . .

Element right 25: null
Element left 26: null
Element right 26: *-**, l
Element left 27: **--, ö
Element right 27: null
Element left 28: null
Element right 28: **-*, f
Element left 29: ***-, v
Element right 29: null

以下は、静的配列を埋めるために使用するファイルです。ツリーには特殊文字があるため、ASCII を使用し、ファイルを読み取るときに変換します。

- 116
-- 109
-* 110
--- 111
--* 103
-*- 107
-** 100
---- 247 
---* 246
--*- 113
--** 122
-*-- 121
-*-* 99
-**- 120
-*** 98
* 101
*- 97
** 105
*-- 119
*-* 114
**- 117
*** 115
*--- 106
*--* 112
*-*- 228
*-** 108
**-- 246
**-* 102
***- 118
**** 104

以下は、ツリーを作成してノードをリンクするために使用するコードです。linkLeftTree() と linkRightTree() は、親ノードとその子ノードをリンクするメソッドです。ノードは open() メソッドで配列に読み込まれます。

package MorseTrees;

import MorseTrees.Nodes.*;
import java.util.*;
import java.io.*;

public class TreePopulater {
    private static final int ALPHABET = 31;
    private static final String alphaRaw = "alphatree2.txt";    
    private static final A_Node[] alphaTree = new AlphaNode[ALPHABET];
    private A_Node aNode;

    public TreePopulater() {
        alphaTree[0] = new AlphaNode("000");
        alphaTree[0].setAlpha('0'); 
        populateRaw(alphaRaw);
    }

    private A_Node[] populateRaw(String treeType)
    {   
        // open and fill static array
        open(treeType);
    }

    private void open(String fileName) {

        //try, catch, etc.
        Scanner in = new Scanner(new File(fileName));
     int counter = 1;

   while (in.hasNextLine()) {
      aNode = new AlphaNode(in.next());
      aNode.setAlpha((char) in.nextInt());
           alphaTree[counter] = aNode;

      counter++;
   }

        linkNodes();
    }

    private void linkNodes() {  
        // force link root node 
        alphaTree[0].setLeft(alphaTree[1]);
        alphaTree[0].setRight(alphaTree[16]);

        linkLeftTree();
        linkRightTree();
        printChildren();
    }

    public void linkLeftTree()
    {
        // link the left, or first half, of the array
        for (int i = 2; i < (alphaTree.length / 2); i++) // or 16
        {   
            alphaTree[i].setLeft(alphaTree[(i++)]);
            alphaTree[i].setRight(alphaTree[(i)]);
        }
    }

    public void linkRightTree()
    {
        // link the right, or second half, of the array
        for (int i = 17; i <= alphaTree.length - 1; i++)
        {
            alphaTree[i].setLeft(alphaTree[(i++)]);
            alphaTree[i].setRight(alphaTree[(i)]);  
        }   
    }

    public void printChildren()
    {
        for (int i = 0; i < alphaTree.length - 1; i++)
        {
            System.out.println("Element left " + i + ": " + alphaTree[i].leftChild());
            System.out.println("Element right " + i + ": " + alphaTree[i].rightChild());
        }   
    }

    public static void main(String[] args)
    {
        TreePopulater tp = new TreePopulater();
    }
}

ノード クラス AlphaNode は、A_Node を拡張します。A_Node は、あなたが期待しているように見えます: 左右の子のインスタンス変数、モールス信号とそれに関連付けられた文字、および必要なすべてのゲッターとセッター。

奇妙なことに、linkLeftTree() と linkRightTree() のセッターで System.out.println() を使用すると、ループ中に null が表示されませんが、実際に子ノードにアクセスしようとすると (予約検索など)。

(謝辞: このプログラムに実装されているアルファベット ツリーは、書籍「コード」にある Charles Petzold の最適化されたツリーに基づいています。ただし、ここにあるすべてのコードは、実際にあなたが作成したものです。)

4

2 に答える 2

0

私は次のコードについて疑わしいです:

   public void linkLeftTree()
    {
        // link the left, or first half, of the array 
        // NOTE: the code runs for i=2,4,8,10,12,14 so many nodes have the left
        //      and right neighbors unassigned
        for (int i = 2; i < (alphaTree.length / 2); i++) // or 16
        {   // NOTE:
            // This should alphaTree[i].setLeft(alphaTree[i+1])
            // Since you are changing the value of i twice 
            // A good idea is to print i and verify the values
            alphaTree[i].setLeft(alphaTree[(i++)]);
            alphaTree[i].setRight(alphaTree[(i)]);
        }
    }

    public void linkRightTree()
    {
        // link the right, or second half, of the array
        //NOTE: the code runs for i=17,19.. so many nodes have the left
        //      and right neighbors unassigned
        for (int i = 17; i <= alphaTree.length - 1; i++)
        {
            // Same as above
            alphaTree[i].setLeft(alphaTree[(i++)]);
            alphaTree[i].setRight(alphaTree[(i)]);  
        }   
    }

どのインデックスがアルゴリズムに固有であるかは正確にはわかりませんが、表示されるnullに関連する質問に答えたと思います。

しかし、割り当てで最高です!あなたが自分でそれを解決しているのは素晴らしいことです..:-)

V

于 2012-06-11T02:31:58.870 に答える
0

(OPに代わって投稿) .

親ノードも出力するように printChildren() メソッドを変更し、親自身を自分の子として割り当てていることに気付きました (例: n は n の子になりました)。他のケースでは、ノードを完全にスキップしていました。これは、for ループで i 変数を使用したために発生しました。

以下のコードは問題を解決し、私が望むことを正確に行います。これは恐ろしく、洗練されていないハックですが、戻ってリファクタリングするときに、よりクリーンにする方法を見つけます。解決策は linkLeftTree() および linkRightTree() メソッドにありました。葉に子ノードを割り当てることは想定されていないことに気付いたので、両方のケースでループするノードの数を減らし、カウンターを使用して子を割り当てました。

public void linkLeftTree() {    
    int counter = 2;
    int counter2 = 3;

        // link the left, or first half, of the array

    for (int i = 1; i < 8; i++) {   
    alphaTree[i].setLeft(alphaTree[(counter++)]);
    alphaTree[i].setRight(alphaTree[(counter2++)]);

              if (counter <= 13) {
         counter++;
             counter2++;
    }
    }
}

public void linkRightTree() {
    int counter = 16;
    int counter2 = 17;

    // link the right, or second half, of the array
    for (int i = 16; i < (24); i++) {   
        alphaTree[i].setLeft(alphaTree[(counter++)]);
        alphaTree[i].setRight(alphaTree[(counter2++)]);

        if (counter < 29) { 
            counter++;
            counter2++;
        }
    }
}

再帰的な検索と出力も期待どおりに機能しており、プログラムの作成はほぼ完了しています。これで、クリーンアップのプロセスが始まります。これを見て時間を割いてくれたみんなに感謝します!

于 2016-09-18T19:14:29.077 に答える