2017-10-13 5 views
1

Treeクラスとその子孫のすべてで値を正しく検索し、その値が見つかるとtrueを返す再帰関数を作成しようとします。JavaScriptの再帰的ツリー検索関数がネストされた子を検出しない

特に重要なのは、再帰的なcontains()関数です。リンターを渡すコードを取得しようとしています。私はネストされた子を検出しないということに関しては1つのエラーしか出ません。他のすべてが通り過ぎています。

マイコード:ここで

/* eslint-disable no-trailing-spaces */ 
/* eslint-disable no-unused-vars */ 
class Tree { 
    constructor(value) { 
    this.value = value; 
    this.children = []; 
    } 
    // Adds a new Tree node with the input value to the current Tree node 
    addChild(value) { 
    this.children.push(new Tree(value)); 
    } 
    // Checks this node's children to see if any of them matches the given value 
    // Continues recursively until the value has been found or all of the children 
    // have been checked 
    contains(value) { 
    const thisNode = this; 
    function checkNode(node) { 
     if (node.value === value) { 
     return true; 
     } 
     if (node.children.length > 0) { 
     for (let i = 0; i < node.children.length; i++) { 
      return checkNode(node.children[i]); 
     } 
     } 
     return false; 
    } 
    return checkNode(thisNode); 
    } 
} 

module.exports = Tree; 

はそれをテストするファイルです。

/* eslint-disable no-undef */ 
const Tree = require('../src/tree'); 

describe('Tree',() => { 
    let tree; 

    beforeEach(() => { 
    tree = new Tree(true); 
    }); 

    it('should have methods named "addChild" and "contains"',() => { 
    expect(typeof tree.addChild).toBe('function'); 
    expect(typeof tree.contains).toBe('function'); 
    }); 

    it('should add children to the tree',() => { 
    tree.addChild(5); 
    expect(tree.children[0].value).toBe(5); 
    }); 

    it('should return true for a value that the tree contains',() => { 
    tree.addChild(5); 
    expect(tree.contains(5)).toBe(true); 
    }); 

    it('should return false for a value that was not added',() => { 
    tree.addChild(5); 
    expect(tree.contains(6)).toBe(false); 
    }); 

    it('should be able to add children to a tree\'s child',() => { 
    tree.addChild(5); 
    tree.children[0].addChild(6); 
    expect(tree.children[0].children[0].value).toBe(6); 
    }); 

    it('should correctly detect nested children',() => { 
    tree.addChild(5); 
    tree.addChild(6); 
    tree.children[0].addChild(7); 
    tree.children[1].addChild(8); 
    expect(tree.contains(7)).toBe(true); 
    expect(tree.contains(8)).toBe(true); 
    }); 
}); 

そしてここでは、リンティングエラーです:

Tree 
    ✓ should have methods named "addChild" and "contains" (5ms) 
    ✓ should add children to the tree (1ms) 
    ✓ should return true for a value that the tree contains (3ms) 
    ✓ should return false for a value that was not added (1ms) 
    ✓ should be able to add children to a tree's child (1ms) 
    ✕ should correctly detect nested children (9ms) 
+0

。つまり、ループの最初の反復のみが実行されます。あなたは実際に何をしたいですか?あなたは本当に最初の子をチェックした結果を返そうとしていますか?あなたがコードを書く前に何をしたいのかを記述してください。 –

+1

あなたのコードに何が問題なのか答えがあります。これを短縮/改善する方法は次のとおりです: 'const checkNode = node => node.value === value || – Thomas

+0

@FelixKling「Treeクラスとそのすべての子孫を値で正しく検索する再帰関数を作成しようとしました」という記述を編集しました。その値が見つかるとtrueを返し、そうでない場合はfalseを返します。それはあなたのための十分な説明ですか?スタックオーバーフローは初心者の方がやや穏やかであれば、より利益を上げることができます。終わり。 –

答えて

2

あなたは無条件FOR-の内側に戻りますループするので、最初の子のみをチェックします。

for (let i = 0; i < node.children.length; i++) { 
     return checkNode(node.children[i]); 
    } 

は、私が思う

for (let i = 0; i < node.children.length; i++) { 
     if (checkNode(node.children[i])) return true; 
    } 
+1

あなたは私より37秒早いです:| | –

+2

西で最速の銃:P – Blorgbeard

+0

@Blorgbeardそれは働いた。ソースはいつもあなたと一緒にいてもらいたい、私の友人。 –

2

でなければならず、これはあなたのコードがどのように見えるかです:

for (let childIndex = 0; childIndex < node.children.length; childIndex++) { 
    const foundInChildren = checkNode(node.children[childIndex]); 
    if (foundInChildren) 
    return true; 
} 
3

あなたの問題は、ここではこのコードの塊である:

if (node.children.length > 0) { 
    for (let i = 0; i < node.children.length; i++) { 
     return checkNode(node.children[i]); 
    } 
    } 

このコード行は、最初の子に対してcheckNodeの結果が何であっても、関数はtrueまたはfalseです。結果がfalseの場合は、引き続きチェックする必要があります。

代わりにこれを試してください:あなたが直接 `` for`ループ本体からreturn`ingさ

if (node.children.length > 0) { 
    for (let i = 0; i < node.children.length; i++) { 
     if (checkNode(node.children[i])) { 
     return true; 
     } 
    } 
    } 
関連する問題