類圖到源碼分析工具—-合并元素處理,圖的同構,迴環處理

來源:互聯網
上載者:User

練手最多的也就是廣搜,今天連個狀態機器也寫不出來,弱,非常的弱,眼高手低的毛病一直沒改,幸好我周圍好人很多,很多。

 

分析一下處理這個圖的同構和迴環處理方法。

首先是第一種情況,兩個類圖,要合并的元素是一樣的類或者介面。可以這樣理解為一個為正本,一個為副本。方法如下:

1,把副本的目標元素,刪除,正本頂替副本的位置。

2,只要副本直接關聯元素和間接關聯元素顯示為TRUE,則直接把正本的直接和間接關聯元素替換為副本的元素。不管正本那邊的關聯元素為true

或者為false;

3,如果副本關聯元素為false,則服從於正本關聯元素。

本著這個想法,先對副本做一次廣搜,然後把顯示為true的元素入隊列,接著和正本元素映射,但凡映射上的元素執行兩個步驟,替換自己的位置,替換和目標元素直接關聯元素記憶體儲的目標元素。例如目標元素A的關聯元素是B,C,D,那麼B,C,D裡面有A,如果A替換為a,那麼B,C,D裡面也要替換A為a。

 

於是乎就有了以下代碼:

/**<br /> * 合并各元素<br /> * @param ve<br /> * @return<br /> * 此處的思想是把副本全部元素刪除,並且把副本visible為true的元素資訊賦給原本<br /> */<br />override public function mergeWith(ve:ICIViewElement) : int<br />{<br />if (ve == null)<br />return EG.Result_S_FALSE;</p><p>var mergeObject: Array = _getMergeObject(ve);<br />if (mergeObject == null)<br />return EG.Result_S_OK;</p><p>var beenVisited: Array = new Array();<br />var length: int = mergeObject["length"];<br />var visited: int = 0;<br />var begin: int = 0;<br />var thisQueue: Vector.<ICIViewElement> = new Vector.<ICIViewElement>();</p><p>thisQueue.push(this);<br />beenVisited[this.fullName] = false;</p><p>while (visited != length && begin != thisQueue.length)<br />{<br />var currThis: ICIViewElement = thisQueue[begin];<br />beenVisited[currThis.fullName] = true;</p><p>//從映射數組中取出資訊和當前同構圖中的節點資訊匹配,並且把副本節點刪除<br />var currVe: ICIViewElement = mergeObject[currThis.fullName];<br />if (currVe)<br />{<br />currVe.deleteThis();<br />visited++;<br />currThis.myVisible = true;<br />currThis.myX = currVe.myX;<br />currThis.myY = currVe.myY;<br />currThis.refresh();<br />CT.refreshAllRelationLines(currThis);<br />_view.elementPool.posChanged(currThis);<br />}</p><p>//關聯元素處理各自容器中的目標元素值<br />//噹噹前節點是class元素時候,根據條件排入佇列中<br />if (currThis.eType == EG.Element_CLASS)<br />{<br />var thisParClass: ICIClass = ICIClass(currThis).parent<br />if (thisParClass && mergeObject[thisParClass.fullName])<br />{<br />if (!beenVisited[thisParClass.fullName])<br />thisQueue.push(thisParClass);<br />}</p><p>var thisChildsClass: Vector.<ICIClass> = ICIClass(currThis).childs;<br />for each (var chlClass: ICIClass in thisChildsClass)<br />{<br />if (beenVisited[chlClass.fullName])<br />continue;</p><p>if (mergeObject[chlClass.fullName])<br />thisQueue.push(chlClass);<br />}</p><p>var thisInterfaceClass: Vector.<ICIInterface> = ICIClass(currThis).interfaces;<br />for each (var interClass: ICIInterface in thisInterfaceClass)<br />{<br />if (beenVisited[interClass.fullName])<br />continue;<br />if (mergeObject[interClass.fullName])<br />thisQueue.push(interClass);<br />}</p><p>var thisUsersClass: Vector.<ICIClass> = ICIClass(currThis).users;<br />for each (var userClass: ICIClass in thisUsersClass)<br />{<br />if (beenVisited[userClass.fullName])<br />continue;<br />if (mergeObject[userClass.fullName])<br />thisQueue.push(userClass);<br />}</p><p>var thisData: IClass = currThis.data as IClass;<br />for each (var mem: IClassMember in thisData.members)<br />{<br />if (beenVisited[mem.type.fullName])<br />continue;<br />if (mergeObject[mem.type.fullName])<br />{<br />var ve: ICIViewElement = ICIView(_view).createElementByData(mem.type) as ICIViewElement;<br />thisQueue.push(ve);<br />}<br />}<br />}<br />else if (currThis.eType == EG.Element_INTERFACE)<br />{//當元素為介面元素時候的處理<br />var thisPar: Vector.<ICIInterface> = ICIInterface(currThis).parents;<br />for each (var par: ICIInterface in thisPar)<br />{<br />if (beenVisited[par.fullName])<br />continue;<br />if (mergeObject[par.fullName])<br />thisQueue.push(par);<br />}</p><p>var thisChilds: Vector.<ICIInterface> = ICIInterface(currThis).childs;<br />for each (var chl: ICIInterface in thisChilds)<br />{<br />if (beenVisited[chl.fullName])<br />continue;</p><p>if (mergeObject[chl.fullName])<br />thisQueue.push(chl);<br />}</p><p>var thisUsers: Vector.<ICIClass> = currThis.users;<br />for each (var user: ICIClass in thisUsers)<br />{<br />if (beenVisited[user.fullName])<br />continue;<br />if (mergeObject[user.fullName])<br />thisQueue.push(user);<br />}</p><p>var thisImpls: Vector.<ICIClass> = ICIInterface(currThis).implementors;<br />for each (var impl: ICIClass in thisImpls)<br />{<br />if (beenVisited[impl.fullName])<br />continue;<br />if (mergeObject[impl.fullName])<br />thisQueue.push(impl);<br />}<br />}</p><p>begin++;<br />}</p><p>//this.refresh();<br />return EG.Result_S_OK;<br />}<br />/**<br /> * 廣搜擷取副本已經顯示的元素<br /> * @param ve<br /> * @return<br /> */<br />private function _getMergeObject(ve: ICIViewElement): Array<br />{<br />var mergeObject: Array = new Array();<br />var mergeVisited: Array = new Array();<br />var mergeVec: Vector.<ICIViewElement> = new Vector.<ICIViewElement>();<br />var begin: int = 0;</p><p>mergeVec.push(ve);<br />mergeObject[ve.fullName] = ve;<br />mergeVisited[ve.id] = false;</p><p>while (begin != mergeVec.length)<br />{<br />var currVe: ICIViewElement = mergeVec[begin];<br />mergeVisited[currVe.id] = true;</p><p>//此處分為class元素和interface元素處理情況<br />if (currVe.eType == EG.Element_CLASS)<br />{<br />var veParClass: ICIClass = ICIClass(currVe).createdParent;<br />if (veParClass && veParClass.myVisible && !mergeVisited[veParClass.id])<br />{<br />mergeVec.push(veParClass);<br />mergeObject[veParClass.fullName] = veParClass;<br />}</p><p>var veChildsClass: Vector.<ICIClass> = ICIClass(currVe).createdChilds;<br />for each (var chlClass: ICIClass in veChildsClass)<br />{<br />if (chlClass.myVisible && !mergeVisited[chlClass.id])<br />{<br />mergeVec.push(chlClass);<br />mergeObject[chlClass.fullName] = chlClass;<br />}<br />}</p><p>var veInterfaceClass: Vector.<ICIInterface> = ICIClass(currVe).createdInterfaces;<br />for each (var interClass: ICIInterface in veInterfaceClass)<br />{<br />if (interClass == this)<br />{<br />_replaceElment(ve, currVe);<br />return null;<br />}</p><p>if (!mergeVisited[interClass.id] && interClass.myVisible)<br />{<br />mergeVec.push(interClass);<br />mergeObject[interClass.fullName] = interClass;<br />}<br />}</p><p>var veUsersClass: Vector.<ICIClass> = ICIClass(currVe).createdUsers;<br />for each (var userClass: ICIClass in veUsersClass)<br />{<br />if (!mergeVisited[userClass.id] && userClass.myVisible)<br />{<br />mergeVec.push(userClass);<br />mergeObject[userClass.fullName] = userClass;<br />}<br />}</p><p>var veTypeClass: Vector.<ICIViewElement> = ICIClass(currVe).createdMemberTypes;<br />for each (var typeClass: ICIViewElement in veTypeClass)<br />{<br />if (typeClass == this)<br />{<br />_replaceElment(ve, currVe);<br />return null;<br />}</p><p>if (!mergeVisited[typeClass.id] && typeClass.myVisible)<br />{</p><p>mergeVec.push(typeClass);<br />mergeObject[typeClass.fullName] = typeClass;<br />}<br />}<br />}<br />else if (currVe.eType == EG.Element_INTERFACE)<br />{<br />var vePar: Vector.<ICIInterface> = ICIInterface(currVe).createdParents;<br />for each (var par: ICIInterface in vePar)<br />{<br />if (par == this)<br />{<br />_replaceElment(ve, currVe);<br />return null;<br />}</p><p>if (par.myVisible && !mergeVisited[par.id])<br />{<br />mergeVec.push(par);<br />mergeObject[par.fullName] = par;<br />}<br />}</p><p>var veChilds: Vector.<ICIInterface> = ICIInterface(currVe).createdChilds;<br />for each (var chl: ICIInterface in veChilds)<br />{<br />if (chl == this)<br />{<br />_replaceElment(ve, currVe);<br />return null;<br />}</p><p>if (chl.myVisible && !mergeVisited[chl.id])<br />{</p><p>mergeVec.push(chl);<br />mergeObject[chl.fullName] = chl;<br />}<br />}</p><p>var veUsers: Vector.<ICIClass> = currVe.createdUsers<br />for each (var user: ICIClass in veUsers)<br />{<br />if (!mergeVisited[user.id] && user.myVisible)<br />{<br />mergeVec.push(user);<br />mergeObject[user.fullName] = user;<br />}<br />}</p><p>var veImpls: Vector.<ICIClass> = ICIInterface(currVe).createdImplementors;<br />for each (var impl: ICIClass in veImpls)<br />{<br />if (!mergeVisited[impl.id] && impl.myVisible)<br />{<br />mergeVec.push(impl);<br />mergeObject[impl.fullName] = impl;<br />}<br />}<br />}</p><p>begin++;<br />}<br />mergeObject["length"] = mergeVec.length;<br />return mergeObject;<br />}<br /> 

CSDN居然沒能控制長寬。

 

處理另一種情況:處理圓環情況。

和前輩討論了一下,明白了情況,問題解決方案就浮出水面。

有一條迴路,A,B,C,D,A。現在要合并兩個A,另外有兩個A各內建了E,F和E,F。元素都相同的。合并的時候要區分迴路上的元素和非迴路上的元素,一開始,討論出,要從副本每個元素都跑一遍,也就是每個元素都深搜一遍看看是不是在一條迴路上,後來想了想,從正本那邊出發就不用了去考慮那麼多了,因為從副本到正本只有一條路,只要獲得了正本就說明和正本直接關聯的那個元素N就在迴路上,那麼就不處理N,直接處理把副本刪除,和正本的非N得直接關聯元素刪除,把正本元素和副本的直接關聯元素黏合。黏合方法和上述一樣。

 

加多這個處理函數

/**<br /> * deal with ring situation while in mergeBfs<br /> * @return<br /> */<br />private function _replaceElment(ve: ICIViewElement, closeElem: ICIViewElement): int<br />{<br />ve.deleteThis();<br />var index: int = 0;</p><p>var pars: Vector.<ICIInterface> = ICIInterface(ve).parents;<br />var thisPars: Vector.<ICIInterface> = ICIInterface(this).parents;<br />for each (var par: ICIInterface in pars)<br />{<br />for each (var thisPar: ICIInterface in thisPars)<br />{<br />if (thisPar.fullName == par.fullName && thisPar.fullName != closeElem.fullName)<br />{<br />if (par.myVisible)<br />{<br />thisPar.deleteThis();<br />par.addChild(this);<br />this.addParent(par);<br />}<br />break;<br />}<br />index++;<br />}</p><p>index = 0;</p><p>par.refreshRelationLines();<br />}</p><p>var childs: Vector.<ICIInterface> = ICIInterface(ve).childs;<br />var thisChilds: Vector.<ICIInterface> = ICIInterface(this).childs;<br />for each (var chl: ICIInterface in childs)<br />{<br />for each (var thisChl: ICIInterface in thisChilds)<br />{<br />if (thisChl.fullName == chl.fullName && thisChl.fullName != closeElem.fullName)<br />{<br />if (chl.myVisible)<br />{<br />thisChl.deleteThis();<br />chl.addParent(this);<br />this.addChild(chl);<br />}<br />break;<br />}<br />index++;<br />}</p><p>index = 0;</p><p>chl.refreshRelationLines();<br />}</p><p>var impls: Vector.<ICIClass> = ICIInterface(ve).implementors;<br />var thisImpls: Vector.<ICIClass> = ICIInterface(this).implementors;<br />for each (var impl: ICIClass in impls)<br />{</p><p>for each (var thisImpl: ICIClass in thisImpls)<br />{<br />if (thisImpl.fullName == impl.fullName && thisImpl.fullName != closeElem.fullName)<br />{<br />if (impl.myVisible)<br />{<br />thisImpl.deleteThis();<br />impl.addInterface(this);<br />this.addImplementor(impl);<br />}<br />break;<br />}<br />index++;<br />}</p><p>index = 0;<br />impl.refreshRelationLines();<br />}</p><p>var users: Vector.<ICIClass> = ICIInterface(ve).users;<br />var thisUsers: Vector.<ICIClass> = ICIInterface(this).users;<br />for each (var user: ICIClass in users)<br />{<br />for each (var thisUser: ICIClass in thisUsers)<br />{<br />if (thisUser.fullName == user.fullName && thisUser.fullName != closeElem.fullName)<br />{<br />if (user.myVisible)<br />{<br />thisUser.deleteThis();<br />user.addMemberType(this);<br />this.addUser(user);<br />}<br />break;<br />}<br />}</p><p>index = 0;</p><p>user.refreshRelationLines();<br />}<br />this.refreshRelationLines();</p><p>return EG.Result_S_OK;<br />} 

 

有個關鍵問題,一開始是以元素名字映射防止返回已經遍曆過的元素,但是在迴路上,是有出現雙胞胎的情況,遍曆過的這個元素名很可能在迴路上也存在。所以改為用id單獨映射。

 

圖這塊當初沒好好學。現在我的心態確實很浮躁。好好地幹自己的分內事。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.