void TGraphCascade::TopologicalSort(TIntV& SortedNIdV) { int Nodes = Graph.GetNodes(); SortedNIdV.Gen(Nodes, 0); // result THash<TInt, TBool> Marks(Nodes); // nodeid -> mark map THash<TInt,TBool> TempMarks(Nodes); // nodeid -> temp mark map THash<TInt, TBool> Added(Nodes); TIntV NIdV; Graph.GetNIdV(NIdV); // all node ids // set marks for (int NodeN = 0; NodeN < Nodes; NodeN++) { int NodeId = NIdV[NodeN]; Marks.AddDat(NodeId, false); TempMarks.AddDat(NodeId, false); Added.AddDat(NodeId, false); } TSStack<TInt> Stack; for (int NodeN = 0; NodeN < Nodes; NodeN++) { int NodeId = NIdV[NodeN]; // select an unmarked node if (!Marks.GetDat(NodeId)) { Stack.Push(NodeId); while (!Stack.Empty()) { // visit TopNode int TopNodeId = Stack.Top(); Marks.GetDat(TopNodeId) = true; TempMarks.GetDat(TopNodeId) = true; // add children, set their temp marks to true TNGraph::TNodeI NI = Graph.GetNI(TopNodeId); int Children = NI.GetOutDeg(); bool IsFinal = true; for (int ChildN = 0; ChildN < Children; ChildN++) { int ChildId = NI.GetOutNId(ChildN); EAssertR(!TempMarks.GetDat(ChildId), "TGraphCascade::TopologicalSort: the graph is not a DAG!"); if (!Marks.GetDat(ChildId)) { // unvisited node IsFinal = false; Stack.Push(ChildId); } } if (IsFinal) { // push TopNode to tail if (!Added.GetDat(TopNodeId)) { SortedNIdV.Add(TopNodeId); Added.GetDat(TopNodeId) = true; } TempMarks.GetDat(TopNodeId) = false; Stack.Pop(); } } } } SortedNIdV.Reverse(); }
TStr TNodeJsFPath::GetCanonicalPath(const TStr& FPath) { // Get absolute path TStr AbsFPath = TStr::GetNrAbsFPath(FPath); // Remove any redundancies TStrV CanonV; AbsFPath.SplitOnAllCh('/', CanonV); TSStack<TStr> CanonS; TStr CurrStr; for (int ElN = 0; ElN < CanonV.Len(); ++ElN) { CurrStr = CanonV.GetVal(ElN); if (CurrStr == "..") { EAssertR(!CanonS.Empty(), "Stack empty"); CanonS.Pop(); } else if (CurrStr != ".") { CanonS.Push(CurrStr+"/"); } } // Assemble the canonical path (from left to right EAssertR(!CanonS.Empty(), "Stack empty"); // We start with drive letter (Windows) or slash (Unix) TChA CanonFPath = AbsFPath.LeftOf('/'); CanonFPath += '/'; // Get the rest of the path for (int CanonN = CanonS.Len() - 1; CanonN >= 0; CanonN--) { CanonFPath += CanonS[CanonN]; } // Done return CanonFPath; }
PDzsHKwBs TDzsHKwBs::LoadTxt(const TStr& FNm){ TSStack<PXmlTok> TokS; PXmlTok RootTok; PSIn SIn=TFIn::New(FNm); TILx Lx(SIn, TFSet()|iloTabSep); Lx.GetSym(syTab, syStr, syEoln, syEof); int PrevLev=-1; while (Lx.Sym!=syEof){ printf("."); int Lev=0; while (Lx.Sym==syTab){Lev++; Lx.GetSym(syTab, syStr);} IAssert(Lx.Sym==syStr); for (int ChN=0; ChN<Lx.Str.Len(); ChN++){ uchar Ch=Lx.Str[ChN]; if (Ch>127){printf("%c", Ch); Fail;}} // create topic PXmlTok TopicTok=TXmlTok::New(xsyTag, "topic"); //TopicTok->AddArg("title", Lx.Str); // topic title TStr TitleStr=TXmlLx::GetChRefFromYuEntRef(Lx.Str); PXmlTok TitleTok=TXmlTok::New(xsyTag, "title"); TopicTok->AddSubTok(TitleTok); PXmlTok TitleStrTok=TXmlTok::New(xsyStr, TitleStr); TitleTok->AddSubTok(TitleStrTok); // topic query TStr QueryStr=GetQueryStr(TitleStr); PXmlTok QueryTok=TXmlTok::New(xsyTag, "query"); TopicTok->AddSubTok(QueryTok); PXmlTok QueryStrTok=TXmlTok::New(xsyStr, QueryStr); QueryTok->AddSubTok(QueryStrTok); // insert topic into tree if (Lev==0){ IAssert(RootTok.Empty()); RootTok=TopicTok; TokS.Push(RootTok); } else if (PrevLev+1==Lev){ TokS.Top()->AddSubTok(TopicTok); TokS.Push(TopicTok); } else if (PrevLev==Lev){ TokS.Pop(); TokS.Top()->AddSubTok(TopicTok); TokS.Push(TopicTok); } else if (PrevLev>Lev){ int UpLev=PrevLev; while (UpLev>Lev){UpLev--; TokS.Pop();} TokS.Pop(); TokS.Top()->AddSubTok(TopicTok); TokS.Push(TopicTok); } else { Fail; } while (Lx.GetSym()!=syEoln){} Lx.GetSym(syTab, syStr, syEoln, syEof); PrevLev=Lev; //if (Lx.SymLnN>100){break;} } PXmlDoc XmlDoc=TXmlDoc::New(RootTok); PDzsHKwBs HKwBs=TDzsHKwBs::New(XmlDoc); return HKwBs; }