【编程珠玑(续)】第二章 关联数组

一,关联数组

       关联数组和数组类似,由以名称作为键的字段和方法组成。

  它包含标量数据,可用索引值来单独选择这些数据,和数组不同的是, 关联数组的索引值不是非负的整数而是任意的标量。这些标量称为Keys,可以在以后用于检索数组中的数值。
  关联数组的元素没有特定的顺序,你可以把它们想象为一组卡片。每张卡片上半部分是索引而下半部分是数值。
  JavaScript的对象本质就是一个关联数组。
  Perl语言中的关联数组用法:
  %ARRAY=(key1,value1,key2,value2,key3,value3);
  一个KEY 对应一个VALUE。


二,有穷状态机模拟器

  "抑制"比特流中所有新出现的1:

  1. Input:      011010111  
  2. Output:  001000011 
紧跟在0后面的1被改成0,输入流中的所有其他比特位不变。

下面的两状态自动机在其状态中对最后一个输入比特进行编码:"LIZ"表示"Last Input Zero",而"LIO"表示"Last Input One"。


指向LIZ的横向箭头表明这是初始状态。从LIZ到LIO的弧线的意思是,如果自动机当前处于状态LIZ且输入是一个1,则输出一个0并进入状态LIO。如果自动机当前处于状态LIO且输入是一个1,则输出一个1仍然在状态LIO。


三,拓扑排序
       拓扑排序算法的输入是一个有向无环图。好的拓扑排序算法还必须能够处理输入图中包含回路因此无法完成排序的可能情况。

       拓扑排序的思想
       拓扑图是让每个结点,组成一个顶点链。然后每个顶点之后再链接图中下一个顶点。
       初始化一个数组,存放每个顶点的入度。
       将所有入度为0 的定点放到 stack 中。每输出一个定点,将相应入度减1
       每输出一个顶点就将入度为0 的输入进 stack 
       最后将stack 输出为止。详细见源码
#include<iostream>
#include<string>
#include<stack>
using namespace std;

#define MAX_VERTEX_NUM 20
typedef struct ArcNode{
	int adjvex;                    //该弧所指向的顶点的位置
	struct ArcNode *nextarc;       //指向下一条弧的指针
	//	string info;           //该弧相关信息
}ArcNode;
typedef struct VNode{
	int data;                          //顶点信息
	ArcNode *firstarc;                 //指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
	AdjList vertices;                  //存储图
	int venum,arcnum;                //图的当前顶点数和弧数
	int kind;                       //图的种类标志
}ALGraph;

int InDegree[MAX_VERTEX_NUM]={0};       //用于拓扑排序


int CreateDG(ALGraph& G){//这个是有向图
	cout<<"请输入图中顶点个数和边数:";
	cin>>G.venum>>G.arcnum;
	int i;
	for( i=0; i<G.venum; i++){
		G.vertices[i].data=i+1; //结点 符号为从 1 开始的数字
		G.vertices[i].firstarc=NULL;
	}
	for( i=0; i<G.arcnum; i++){
		cout<<"请输入你要加入的边的信息(边所在的顶点下标:从1开始的数字):";
		int v1, v2;
		cin>>v1>>v2;
		ArcNode* current=G.vertices[v1-1].firstarc;
		ArcNode* p=G.vertices[v1-1].firstarc;
		InDegree[v2-1]++;//入度++
		if(current==NULL){ //如果输入结点 第一个 结点为空,则新建一个结点插入
			G.vertices[v1-1].firstarc=new ArcNode;
			G.vertices[v1-1].firstarc->adjvex=v2-1;
			G.vertices[v1-1].firstarc->nextarc=NULL;
		}
		else{//采用尾插法插入到链表中
			while(current!=NULL){
				p=current;
				current=current->nextarc;
			}
			current=new ArcNode;
			current->adjvex=v2-1;
			current->nextarc=NULL;
			p->nextarc=current;
		}
	}
	return 1;
}

void TopologicalSort(ALGraph &G){
	stack<int> S;
	int i;
	for( i=0; i<G.venum; i++){
		if(InDegree[i]==0){
			S.push(i);  //将所有入度为 0  的入栈
		}
	}
	int count=0;
	while(!S.empty()){
		i=S.top();
		S.pop();
		cout<<G.vertices[i].data<<"  ";
		++count;
		ArcNode *p=NULL;
		for( p=G.vertices[i].firstarc; p!=NULL; p=p->nextarc){
			int w=p->adjvex;
			InDegree[w]--;
			if(InDegree[w]==0){
				S.push(w);
			}
		}
	}
	if(count<G.venum){  //看是否将所有结点输出
		cout<<"有向图中有环存在"<<endl;
	}
}

int main(){
	ALGraph G;
	CreateDG(G);
	ArcNode* current1;
	ArcNode* p;
	for(int k=0; k<G.venum; k++){
		cout<<G.vertices[k].data<<" -> ";
		ArcNode* current1=G.vertices[k].firstarc;
		while(current1!=NULL){
			cout<<current1->adjvex<<" -> ";
			current1=current1->nextarc;
		}
		cout<<endl;
	}

	TopologicalSort(G);

	for(int i=0; i<G.venum; i++){                         //析构函数
		current1=p=G.vertices[i].firstarc;
		if(current1==NULL)
			continue;
		else{
			while(p!=NULL){
				p=current1->nextarc;
				delete current1;
				current1=p;
			}
		}
	}
}
四,习题
       采用AWK 来写,略过




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值