• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javaandroidc++linuxc#objective-ccocoa誰得qtrubypythonwindowsphpgamebathyscapheguic翻訳omegattwitterframeworkbtronvb.net計画中(planning stage)testdomarduinodirectxpreviewerゲームエンジン

programming language


Commit MetaInfo

Révisionf82455fb9478f929e27626b07c89ef6ae193ea82 (tree)
l'heure2020-11-22 21:53:44
Auteurdhrname <dhrname@user...>
Commiterdhrname

Message de Log

Add the insertBefore method

Change Summary

Modification

--- a/main.cpp
+++ b/main.cpp
@@ -23,6 +23,8 @@
2323
2424 #include <iostream>
2525 #include <string>
26+#include <typeinfo>
27+#include <stdexcept>
2628
2729 /*Nodeの抽象クラス
2830 * 5方向リンクのリスト
@@ -31,13 +33,24 @@ class Node
3133 {
3234 public:
3335 virtual Node* getParent() = 0;
36+ virtual void setParent(Node*) = 0;
37+
3438 virtual Node* getNext() = 0;
39+ virtual void setNext(Node*) = 0;
40+
3541 virtual Node* getPrev() = 0;
42+ virtual void setPrev(Node*) = 0;
43+
3644 virtual Node* getFirstChild() = 0;
45+ virtual void setFirstChild(Node*) = 0;
46+
3747 virtual Node* getLastChild() = 0;
48+ virtual void setLastChild(Node*) = 0;
49+
3850 virtual Node* removeChild(Node* const) = 0;
3951 virtual Node* insertBefore(Node* const, Node* const) = 0;
4052 virtual Node* appendChild(Node* const) = 0;
53+
4154 virtual bool isNode() = 0;
4255 };
4356
@@ -45,11 +58,16 @@ public:
4558 class EmptyNode: public Node
4659 {
4760 public:
48- Node* getParent(){return this;};
49- Node* getNext(){return this;};
50- Node* getPrev(){return this;};
51- Node* getFirstChild(){return this;};
52- Node* getLastChild(){return this;};
61+ Node* getParent() {return this;};
62+ Node* getNext() {return this;};
63+ Node* getPrev() {return this;};
64+ Node* getFirstChild() {return this;};
65+ Node* getLastChild() {return this;};
66+ void setParent(Node* node){};
67+ void setNext(Node* node){};
68+ void setPrev(Node* node){};
69+ void setFirstChild(Node* node){};
70+ void setLastChild(Node* node){};
5371 Node* removeChild(Node*){return this;};
5472 Node* insertBefore(Node*, Node*){return this;};
5573 Node* appendChild(Node*){return this;};
@@ -59,13 +77,13 @@ public:
5977 }
6078 };
6179
62-Node* const emptynode = new EmptyNode();
80+EmptyNode* const emptynode = new EmptyNode();
6381
6482 /*BaseNodeの基底クラス
6583 * Node抽象クラスに対する内部実装*/
6684 class BaseNode: public EmptyNode
6785 {
68-private:
86+protected:
6987 Node* parentNode;
7088 Node* nextSibling;
7189 Node* previousSibling;
@@ -83,46 +101,87 @@ public:
83101
84102 virtual ~BaseNode(){}
85103
86- virtual void throwArgumentError(Node* const node, const std::string& str);
87- virtual void setParent(Node* node);
88- virtual void setNext(Node* node);
89- virtual void setPrev(Node* node);
90- virtual void setFirstChild(Node* node);
91- virtual void setLastChild(Node* node);
104+ virtual void throwNULLArgumentError(Node* const, const std::string&);
105+ virtual void throwArgumentError(Node* const, const std::string&);
106+
107+ virtual void setParent(Node*);
108+ virtual void setNext(Node*);
109+ virtual void setPrev(Node*);
110+ virtual void setFirstChild(Node*);
111+ virtual void setLastChild(Node*);
112+
92113 virtual Node* getParent();
93114 virtual Node* getNext();
94115 virtual Node* getPrev();
95116 virtual Node* getFirstChild();
96117 virtual Node* getLastChild();
118+
97119 virtual Node* removeChild(Node*);
98120 virtual Node* insertBefore(Node*, Node*);
99121 virtual Node* appendChild(Node*);
100- virtual bool isNode()
122+
123+ virtual bool isNode() const
101124 {
102125 return true;
103126 }
104127 };
105128
106-inline void BaseNode::throwArgumentError(Node* const node, const std::string& str)
129+/*throwNULLArgumentError 関数
130+ * 引数のNULLチェックをして、nullptrだったら例外を投げる
131+ * @param node 木構造の節
132+ * @param name 引数の例外が発生したメンバ関数名*/
133+inline void BaseNode::throwNULLArgumentError(Node* const node, const std::string& name)
134+{
135+ if (nullptr == node)
136+ {
137+ /*バグの放置を防ぐため、例外を投げる前に、エラーを出力して報告*/
138+ std::cerr << "NULL Argument Error on the member " << name << std::endl;
139+ throw std::invalid_argument("error!");
140+ }
141+}
142+
143+/*throwArgumentError 関数
144+ * 引数のチェックをして、nullptrか、emptynode(空ノード)だったら例外を投げる
145+ * @param node 木構造の節
146+ * @param str 引数の例外が発生したメンバ関数名*/
147+inline void BaseNode::throwArgumentError(Node* const node, const std::string& name)
107148 {
108- /*例外を投げる前に、エラーを出力して報告*/
109- std::cout << "Argument Error on the member " << str << std::endl;
110- throw;
149+ this->throwNULLArgumentError(node, name);
150+ if ( !node->isNode() )
151+ {
152+ /*バグの放置を防ぐため、例外を投げる前に、エラーを出力して報告*/
153+ std::cerr << "Argument Error on the member " << name << std::endl;
154+ throw std::invalid_argument("error!");
155+ }
111156 }
112157
113-void BaseNode::setParent(Node* node){
158+void BaseNode::setParent(Node* node)
159+{
160+ this->throwNULLArgumentError(node, "setParent");
114161 this->parentNode = node;
115162 }
116-void BaseNode::setNext(Node* node){
163+
164+void BaseNode::setNext(Node* node)
165+{
166+ this->throwNULLArgumentError(node, "setNext");
117167 this->nextSibling = node;
118168 }
119-void BaseNode::setPrev(Node* node){
169+
170+void BaseNode::setPrev(Node* node)
171+{
172+ this->throwNULLArgumentError(node, "setPrev");
120173 this->previousSibling = node;
121174 }
122-void BaseNode::setFirstChild(Node* node){
175+
176+void BaseNode::setFirstChild(Node* node)
177+{
178+ this->throwNULLArgumentError(node, "setFirstChild");
123179 this->firstChild = node;
124180 }
125-void BaseNode::setLastChild(Node* node){
181+
182+void BaseNode::setLastChild(Node* node)
183+{
184+ this->throwNULLArgumentError(node, "setLastChild");
126185 this->lastChild = node;
127186 }
128187
@@ -130,6 +189,7 @@ Node* BaseNode::getParent()
130189 {
131190 return this->parentNode;
132191 }
192+
133193 Node* BaseNode::getNext()
134194 {
135195 return this->nextSibling;
@@ -146,14 +206,109 @@ Node* BaseNode::getLastChild()
146206 {
147207 return this->lastChild;
148208 }
149-Node* BaseNode::removeChild(Node* const node)
209+
210+/*removeChild メンバ関数
211+ *自分からchildノードを引き離して、子ノードとして扱わないようにさせる
212+ *@param child 引き離される子ノード
213+ *@return 引き離された子ノード
214+ **/
215+Node* BaseNode::removeChild(Node* const child)
150216 {
151- this->throwArgumentError(node, "removeChild");
152- return this->parentNode;
217+ this->throwArgumentError(child, "removeChild");
218+
219+ child->setParent(emptynode);
220+
221+ if (this->lastChild == child)
222+ {
223+ /*末子ノードがchildである場合は自分のlastChildメンバを書きかえておく*/
224+ this->setLastChild(child->getPrev());
225+ }
226+ if (this->firstChild == child)
227+ {
228+ /*長子ノードがchildである場合は自分のfirstChildメンバを書きかえておく*/
229+ this->setFirstChild(child->getNext());
230+ }
231+
232+ /*nodeが抜けた後、隣接ノードに関するメンバは書き換えておく*/
233+ if (child->getPrev()->isNode())
234+ {
235+ child->getPrev()->setNext(child->getNext());
236+ }
237+ if (child->getNext()->isNode())
238+ {
239+ child->getNext()->setPrev(child->getPrev());
240+ }
241+
242+ child->setNext(emptynode);
243+ child->setPrev(emptynode);
244+
245+ return child;
153246 }
154247 Node* BaseNode::insertBefore(Node* const node, Node* const prev)
155248 {
156- return this->parentNode;
249+ this.throwArgumentError(node, "insertBefore");
250+
251+ /*prevはemptynodeの可能性が含まれる*/
252+ this.throwNULLArgumentError(prev, "insertBefore");
253+
254+ /*祖先ノードの中に、今挿入しつつあるnodeと一致するものがあれば、参照エラー
255+ * というのは、循環参照を引き起こすため*/
256+ Node* p = this;
257+
258+ while (p.isNode())
259+ {
260+ if (p == node)
261+ {
262+ throw std::invalid_argument("Reference error on the insertBefore");
263+ }
264+
265+ p = p->getParent(p);
266+ }
267+
268+ Node* pnode = node->getParent();
269+
270+ if (pnode->isNode())
271+ {
272+ /*nodeがすでに、他の枝に挿入されていた(子ノードであった)場合、引き離しておく*/
273+ pnode->removeChild(node);
274+ }
275+
276+ node->setParent(this);
277+
278+ if (!prev->isNode())
279+ {
280+ /*prevノードがemptynodeの場合、末子ノードとしてnodeが追加される
281+ *末子ノードが存在するときは、そのノードのメンバも書きかえておく*/
282+ Node* lastChild = this->getLastChild();
283+ if (lastChild->isNode())
284+ {
285+ lastChild->setNext(node);
286+ node->setPrev(lastChild);
287+ }
288+ /*末子ノードとして挿入*/
289+ this->setLastChild(node);
290+ }
291+ else
292+ {
293+ Node* prevOfPrev = prev->getPrev();
294+ if (prevOfPrev->isNode())
295+ {
296+ /*prevの隣接ノードのnextSiblingメンバを書きかえておく*/
297+ prevOfPrev->setNext(node);
298+ }
299+ node->setPrev(prevOfPrev);
300+ prev->setPrev(node);
301+ node->setNext(prev);
302+ }
303+
304+ if (this->getFirstChild() == prev)
305+ {
306+ /*長子ノードがprevの場合、firstChildメンバをnodeに書きかえておく
307+ *これはprevがemptynodeの場合でも同様*/
308+ this->setFirstChild(node);
309+ }
310+
311+ return node;
157312 }
158313 Node* BaseNode::appendChild(Node* const node)
159314 {
@@ -162,7 +317,14 @@ Node* BaseNode::appendChild(Node* const node)
162317
163318 int main(int argc, char **argv)
164319 {
165- std::string str1 = "ABCD";
320+ std::string str1 = "ABC";
166321 std::cout << "A" << str1 << std::endl;
322+ try
323+ {
324+ }
325+ catch(std::invalid_argument e)
326+ {
327+ }
328+ delete emptynode;
167329 return 0;
168330 }