本文主要是介绍AOV拓扑排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这是一个AOV拓扑排序的例子,为了应付公司测试而作,写起来也不容易,给记录一下。
在Visual C++2005下做的,这个版本的IDE环境用起来还不错。
aov.h
// data structure
// linked graph
#include < iostream >
#include < vector >
#include < string >
#include < map >
class EdgeNode
... {
public:
int adjvex;
//double weight; useless in this program.
EdgeNode *nextarc;
public:
EdgeNode(const int idx)
...{
adjvex = idx;
nextarc = 0;
}
} ;
// table head
class VNode
... {
public:
std::string data;
EdgeNode *firstarc;
public:
VNode(const char* data, EdgeNode * firstarc)
...{
if(data != 0)
this->data = data;
else
printf("check test file. VNode Constructor. ");
this->firstarc = firstarc;
}
} ;
class Graph
... {
public:
int vnum;
std::vector<VNode> Vertices;
private:
std::map<std::string, int> node_map;//pretend to be hash_map
public:
Graph()
...{
vnum = 0;
}
int addNode(VNode& node);
int getNode(const char* name); //return the index in Vertices.
void clear();
} ;
// linked graph
#include < iostream >
#include < vector >
#include < string >
#include < map >
class EdgeNode
... {
public:
int adjvex;
//double weight; useless in this program.
EdgeNode *nextarc;
public:
EdgeNode(const int idx)
...{
adjvex = idx;
nextarc = 0;
}
} ;
// table head
class VNode
... {
public:
std::string data;
EdgeNode *firstarc;
public:
VNode(const char* data, EdgeNode * firstarc)
...{
if(data != 0)
this->data = data;
else
printf("check test file. VNode Constructor. ");
this->firstarc = firstarc;
}
} ;
class Graph
... {
public:
int vnum;
std::vector<VNode> Vertices;
private:
std::map<std::string, int> node_map;//pretend to be hash_map
public:
Graph()
...{
vnum = 0;
}
int addNode(VNode& node);
int getNode(const char* name); //return the index in Vertices.
void clear();
} ;
aov.cpp
// Normal return 0, otherwise -1
// Graph DAG, which records clothes information.
//
#include " aov.h "
using namespace std;
int Graph::addNode(VNode & node)
... {
node_map.insert(map<std::string, int>::value_type(node.data, vnum++));
Vertices.push_back(node);
return 0;
}
int Graph::getNode( const char * name)
... {
map<string, int>::iterator it;
it = node_map.find(name);
if(it != node_map.end())
return it->second;
return -1;
}
void Graph::clear()
... {
vector<EdgeNode*> needtodel;
for(vector<VNode>::iterator it = Vertices.begin(); it != Vertices.end(); ++it)
...{
EdgeNode* next = it->firstarc;
while(next)
...{
needtodel.push_back(next);
next = next->nextarc;
}
}
for(vector<EdgeNode*>::iterator it = needtodel.begin(); it != needtodel.end(); ++it)
...{
delete *it;
}
}
// Graph DAG, which records clothes information.
//
#include " aov.h "
using namespace std;
int Graph::addNode(VNode & node)
... {
node_map.insert(map<std::string, int>::value_type(node.data, vnum++));
Vertices.push_back(node);
return 0;
}
int Graph::getNode( const char * name)
... {
map<string, int>::iterator it;
it = node_map.find(name);
if(it != node_map.end())
return it->second;
return -1;
}
void Graph::clear()
... {
vector<EdgeNode*> needtodel;
for(vector<VNode>::iterator it = Vertices.begin(); it != Vertices.end(); ++it)
...{
EdgeNode* next = it->firstarc;
while(next)
...{
needtodel.push_back(next);
next = next->nextarc;
}
}
for(vector<EdgeNode*>::iterator it = needtodel.begin(); it != needtodel.end(); ++it)
...{
delete *it;
}
}
test.h
#include " aov.h "
#define PATH_LEN 256
class AOVTest
... {
Graph G;
std::vector<int> outputArray;
public:
int prepare(const char* file);
int TopologicalSort();
int output(const char* file);
} ;
#define PATH_LEN 256
class AOVTest
... {
Graph G;
std::vector<int> outputArray;
public:
int prepare(const char* file);
int TopologicalSort();
int output(const char* file);
} ;
test.cpp
#include " test.h "
#include < fstream >
#include < stack >
using namespace std;
#define BUFFER_SIZE 1024
int AOVTest::TopologicalSort()
... {
int count = 0;
int* indegree = (int*)calloc(G.vnum, sizeof(int));
if(!indegree)
...{
printf( "Can't allocate memory " );
return -1;
}
for(int i = 0; i < G.vnum; ++i)
...{
EdgeNode* t = G.Vertices[i].firstarc;
while(t)
...{
indegree[t->adjvex]++;
t = t->nextarc;
}
}
stack<int> S;
for(int i = 0; i<G.vnum; ++i)
...{
if(indegree[i] == 0)
S.push(i);
}
count = 0;
while(!S.empty())
...{
int idx = S.top();
outputArray.push_back(idx);
S.pop();
++count;
for(EdgeNode* t = G.Vertices[idx].firstarc; t ; t = t->nextarc)
...{
int k = t->adjvex;
indegree[k]--;
if(indegree[k] == 0)
S.push(k);
}
}
if(count < G.vnum)
...{
free(indegree);
return -1;
}
free(indegree);
return 0;
}
//
// create graph from test file
int AOVTest::prepare( const char * file)
... {
fstream fs(file, ios::in);
if(!fs)
...{
cout << "in file open failed!" << endl;
return -1;
}
while(!fs.eof())
...{
char buffer[BUFFER_SIZE];
memset(buffer, 0, BUFFER_SIZE);
fs.getline(buffer, BUFFER_SIZE);
string line(buffer);
if(line.empty())
continue;
string::size_type pos = 0;
pos = line.find("->", 0);
if(pos != string::npos)
...{
//handle with first cloth
string sfirst = line.substr(0, pos);
if(sfirst.empty())
...{
printf("Error format. check test file. //->first one not exist!");
return -1;
}
int idx1 = G.getNode(sfirst.c_str());
if(idx1 == -1)
...{ //find in VNode
idx1 = G.vnum;
VNode vnode1(sfirst.c_str(), 0);
G.addNode(vnode1);
}
//handle with last cloth
string slast = line.substr(pos + 2, line.length() - pos - 2);
if(slast.empty())
...{
printf("Error format. check test file. //->last one not exist!");
return -1;
}
int idx2 = G.getNode(slast.c_str());
if(idx2 == -1)
...{ //find in VNode
idx2 = G.vnum;
VNode vnode2(slast.c_str(), 0);
G.addNode(vnode2);
}
//connection reverse
EdgeNode* plink = new EdgeNode(idx2);
EdgeNode* next = G.Vertices[idx1].firstarc;
if(!next)
G.Vertices[idx1].firstarc = plink;
else
...{
EdgeNode* current;
while(next)
...{
current = next;
next = next->nextarc;
}
current->nextarc = plink;
}
}
}
return 0;
}
int AOVTest::output( const char * file)
... {
fstream fs(file, ios::out);
if(!fs)
...{
cout << "out file open failed!" << endl;
return -1;
}
for(vector<int>::iterator it = outputArray.begin(); it != outputArray.end(); ++it)
...{
fs << G.Vertices[*it].data << endl;
}
return 0;
}
#include < fstream >
#include < stack >
using namespace std;
#define BUFFER_SIZE 1024
int AOVTest::TopologicalSort()
... {
int count = 0;
int* indegree = (int*)calloc(G.vnum, sizeof(int));
if(!indegree)
...{
printf( "Can't allocate memory " );
return -1;
}
for(int i = 0; i < G.vnum; ++i)
...{
EdgeNode* t = G.Vertices[i].firstarc;
while(t)
...{
indegree[t->adjvex]++;
t = t->nextarc;
}
}
stack<int> S;
for(int i = 0; i<G.vnum; ++i)
...{
if(indegree[i] == 0)
S.push(i);
}
count = 0;
while(!S.empty())
...{
int idx = S.top();
outputArray.push_back(idx);
S.pop();
++count;
for(EdgeNode* t = G.Vertices[idx].firstarc; t ; t = t->nextarc)
...{
int k = t->adjvex;
indegree[k]--;
if(indegree[k] == 0)
S.push(k);
}
}
if(count < G.vnum)
...{
free(indegree);
return -1;
}
free(indegree);
return 0;
}
//
// create graph from test file
int AOVTest::prepare( const char * file)
... {
fstream fs(file, ios::in);
if(!fs)
...{
cout << "in file open failed!" << endl;
return -1;
}
while(!fs.eof())
...{
char buffer[BUFFER_SIZE];
memset(buffer, 0, BUFFER_SIZE);
fs.getline(buffer, BUFFER_SIZE);
string line(buffer);
if(line.empty())
continue;
string::size_type pos = 0;
pos = line.find("->", 0);
if(pos != string::npos)
...{
//handle with first cloth
string sfirst = line.substr(0, pos);
if(sfirst.empty())
...{
printf("Error format. check test file. //->first one not exist!");
return -1;
}
int idx1 = G.getNode(sfirst.c_str());
if(idx1 == -1)
...{ //find in VNode
idx1 = G.vnum;
VNode vnode1(sfirst.c_str(), 0);
G.addNode(vnode1);
}
//handle with last cloth
string slast = line.substr(pos + 2, line.length() - pos - 2);
if(slast.empty())
...{
printf("Error format. check test file. //->last one not exist!");
return -1;
}
int idx2 = G.getNode(slast.c_str());
if(idx2 == -1)
...{ //find in VNode
idx2 = G.vnum;
VNode vnode2(slast.c_str(), 0);
G.addNode(vnode2);
}
//connection reverse
EdgeNode* plink = new EdgeNode(idx2);
EdgeNode* next = G.Vertices[idx1].firstarc;
if(!next)
G.Vertices[idx1].firstarc = plink;
else
...{
EdgeNode* current;
while(next)
...{
current = next;
next = next->nextarc;
}
current->nextarc = plink;
}
}
}
return 0;
}
int AOVTest::output( const char * file)
... {
fstream fs(file, ios::out);
if(!fs)
...{
cout << "out file open failed!" << endl;
return -1;
}
for(vector<int>::iterator it = outputArray.begin(); it != outputArray.end(); ++it)
...{
fs << G.Vertices[*it].data << endl;
}
return 0;
}
最后的了,main.cpp
#include " test.h "
#define USAGE_MSG "Usage: AOV [infile] + options
- o refer to output file.
default - o is result.txt. "
int main( int argc, char ** argv)
... {
if(argc < 2)
...{
//printf("Usage: AOV [infile] + options
// -o refer to output file.
// default -o is result.txt. ");
printf(USAGE_MSG);
getchar();
return -1;
}
char infile[256];
char outfile[256];
memset(outfile, 0, sizeof(outfile));
for(int i = 1; i < argc; ++i)
...{
if(argv[i][0] != '-')
...{
if(i == 1)
strcpy(infile, argv[i]);
else if(i == 3)
strcpy(outfile, argv[i]);
else
...{
printf(USAGE_MSG);
getchar();
return -1;
}
}
else
...{
if(argv[i][1] != 'o' || strlen(argv[i]) > 2)
...{
printf(USAGE_MSG);
getchar();
return -1;
}
}
}
if(!outfile)
...{
strcpy(outfile, "result.txt");
}
AOVTest ts;
int ret = 0;
ret = ts.prepare(infile);
if(ret)
_ASSERT(0);
ret = ts.TopologicalSort();
if(ret)
_ASSERT(0);
ret = ts.output(outfile);
if(ret)
_ASSERT(0);
getchar();
return 0;
}
#define USAGE_MSG "Usage: AOV [infile] + options
- o refer to output file.
default - o is result.txt. "
int main( int argc, char ** argv)
... {
if(argc < 2)
...{
//printf("Usage: AOV [infile] + options
// -o refer to output file.
// default -o is result.txt. ");
printf(USAGE_MSG);
getchar();
return -1;
}
char infile[256];
char outfile[256];
memset(outfile, 0, sizeof(outfile));
for(int i = 1; i < argc; ++i)
...{
if(argv[i][0] != '-')
...{
if(i == 1)
strcpy(infile, argv[i]);
else if(i == 3)
strcpy(outfile, argv[i]);
else
...{
printf(USAGE_MSG);
getchar();
return -1;
}
}
else
...{
if(argv[i][1] != 'o' || strlen(argv[i]) > 2)
...{
printf(USAGE_MSG);
getchar();
return -1;
}
}
}
if(!outfile)
...{
strcpy(outfile, "result.txt");
}
AOVTest ts;
int ret = 0;
ret = ts.prepare(infile);
if(ret)
_ASSERT(0);
ret = ts.TopologicalSort();
if(ret)
_ASSERT(0);
ret = ts.output(outfile);
if(ret)
_ASSERT(0);
getchar();
return 0;
}
这篇关于AOV拓扑排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!