离散实验 判断集合之间是单射,满射还是双射

离散实验 判断集合之间是单射,满射还是双射通过C++实现集合间映射关系判断思路:创建判断两个集合之间是否是单射,满射,双射的函数,同时也分别创建三个函数,里面存放两集合间的映射关系,再通过刚刚创建的判断函数,进行验证是否满足条件。涉及的数学知识1.单射:设f是由集合A到集合B的映射,如果所有x,y∈A,且x≠y,都有f(x)≠f(y),则称f为由A到B的单射。2.满射:如果每个可能的像至少有一个变量映射其上(即像集合B中的每个元素在A中都有一个或一个以上的原像),或者说值域任何元素都有至少有一个变量与之对应,那这个映射就叫做满射。3.双

大家好,又见面了,我是你们的朋友全栈君。

通过C++实现集合间映射关系判断

思路:
创建判断两个集合之间是否是单射,满射,双射的函数,同时也分别创建三个函数,里面存放两集合间的映射关系,再通过刚刚创建的判断函数,进行验证是否满足条件。

涉及的数学知识

1.单射:设f是由集合A到集合B的映射,如果所有x,y∈A,且x≠y,都有f(x)≠f(y),则称f为由A到B的单射。
2.满射:如果每个可能的像至少有一个变量映射其上(即像集合B中的每个元素在A中都有一个或一个以上的原像),或者说值域任何元素都有至少有一个变量与之对应,那这个映射就叫做满射。
3.双射:既是单射又是满射的映射称为双射,亦称“一一映射”。

插入相应集合

思路:大体一致以单射举例
vector<int> srcvector<int> dst作为参数传进我们创建的map<int, int> BuildInjection
我们创建一个新的map<int, int> injection;函数用来存放两个集合间的映射关系。
由单射定义可以知道,当我们的x中的元素大于y中的元素时一定不满足我们的单射,然后我们按照x中的元素个数进行遍历将y中的元素与之对应,这个我们使用到pair<int,int> p(src[i],dst[i]);pair是将2个数据组合成一组数据,当需要这样的需求时就可以使用pair,其中我们的map就是将key和value放在一起来保存。我们将pair里面的数据插入到map中来,进行保存,方便我们下一次在判断是否为单射的时候使用

/* BuildInjection 功能:构造集合src到集合dst的单射,将建立的映射保存在返回值injection中 例如,将src中的元素1映射为dst中的元素3,则injection[1] = 3 */
map<int, int> BuildInjection(vector<int> src, vector<int> dst)
{ 

map<int, int> injection;
if(src.size()>dst.size()){ 

cout<<"不能创建单射"<<endl;
}else{ 

for(int i=0;i<src.size();i++){ 

pair<int,int> p(src[i],dst[i]);
injection.insert(p);
}
}
return injection;
}
/* BuildSurjection 功能:构造集合src到集合dst的满射,将建立的映射保存在返回值surjection中 */
map<int, int> BuildSurjection(vector<int> src, vector<int> dst)
{ 

map<int, int> surjection;
if(src.size()<dst.size()){ 

cout<<"不能创建满射"<<endl;
}else{ 

for(int i=0;i<src.size();i++){ 

pair<int,int> p(src[i],dst[i%dst.size()]);
surjection.insert(p);
}
}
return surjection;
}
/* BuildBijection 功能:构造集合src到集合dst的双射,将建立的映射保存在返回值bijection中 */
map<int, int> BuildBijection(vector <int> src, vector<int> dst)
{ 

map<int, int> bijection;
if(src.size()!=dst.size()){ 

cout<<"不能创建双射"<<endl;
}else{ 

for(int i=0;i<src.size();i++){ 

bijection[src[i]]=dst[i];
}
}
return bijection;
}

1.1 判断是否是单射

思路:
在判断一组映射关系是否是单射时,我们主要去判断x中的元素在y中都有与之对应的,而且一个x对应一个y,主要采用的还是一种标记的思想,在传入进来的y中进行遍历,让y中的元素全部标记为1,我们再在那段映射关系中进行遍历,如果说有不等于1的就证明在这段映射关系中,有不是y中的元素,所以我们可以让他返回一个false;同时要注意的是即使y存在在这段映射关系中,也不能直接就判断这个映射是单射,因为其中有两个x对应同一个y的情况,所以我们可以通过一个计数的思想将这段映射关系中符合y中标记为1的自加,如果我们自加的个数>1就说明其中存在两个x对应同一个y,我们也让其返回false,反之,返回true
:在我们去判断自加数是否>1的时候,我们应该在我们创建的那个flag中及逆行遍历
:由于我们是写了一个变量通过改变这个变量的值进行改变这个函数的返回值的,所以要在我们发现自加数>1存在就让其停止循环,加上break

/* ValidateInjection 功能:验证给定的两个集合src和dst之间的映射injection是否为单射。 如果是单射则返回true,不是单射返回false */
bool ValidateInjection(vector<int> src, vector<int> dst, map<int, int> injection)
{ 

bool bIsInjection = false;
map<int,int>mp,flag; 
map<int,int>::iterator it=injection.begin();
if(injection.size()<src.size()){ 

return false;
} else{ 

for(int i=0;i<dst.size();i++){ 

mp[dst[i]]=1; flag[dst[i]]=0;
}
for(;it!=injection.end();it++){ 

if(	!mp[it->second]) bIsInjection = false;
flag[it->second]++;
}
}
for(it=flag.begin();it!=flag.end();it++){ 

if(it->second>1) { 

bIsInjection = false;
break;
}else { 

bIsInjection = true;
}
}
return bIsInjection ;
}

1.2判断是否是满射

思路:
在判断一个映射是否是满射时,我们主要去判断每一个x都有y与之对应,同时y中都有x与之对应,采用的还是标记和计数的思想,主要和上面单射的区别就是在于计数,这一块,如果我们自加数要是少于我们y中的元素个数,就证明在我们这个映射关系中有y存在剩余,这不满足满射定义。返回false,否则返回true。

/* ValidateSurjection 功能:验证给定的两个集合src和dst之间的映射surjection是否为满射。 如果是满射则返回true,不是满射返回false */
bool ValidateSurjection(vector<int> src, vector<int> dst, map<int, int> surjection)
{ 

bool bIsSurjection=false;
map<int,int>mp,flag; 
map<int,int>::iterator it= surjection.begin();
for(int i=0;i<dst.size();i++){ 

mp[dst[i]]=1; flag[dst[i]]=0;
}
for(;it!=surjection.end();it++){ 

if(	!mp[it->second])  bIsSurjection = false;
flag[it->second]++;
}
for(it=flag.begin();it!=flag.end();it++){ 

if(it->second<dst.size())  bIsSurjection = false;
bIsSurjection = true;
}
return bIsSurjection;
}

1.3判断是否是双射

思路:
双射:即使单射也是满射,二者同时满足,所以我们可以使用上面我们判断单射和满射的函数及逆行判断是否是双射。

/* ValidateBijection 功能:验证给定的两个集合src和dst之间的映射bijection是否为双射。 如果是双射则返回true,不是满射返回false */
bool ValidateBijection(vector<int> src, vector<int> dst, map<int, int> bijection)
{ 

bool bBiSurjection = false;
if(bijection.size()!=src.size()){ 

return false;
} else{ 

bBiSurjection = (ValidateInjection(src, dst, bijection) && ValidateSurjection(src, dst, bijection));
}
return bBiSurjection;
}

主函数

int main()
{ 

vector<int> setA, setB, setC;
for (int i = 0; i < 10; i++)
setA.push_back(i);
for (int i = 50; i < 70; i++)
setB.push_back(i);
for (int i = 130; i < 140; i++)
setC.push_back(i);
map<int, int>::iterator iter;
map<int, int> injection;
injection = BuildInjection(setA, setB);
for (iter = injection.begin(); iter != injection.end(); iter++)
cout << iter->first << "->" << iter->second << endl;
cout << ValidateInjection(setA, setB, injection) << endl;
system("pause");
map<int, int> surjection;
surjection = BuildSurjection(setB, setA);
for (iter = surjection.begin(); iter != surjection.end(); iter++)
cout << iter->first << "->" << iter->second << endl;
cout << ValidateSurjection(setB, setA, surjection) << endl;
system("pause");
map<int, int> bijection;
bijection = BuildBijection(setA, setC);
for (iter = bijection.begin(); iter != bijection.end(); iter++)
cout << iter->first << "->" << iter->second << endl;
cout << ValidateBijection(setA, setC, bijection) << endl;
system("pause");
return 0;
}

总结

1.此次实验总体上采用的是一种计数和标记的思想,能实现这个想法主要是map函数它有两个参数,一个是key,一个是value值,:key值不能有重复的,有重复的会自动将其删除一个,但是value值可以有重复的,这让标记可以实现。本次计数也是通过创建map函数进行计数的flag[it->second]++;
2.同时注意我们要判断函数的范围即我们要在哪个for循环中进行遍历
3.对pair的元素进行操作的时候,通过first和sencond访问it->second

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/132991.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 系统可用性「建议收藏」

    系统可用性「建议收藏」一个网站、系统的战术包括可用性战术、可修改性战术、性能战术、安全性战术、可测试性战术、易用性战术。质量需求指定了软件的响应,以实现业务目标,战术是影响质量属性响应的设计决策,构架策略是战术的集合,构架

  • java设置content type_Response Content Type设置[通俗易懂]

    java设置content type_Response Content Type设置[通俗易懂]1.常见的contenttype:.aiff=audio/aiff.anv=application/x-anv.asa=text/asa.asf=video/x-ms-asf.asp=text/asp.asx=video/x-ms-asf.au=audio/basic.avi=video/avi.awf=application/vnd.adobe.workfl…

  • elementUI 时间格式化

    elementUI 时间格式化1.html:<el-table-columnprop=”dateTime”:formatter=”dateFormat”label=”日期”></el-table-column>2.vue的methods里面//方法methods:{//时间格式化dateFormat(row,colum…

  • 计算机组成原理期末复习90分以上选择填空大题总考点

    同学,你好!若觉得有用请点赞或关注~以后会发布更多有用的内容。2019-07-24更新:插入了一张“高分喷雾”。20…

  • WebService接口测试

    WebService接口测试WebService的理解WebService就是Web服务的意思,对应的应用层协议为SOAP(相当于HTTP协议),可理解为远程调用技术。 特点:客户端发送的请求主体内容(请求报文)的格式为XML格式接口返回的响应主体内容(响应报文)的格式为XML格式WSDL的介绍就是WebService接口对应的WSDL文件,该文件通过xml格式说明如何调用,可以看作WebService的接口文档(使用说明书…

  • ribbon负载均衡策略有哪几种_负载均衡策略的是

    ribbon负载均衡策略有哪几种_负载均衡策略的是目录1.基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,2.@LoadBalanced1.基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloudAlibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。如图所示:当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略.Ribbon是什么?(Netflix公司提供的负载均衡…

    2022年10月13日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号