闲暇有余,威盛第10题的解法(高手看看有问题不)

threeleafzerg007 2008-12-05 02:21:19
(原题) 题目10Please give a description of the algorithm to renmove the dead code in a program (That is,”dead code elimination ”),(An instruction and a variable are dead if it computes values which are not used on any executable path to the procedure’s exit.)For example, in below program,(请给出一个算法,实现移除死代码的功能)
b=a+c
d=c+f
d=d*a
d=d*c
return d;

Instruction “b=a+c”is dead since b has no effect to the final output d.(比如说上面的代码中b=a+c 就对最后结果d一点用处都没有)
We need an algorithm to find out such dead code and remove them from the final program.

思路:
根据每一个表达式 逐渐建立一张 有向图 以邻接表方式存储

struct _adjacentNode{

char nodeName[16];
char *nodeNameList;
int Listlength; // 出度数
}adjacentNode;

adjacentNode map[MAX_NODE_NUM];


比如 读到 d = c + f

遍历一下 d 节点的出度表 有没有c f如果没有 则加入 并且出度+2

整个图建立完后 根据 return 哪一个结点 开始 以该节点单向(出)遍历整个图,得到连通图,没有包括的结点就是dead expression

代码:

class-a.h
#ifndef _CLASS_A_H_
#define _CLASS_A_H_

struct listNode;

struct adjacentNode{
char nodeName;
struct listNode *nlist;
int degree; //出度
};
#endif

class-b.h
#ifndef _CLASS_B_H_
#define _CLASS_B_H_

struct adjacentNode;

struct listNode{
struct adjacentNode *pNode;
struct listNode *next;
};

#endif

//之所以放2个头件 主要是这两结构互相嵌套

algorithm.h

#ifndef _ALGORITHM_H_
#define _ALGORITHM_H_
#include <algorithm>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
//广度优先
int MAP_BFS_Search(struct adjacentNode *pmap,struct adjacentNode *pStart,vector<char> &connGraph);

//深度优先
int MAP_DFS_Search(struct adjacentNode *pmap,struct adjacentNode *pStart,vector<char> &connGraph);

#endif

algorithm.cpp
#include "class-a.h"
#include "class-b.h"
#include "util.h"
#include "algorithm.h"

int MAP_BFS_Search(struct adjacentNode *pmap,struct adjacentNode *pStart,vector<char> &connGraph)
{
if(pStart == NULL || pStart->degree == -1)
return -1;
deque<char> charQueue;
connGraph.push_back(pStart->nodeName);
for(struct listNode *p1 = pStart->nlist; p1 !=NULL;charQueue.push_back(p1->pNode->nodeName),p1=p1->next);
while(!charQueue.empty())
{
char pop = charQueue.front();
charQueue.pop_front();
connGraph.push_back(pop);
struct adjacentNode *p2 = &(pmap[pop-'a']);
for(struct listNode *p3 = p2->nlist;p3 != NULL; p3 = p3->next)
{
char c = p3->pNode->nodeName;
if(find(connGraph.begin(),connGraph.end(),c) == connGraph.end())
{
charQueue.push_back(c);
}
}
}
return 0;
}

int MAP_DFS_Search(struct adjacentNode *pmap,struct adjacentNode *pStart,vector<char> &connGraph)
{
if(pStart == NULL || pStart->degree == -1)
return -1;
deque<char> charStack;
charStack.push_front(pStart->nodeName);
while(!charStack.empty())
{
char c = charStack.front();
struct listNode *p1 = NULL;
for(p1 = pmap[c-'a'].nlist; p1 != NULL; p1 = p1->next)
{
char d = p1->pNode->nodeName;
//已经遍历过
if(find(connGraph.begin(),connGraph.end(),d) != connGraph.end())
continue;
//是祖先
if(find(charStack.begin(),charStack.end(),d) != charStack.end())
continue;
charStack.push_front(d);
break;
}
if(p1 != NULL)
continue;
connGraph.push_back(c);
charStack.pop_front();
}
return 0;
}

util.h
#ifndef _UTIL_H_
#define _UTIL_H_

int ProcessFile(char *filename,struct adjacentNode *pmap,char &result);
int ProcessLine(struct adjacentNode *pmap,const char *line,char &result);
void InitializeMap(struct adjacentNode *pmap,int size);
bool IsNodeExist(struct listNode *listhead,char nodeName);
void PrintMap(struct adjacentNode *pmap,int size);

#endif

...全文
196 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
threeleafzerg007 2008-12-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sss_free 的回复:]
引用 3 楼 threeleafzerg007 的回复:
我倒 根据上面的提示 我发现自己的问题了

它那算术是

自上往下算的

也就是说
如果
d=d*a
d=a*b
然后
b=b*c

这时候b=b*c实际上是无效语句 d不依赖于c
但是我的设计里 d依赖于 c了
谢2楼 你的想法很不错 我觉得应该能实现。 一会会给分的


快点给分啦~,哈哈
推荐你一本书“自动机理论和计算导论”,我工作这么多年平时仍然在看这本书,还是觉得很多地方不懂
[/Quote]

我在看算法导论 重新学一遍数据结构和算法 当年看的是 清华大学 严蔚敏的那本烂书 唉 中国人写的计算机书99%的垃圾
接分吧 呵呵
lala_benben 2008-12-05
  • 打赏
  • 举报
回复
mark
sss_free 2008-12-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 threeleafzerg007 的回复:]
我倒 根据上面的提示 我发现自己的问题了

它那算术是

自上往下算的

也就是说
如果
d=d*a
d=a*b
然后
b=b*c

这时候b=b*c实际上是无效语句 d不依赖于c
但是我的设计里 d依赖于 c了
谢2楼 你的想法很不错 我觉得应该能实现。 一会会给分的

[/Quote]
快点给分啦~,哈哈
推荐你一本书“自动机理论和计算导论”,我工作这么多年平时仍然在看这本书,还是觉得很多地方不懂
threeleafzerg007 2008-12-05
  • 打赏
  • 举报
回复
我倒 根据上面的提示 我发现自己的问题了

它那算术是

自上往下算的

也就是说
如果
d=d*a
d=a*b
然后
b=b*c

这时候b=b*c实际上是无效语句 d不依赖于c
但是我的设计里 d依赖于 c了
谢2楼 你的想法很不错 我觉得应该能实现。 一会会给分的
sss_free 2008-12-05
  • 打赏
  • 举报
回复
我想可以用语法产生式,从底部往上找
E$E->E
s->E
a|b|c|f->s
这个s的集合可以通过遍历源码。
d=d*c根据第一个产生式
d=(E*E)*c
然后
d=(d*a)*c
再向上扫描
d=((c+f)*a)*c
到底了,c,f,a,c都是symbol了
没有b向上扫描,找到b=a+c;remove it.


我没动手做,就是谈点想法。
threeleafzerg007 2008-12-05
  • 打赏
  • 举报
回复
还有:
util.cpp
#include <set>
#include <iostream>
#include <fstream>
#include "class-a.h"
#include "class-b.h"
#include "error.h"
#include "util.h"
using namespace std;
static bool isAlpha(char c)
{
if(c >= 'a' && c <= 'z')
return true;
return false;
}
static bool isExpr(char c)
{
if(c == '-' || c == '+' || c == '*' || c == '/')
return true;
return false;
}
static bool isEqual(char c)
{
if(c == '=')
return true;
return false;
}
static bool isNum(char c)
{
if(c >= '0' && c <= '9')
return true;
return false;
}
int ProcessFile(char *filename,struct adjacentNode *map,char &result)
{
ifstream ifile(filename,ifstream::in);
char line[1024];
int ret = 0;
if(!ifile.is_open())
{
return FILE_OPEN_ERROR;
}

while(ifile.good())
{
memset(line,0,1024);
ifile.getline(line,1024);
ret = ProcessLine(map,line,result);
if(ret)
return ret;
}
ifile.close();
return 0;
}

int ProcessLine(struct adjacentNode *map,const char *line,char &result)
{
bool bequal = false;
struct adjacentNode *pNode = NULL;
for(const char *p = line; p != NULL && *p != '\0';p++)
{
if(isAlpha(*p))
{
if(!bequal)
{
pNode = &(map[*p-'a']);
if(pNode->degree == -1)
{
pNode->degree = 0;
}
continue;
}
else
{
if(map[*p-'a'].degree == -1)
{
map[*p-'a'].degree = 0;
}
if(!IsNodeExist(pNode->nlist,*p))
{
struct listNode *pnew = new struct listNode;
pnew->pNode = &(map[*p-'a']);
pnew->next = NULL;
if(pNode->nlist == NULL)
{
pNode->nlist = pnew;
}
else
{
struct listNode *p1 = NULL;
for(p1 = pNode->nlist;p1->next != NULL;p1 = p1->next);
p1->next = pnew;
}
(pNode->degree)++;
}
continue;
}
}
if(isEqual(*p))
{
bequal = true;
continue;
}
if(isExpr(*p))
{
continue;
}
if(isNum(*p))
{
continue;
}
if(*p == '!')
{
if(p+1!= NULL)
result = *(p+1);
else
result = 0;
return 0;
}
return UNKNOWN_CHAR_ERROR;
}
return 0;
}

void InitializeMap(struct adjacentNode *map,int size)
{
memset(map,0,sizeof(adjacentNode)*size);
for(int i = 0; i < size; i++)
{
map[i].nodeName = 'a' + i;
map[i].degree = -1;
}
return;
}


bool IsNodeExist(struct listNode *listhead,char nodeName)
{
for(struct listNode *pn = listhead; pn != NULL;pn = pn->next)
{
if(pn->pNode->nodeName == nodeName)
return true;
}
return false;
}

void PrintMap(struct adjacentNode *pmap,int size)
{
int i = 0;
for(struct adjacentNode *p1 = pmap;i < size; i++,p1++)
{
if(p1->degree == -1)
continue;

cout<<"NodeName:"<<p1->nodeName<<" Degree:"<<p1->degree<<endl;
cout<<"NodeList:";
for(struct listNode *p2 = p1->nlist;p2 != NULL; p2 = p2->next)
{
cout<<" "<<p2->pNode->nodeName;
}
cout<<endl;
}
return;
}

error.h
#ifndef _ERROR_H_
#define _ERROR_H_

#define BASENUM 1

#define FILE_OPEN_ERROR BASENUM+1
#define UNKNOWN_CHAR_ERROR BASENUM+2
#endif

main.cpp

#include <iostream>
#include <vector>
#include "class-a.h"
#include "class-b.h"
#include "util.h"
#include "algorithm.h"
#include "error.h"
using namespace std;

#define FILE_NAME "expr.txt"
#define MAX_NODE_NUM 26
int main()
{

struct adjacentNode map[MAX_NODE_NUM];
char result = 0;
InitializeMap(map,MAX_NODE_NUM);
int r = ProcessFile(FILE_NAME,map,result);
if(r)
{
cout<<"ProcessFile error"<<endl;
}
PrintMap(map,MAX_NODE_NUM);
cout<<"Node waiting for count:"<<result<<endl;
vector<char> connGraph;
/*
r = MAP_BFS_Search(map,&(map[result-'a']),connGraph);
if(r)
{
cout<<"MAP_BFS_Search error"<<endl;
}
*/
r = MAP_DFS_Search(map,&(map[result-'a']),connGraph);
if(r)
{
cout<<"MAP_DFS_Search error"<<endl;
}
cout<<"ConnGraph:"<<endl;
for(vector<char>::iterator it = connGraph.begin(); it != connGraph.end(); ++it)
{
cout<<*it;
}
cout<<endl;
return 0;
}

expr.txt
b=a+c
d=c+f
g=b-a
f=a-c
a=10
c=3*12
e=c+f
!e


贴完了,写的仓促 ,图里内存没有释放 c/c++ 代码风格混乱 望海涵 主要是看看算法逻辑上有没有问题,能不能解那个题 我自己只测试了1个列子 结果正常



64,644

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧