《数据结构、算法与应用C++语言描述》-栈的应用-离线等价类问题

离线等价类问题

问题描述

等价类:假定一个具有n个元素的集合U=1,2,…,n和一个具有r个关系的集合 R = ( i 1 , j 1 ),( i 2 , j 2 ), … ,( i r , j r ) R=(i_1,j_1),(i_2,j_2),…,(i_r, j_r) R=i1j1),(i2j2),,(ir,jr。关系 R是一个等价关系(equivalence relation),当且仅当如下条件为真:

  • 对于所有的 a ⊂ R a\subset R aR,有(a,a) ⊂ \subset R时(关系是自反的)。
  • (a,b) ⊂ \subset R,当且仅当(b,a) ⊂ \subset R(关系是对称的)。
  • 若(a,b) ⊂ \subset R且(b,c) ⊂ \subset R,则有(a,c) ⊂ \subset R(关系是传递的)。

在给出等价关系R时,我们经常会忽略其中的某些数对,这些数对可以应用等价关系的自反性、对称性和传递性来得到。

如果(a,b) ⊂ \subset R,则元素a和b是等价的。所谓等价类(equivalence class)是指相互等价的元素的最大集合。“最大”意味着不存在类以外的元素与类内部的元素等价。因为一个元素只能属于一个等价类,等价关系把集合 U划分为不相交的等价类。

举例

例6-3 假定 n=14,R={(1,11),(7,11),(2,12),(12,8),(11,12),(3,13),(4,13),(13,14),(14,9),(5,14),(6,10)}。我们忽略了所有形如(a,a)的数对,因为按照自反性,这些数对是隐含的。同样也忽略了所有对称的数对。因为(1,11) ⊂ \subset R,所以按照对称性应有(11,1) ⊂ \subset R。其他被忽略的数对由传递性可以得到。例如,由(7,11)和(11,12),可以得到(7,12) ⊂ \subset R。

例 6-4 考察例 6-3 中的等价关系。由于元素 1 与 11,11 与 12 是等价的,因此,元素1、11、12是等价的,它们应属于同一个等价类。不过,这三个元素还不能构成一个等价类,因为还有其他的元素与它们等价(例如7)。因此(1,11,12)不是等价元素的最大集合。集合{1,2,7,8,11,12)才是一个等价类。关系R还定义了另外两个等价类:(3,4,5,9,13,14)和(6,10)。注意,这三个等价类是互不相交的。

离线等价类(offline equiralence class)问题中,已知 n 和 R,确定所有的等价类。由等价类的定义得知,每个元素只能属于一个等价类。
简化问题描述:这个问题的输入是元素数目n、关系对数目r以及r个关系对。目标是把n个元素划分为等价类。

求解策略

求解分为两个阶段。在第一个阶段,我们输入数据,建立 n个表以表示关系对。对每一个关系对(i,j),i放在list[j],j放在list[i]。

例8-3 假定n=9,r=11,且11个关系对是(1,5),(1.6),(3,7),(4,8),(5,2),(6,5),(4,9),(9,7),(7,8),(3,4),(6,2)。9个表是:

list[1]=[5,6]
list[2]=[5,6]
list[3]=[7,4]
list[4]=[8,9,3]
list[5]=[1,2,6]
list[6]=[1,2,5]
list[7]=[3,9,8]
lis[8]=[4,7]
list[9]=[4,7]

在第二个阶段是寻找等价类。为寻找一个等价类,首先要找到该等价类中第一个没有输出的元素。这个元素作为该等价类的种子。该种子作为等价类的第一个成员输出。从这个种子开始,我们找出该等价类的所有其他成员。种子被加到一个表unprocessedList中。从表unprocessedLis中删除一个元素i,然后处理表list[i]。list[i]中所有元素和种子同属一个等价类;将list[i]中还没有作为等价类成员的元素输出,然后加入unprocessedList中。这是一个过程:从表 unprocessedLis 中删除一个元素i,然后把表 list[i]中还没有输出的元素输出,并且加入unprocessedList中。这个过程持续进行到unprocessedList为空。这时我们就找到了一个等价类,然后继续寻找下一个等价类的种子。

例8-4 考虑例8-3。令1 是第一个种子,作为一个等价类的成员被输出,然后加入表unprocessedList中。接下来把1从unprocessedList中删除,然后处理list[1]。元素5和6属于list[1],与1同属一个等价类,它们被输出,然后加入unprocessedList中。将5或6从unprocessedList中删除,然后处理它们所在的表。假定删除的是5。考察list[5]中的元素1、2和6。因为1和6已经输出,所以被忽略。把元素2输出,然后加入unprocessedList中。当unprocessedList中的剩余元素(6和2)被删除和处理,没有其他元素被输出或加入unprocessedList时,unprocessedList成为空表,这时我们便找到了一个等价类。
为找到另一个等价类,我们要寻找一个种子,它是还没有输出的元素。元素 3 还没有输出,因此可以作为下一个等价类得种子。元素3、4、7、8和9作为这个等价类的元素被输出。这时不再有种子,因此我们找到了所有等价类。

代码

#include <iostream>
#include <stack>
using namespace std;/*离线等价类问题*/
void offlineEquivalenceClass()
{int n,//元素个数r;//关系个数/*输入元素个数n*//*首先成功输入一次*/cout << "Enter number of elements(n >= 2):";while (!(cin >> n)) {//如果输入类型不匹配,则执行循环体cin.clear(); // reset input设置标志位为有效while (cin.get() != '\n') //删除没有用的输入continue; // get rid of bad inputcout << "Enter number of elements(n >= 2):";}/*成功输入一次后检查是否符合要求*/while (n < 2) {//如果元素个数小于2,则出错cout << "n must be equal or bigger than 2!" << endl;cout << "Enter number of elements(n >= 2):";while (!(cin >> n)) {//如果输入类型不匹配,则执行循环体cin.clear(); // reset input设置标志位为有效while (cin.get() != '\n') //删除没有用的输入continue; // get rid of bad inputcout << "Enter number of elements(n >= 2):";}}/*输入关系个数r*//*首先成功输入一次*/cout << "Enter number of relations(r >= 1):";while (!(cin >> r)) {//如果输入类型不匹配,则执行循环体cin.clear(); // reset input设置标志位为有效while (cin.get() != '\n') //删除没有用的输入continue; // get rid of bad inputcout << "Enter number of relations(r >= 1):";}/*成功输入一次后检查是否符合要求*/while (r < 1) {//如果元素个数小于2,则出错cout << "r must be equal or bigger than 1!" << endl;cout << "Enter number of relations(r >= 1):";while (!(cin >> r)) {//如果输入类型不匹配,则执行循环体cin.clear(); // reset input设置标志位为有效while (cin.get() != '\n') //删除没有用的输入continue; // get rid of bad inputcout << "Enter number of relations(r >= 1):";}}/*建立空栈组成的数组,stack[0]不用,用于存储表格*/stack<int>* list = new stack<int>[n + 1];/*输入r个关系,存储在表中*/int a, b;//(a,b)是一个关系for (int i = 1; i <= r; i++){cout << "Enter next relation/pair:";while (!(cin >> a >> b)) {//如果输入类型不匹配,则执行循环体cin.clear(); // reset input设置标志位为有效while (cin.get() != '\n') //删除没有用的输入continue; // get rid of bad inputcout << "Enter error!Enter current relation/pair:";}list[a].push(b);list[b].push(a);}/*初始化已输出等价类*/stack<int> unprossedList;bool* out = new bool[n + 1];//判断该元素是否输出for (int i = 1; i <= n; i++)out[i] = false;/*输出等价类*/for (int i = 1; i <= n; i++){if (!out[i]){cout << "Next class is:" << i << " ";out[i] = true;unprossedList.push(i);//从unprossedList中取类的剩余元素while (!unprossedList.empty()){int j = unprossedList.top();unprossedList.pop();while (!list[j].empty()){int q = list[j].top();list[j].pop();if (!out[q]) //未输出{cout << q << " ";out[q] = true;unprossedList.push(q);}}}cout << endl;}}cout << "End of list of eqivalence classes." << endl;
}int main()
{cout << "offlineEquivalenceClass()*******" << endl;offlineEquivalenceClass();return 0;
}

运行结果

C:\Users\15495\Documents\Jasmine\Work\coding\cmake-build-debug\coding.exe
offlineEquivalenceClass()*******
Enter number of elements(n >= 2):14
Enter number of relations(r >= 1):11
Enter next relation/pair:1 11
Enter next relation/pair:7 11
Enter next relation/pair:2 12
Enter next relation/pair:12 8
Enter next relation/pair:11 12
Enter next relation/pair:3 13
Enter next relation/pair:4 13
Enter next relation/pair:13 14
Enter next relation/pair:14 9
Enter next relation/pair:5 14
Enter next relation/pair:6 10
Next class is:1 11 12 7 8 2 
Next class is:3 13 14 4 5 9
Next class is:6 10
End of list of eqivalence classes.Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/91912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推出全新AIGameFi,SCF金融公链FinSOUL促进元宇宙发展

在被誉为元宇宙元年的2021年&#xff0c;SCF&#xff08;Standard Cross Finance&#xff09;金融公链正着眼于打造一项开创性的项目&#xff0c;推出创新的金融公链生态&#xff0c;并期待成为元宇宙2.0的先锋。虽然2021年见证了元宇宙项目的强势崛起&#xff0c;但在SCF金融公…

Vue定义全局组件的方式

Vue.js是一种流行的JavaScript框架&#xff0c;用于构建交互式的Web应用程序。Vue提供了一种简单而灵活的方式来定义和使用组件。在本文中&#xff0c;我们将探讨Vue中定义全局组件的三种方式&#xff0c;让你能够更好地理解和使用Vue组件。 引言 组件是Vue应用程序的基本构建…

【C++】class的设计与使用(十)重载iostream运算符

希望对某个类对象进行读写操作&#xff0c;直接cout<<类对象<<endl;或cin>>类对象;编译器会报错&#xff0c;所以我们必须提供一份重载的input/output运算符&#xff1a; 重载ostream运算符 ostream& operator<<(ostream &os, const Triangu…

Redis配置和优化

Redis配置和优化 一 、Redis介绍二、关系数据库和非关系数据库2.1、关系型数据库2.2、 非关系型数据库2.3、 非关系型数据库的产生背景2.4、 关系型数据库和非关系型数据库区别2.5、 总结 三、缓存概念3.1、系统缓存3.2、 缓存保存位置及分层结构3.2.1、DNS缓存3.2.2、 应用层缓…

10.1 File类

前言&#xff1a; java.io包中的File类是唯一一个可以代表磁盘文件的对象&#xff0c;它定义了一些用于操作文件的方法。通过调用File类提供的各种方法&#xff0c;可以创建、删除或者重命名文件&#xff0c;判断硬盘上某个文件是否存在&#xff0c;查询文件最后修改时间&…

MySQL数据库基础与概念解析

在如今这个信息爆炸的时代,数据成了我们生活中不可或缺的一部分。但是,数据本身并没有太大的价值,真正重要的是我们如何管理和利用这些数据。这就引出了数据库这一概念,一个系统化、高效的数据管理工具。 特别是在复杂的应用场景中,比如游戏《三国志》系列,一个好的数据…

【HTML】表格行和列的合并

概述 当我们需要在 HTML 表格中展示复杂的数据时&#xff0c;行和列的合并可以帮助我们实现更灵活的布局和结构。通过合并行和列&#xff0c;我们可以创建具有更多层次和结构的表格&#xff0c;使数据更易于理解和分析。 在 HTML 表格中&#xff0c;我们可以使用 rowspan 和 …

ELK整合springboot(第二课)

一、创建一个springboot的项目 pom文件如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLo…

Debian跳过grub页面

nano /etc/default/grub将GRUB_TIMEOUT的值改为0 将GRUB_CMDLINE_LINUX_DEFAULT的值改为"quiet splash" 如果要禁用开局日志的话&#xff0c;将GRUB_CMDLINE_LINUX_DEFAULT的值改为"quiet splash loglevel0" update-grub

lv5 嵌入式开发-12 信号灯

目录 1 信号量/灯(semaphore)基本概念 2 信号量&#xff0d;&#xff30;&#xff0f;&#xff36;操作概念 3 三种信号灯 3.1 有名信号灯 3.1.1 打开 3.1.2 关闭 3.1.3 删除 3.2 无名信号灯 3.2.1 初始化 3.2.2 销毁 3.3 信号灯P操作 3.4 信号灯V操作 3.5 示例 …

Visual Studio 中将TAB设置为空格

将TAB设置为空格的原因很多&#xff0c;其中一点是为了统一不同编译器对TAB的解释&#xff0c;防止代码风格在不同编译器下不一致等。 在菜单中选择: 工具-->选项-->文本编辑器--->所有语言-->制表符 在窗口中选择&#xff0c;制表符大小和缩进大小都选为4&#xf…

10.1 国庆节小任务

目录 select实现服务器并发 服务器 客户端 运行现象 select实现服务器并发 服务器 #include<myhead.h>#define PORT 8888 //1024~49151 #define IP "192.168.1.104" //ifconfig查看本机IPint main(int argc, const char *argv[]) {//创建流式…

本次CTF·泰山杯网络安全的基础知识部分(二)

简记23年九月参加的泰山杯网络安全的部分基础知识的题目&#xff0c;随时补充 15&#xff08;多选&#xff09;网络安全管理工作必须坚持“谁主管、谁负责&#xff0c;谁运营、谁负责&#xff0c;谁使用、谁负责”的原则&#xff0c;和“属地管理”的原则 谁主管、谁负责&…

WiFi网络分析工具Airtool for Mac

Airtool是一款Mac平台上的WiFi网络分析工具&#xff0c;它可以帮助用户监测、分析和管理无线网络。 以下是Airtool的一些主要功能和特点&#xff1a; 实时监测&#xff1a;Airtool可以实时监测当前Mac设备所连接的WiFi网络&#xff0c;包括网络速度、信号强度、连接状态等。信…

Greenplum 对比 Hadoop

Greenplum属于MPP架构&#xff0c;和Hadoop一样都是为了解决大规模数据的并行计算而出现的技术&#xff0c;两者的相似点在于&#xff1a; 分布式存储&#xff0c;数据分布在多个节点服务器上分布式并行计算框架支持横向扩展来提高整体的计算能力和存储容量都支持X86开放集群架…

8、表格标签

8、表格标签 一、为什么使用表格 简单通用结构稳定 二、基本结构 &#xff08;一&#xff09;单元格 &#xff08;二&#xff09;行 行的英语是rows所以&#xff0c;行就用tr表示 &#xff08;三&#xff09;列 使用td表示 &#xff08;四&#xff09;跨行 &#xff…

蓝桥等考Python组别九级002

第一部分:选择题 1、Python L9 (15分) 运行下面程序,可以输出几行“*”?( ) for i in range(5): for j in range(6): print(*, end = ) print() 3456正确答案:C 2、Python L

Spark SQL

Spark SQL 一、Spark SQL概述二、准备Spark SQL的编程环境三、Spark SQL程序编程的入口四、DataFrame的创建五、DataFrame的编程风格六、DataSet的创建和使用七、Spark SQL的函数操作 一、Spark SQL概述 Spark SQL属于Spark计算框架的一部分&#xff0c;是专门负责结构化数据的…

运算符 - Go语言从入门到实战

运算符 - Go语言从入门到实战 算术运算符 假设A变量等于10&#xff0c;B变量等于20。 运算符描述实例相加A B 输出结果 30-相减A - B 输出结果 -10*相乘A * B 输出结果 200/相除B / A 输出结果 2%求余B % A 输出结果 0⾃增A 输出结果 11–⾃减A-- 输出结果 9 特性&#xf…

NIO基础

nio : non-blocking io 非阻塞IO 1. 三大组件 1.1 channel和buffer channel 有点像stream &#xff0c;他就是读写数据的双向通道&#xff0c;可以从channel将数据读入buffer&#xff0c;也可以将buffer的数据写入channel&#xff0c;之前的stream 要么输入&#xff0c;要么…