1

私はそれを短くします。コードを実行するとき、最初の文字 (例: 'k') を入力すると、すべて問題ありません。2 回目に文字 (例: 'j') を入力すると、エラーが発生し、コンパイラはそれが行 (コメントがある) にあると言います。助けてください。ありがとうございました。

コード:

struct nodeType{
    char letter;
    nodeType*leftNode;
    nodeType*rightNode;

};
void putInNode(nodeType*n,char c){
    if ((char)(n->letter) >='a' && (char)(n->letter) <='z')/* ERROR IS HERE*/
    {
        if(n->letter < c)
            putInNode(n->leftNode, c);
        else
            putInNode(n->rightNode, c);
    }
    n->letter=c;
}
int main(){
    nodeType*a=new nodeType();
    char c;
    do {
        cin >> c;
        if(c=='.')
            break;
        putInNode(a,c);
    } while (true);
    cout << a->letter << endl;

}
4

3 に答える 3

3

これの目的が入力ストリームからの文字のみのツリーを構築し、ピリオドに達したときに停止し、 にないものをスキップすることである場合、{'a'...'z'}これがあなたが求めているものだと思います:

#include <iostream>

struct nodeType
{
    nodeType(char ch = 0)
       : letter(ch), leftNode(), rightNode()
    {}

    char letter;
    nodeType* leftNode;
    nodeType* rightNode;
};

void putInNode(nodeType*& n,char c)
{
    if (!n)
    {
        n = new nodeType(c);
    }
    else if (n->letter >='a' && n->letter <='z')
    {
        if(c < n->letter)
            putInNode(n->leftNode, c);
        else
            putInNode(n->rightNode, c);
    }
}

int main()
{
    nodeType* a = NULL;
    char c;
    while ((std::cin >> c) && c != '.')
        putInNode(a,c);

    if (a)
        std::cout << a->letter << '\n';
}

注: これにより、重複が右側の子行に押し出されます。これが意図されていない場合は、次のように変更します。

        if(c < n->letter))
            putInNode(n->leftNode, c);

代わりにこれに:

        if(c <= n->letter)) // <== note less-or-equal
            putInNode(n->leftNode, c);

結果の動的ツリーのクリーンアップはあなたに任せます。そして、書かれているとおり(以前と現在の両方)、最初のノードは常にツリーのルートになることに注意してください(いつか、シフトを介してバランスを取ることを計画していると思います。この道をさらに下っていきます)。

于 2013-02-27T19:09:51.243 に答える
2

問題は、ルートノードから離れたノードを実際に割り当てていないことです。したがって、2 番目の文字を入力すると、最初の文字は既に親ノードに文字を設定しており、ツリーの左側のノードを逆参照しようとすると失敗します (b/c は未割り当てのメモリです)。

于 2013-02-27T19:01:09.340 に答える
1

問題は、単一のノードにスペースを割り当てているだけで、変数を初期化していないことです。

初めてdoループを通過するa->letter = 0と、関数に入るときにputInNode文字が割り当てられると思いkます。次回のループでは、 と の間にあるとが true にn->letterなるので、kazk < jputInNode(n->leftNode, c);

n->leftNodeただし、初期化されていないため、それを参照しようとするn->letterと、segfault が発生します。

これを修正するには (この関数で新しいノードを作成したくない場合)、構造体のコンストラクターを作成してから null をチェックします。

struct nodeType{
  nodeType() 
  {
    letter    = 0;
    leftNode  = nullptr;
    rightNode = nullptr;
  }
  char letter;
  nodeType*leftNode;
  nodeType*rightNode;
};

次にputInNode

void putInNode(nodeType*n,char c){
   if(n == nullptr) {
      return;
   }
   if ((char)(n->letter) >='a' && (char)(n->letter) <='z') {
   .
   .
   .
于 2013-02-27T19:10:06.440 に答える