精华内容
下载资源
问答
  • 交且与差
    千次阅读
    2022-03-08 11:34:37

    ClickHouse 实现数组交并差计算

    计算数组交集

    函数:arrayIntersect(arr1,arr2,...)
    功能说明:计算 arr1,arr2等数组元素交集。
    返回值:交集元素子数组。
    SQL 实例:

    SELECT
        arrayIntersect([1, 2, 3], [4, 5, 6]) AS noIntersect,
        arrayIntersect([1, 2, 3], [2, 3, 4, 5, 6]) AS hasIntersect
    FORMAT Vertical

    输出:
    noIntersect: []
    hasIntersect: [3,2]

    计算数组并集

    组合使用函数来实现arrayDistinct(arrayConcat(a, b))。
    SQL 实例:

    SELECT
        [1, 2] AS a,
        [2, 3] AS b,
        arrayDistinct(arrayConcat(a, b)) AS res
    FORMAT Vertical

    输出:
    a: [1,2]
    b: [2,3]
    res: [1,2,3]

    计算数组差集

    差集的实现要有一些技术含量了(感觉 ClickHouse 后面应该内置数组差集计算函数,实现类似arrayExcept() 函数),需要使用数组交集函数arrayIntersect() 结合高阶函数 arrayMap()和 arrayFilter()来组合实现。
    SQL 实例:

    SELECT
        arrayIntersect([1, 2, 3], [4, 5, 6]) AS noIntersect,
        arrayIntersect([1, 2, 3], [2, 3, 4, 5, 6]) AS hasIntersect
    FORMAT Vertical
    SELECT
        [1, 2] AS a,
        [2, 3] AS b,
        arrayFilter(x -> (x IS NOT NULL), arrayMap(x -> multiIf(x NOT IN arrayIntersect(a, b), x, NULL), a)) AS res
    FORMAT Vertical

    输出:
    a: [1,2]
    b: [2,3]
    res: [1]

    使用 交(INTERSECT)、并(UNION)、差(EXCEPT)的SQL子句关键字 实现

    另外, ClickHouse 中有集合交(INTERSECT)、并(UNION)、差(EXCEPT)的SQL子句关键字,可以实现数组的交并差运算。实例 SQL 如下。

    交集SQL:

    SELECT a.i
    FROM
    (
        SELECT arrayJoin([1, 2]) AS i
    ) AS a
    INTERSECT
    SELECT b.i
    FROM
    (
        SELECT arrayJoin([2, 3]) AS i
    ) AS b

    输出:2

    并集 SQL:

    SET union_default_mode = 'ALL';
    SELECT DISTINCT t.i
    FROM
    (
        SELECT a.i
        FROM
        (
            SELECT arrayJoin([1, 2]) AS i
        ) AS a
        UNION
        SELECT b.i
        FROM
        (
            SELECT arrayJoin([2, 3]) AS i
        ) AS b
    ) AS t

    输出:
    1
    2
    3

    差集 SQL:

    SELECT a.i
    FROM
    (
        SELECT arrayJoin([1, 2]) AS i
    ) AS a
    EXCEPT
    SELECT b.i
    FROM
    (
        SELECT arrayJoin([2, 3]) AS i
    ) AS b

    输出:1

    上述[1,2]和[2,3]分别表示要求差集的数组

    数据函数解释:
    arrayIntersect表示多个数组求交集
    arrayConcat表示连接多个数组为一个数组
    arrayDistinct表示将多个数组元素去重组合为一个数组
    arrayMap表示使用lambda函数转换
    arrayFilter表示使用lambda函数过滤

    参考资料:

    https://clickhouse.tech/docs/zh/sql-reference/functions/higher-order-functions/

    更多相关内容
  • 课程设计 集合的并、运算 可执行文件+电子版设计报告 1.2 基本要求 (1) 集合的元素限定为小写字母字符 [‘a’..’z’] 。 (2) 演示程序以用户和计算机的对话方式执行。 【测试数据】 (1)Set1="magazine",...
  • danlianbiao.rar_

    2022-09-14 15:48:34
    c编的,数据结构实验报告,很详细.流程都有 是单链表
  • 实现、并、运算时,分别把代码写成函数的形式,即实现运算的函数,实现并运算的函数,实现运算的函数,在主函数中分别调用三个函数。 使用菜单形式对应各个操作,应允许用户反复查看结果,想结束程序时,...
  • 实现集合

    2019-01-30 14:11:42
    运用C++实现的小程序,集合的运算。大一时候的一个小课设。可以运行,有exe
  • 链表实现集合运算 链表实现集合运算
  • exp2-6.rar_集合

    2022-09-22 17:51:38
    编写程序 采用单链表表示集合,并实现两个集合的并、
  • 题目 集合的并运算 问题描述 编制一个能演示执行集合的并运算的程序 基本要求 (1) 集合的元素限定为小写字母字符 [, a. ?z?] (2) 演示程序以用户和计算机的对话方式执行 测试数据 (1)Set1="magazine" ...
  • 含并、运算的集合类型试验报告,这个报告是做计算机试验的标准样式,分为了7个模块。
  • 集合运算 求两个集合的、排序、删除相同字符等
  • 一集合的并运算 1.问题描述 编制一个能演示执行集合的并运算的程序 要求 集合的元素限定为小写字母字符[a.z] 演示程序以用户和计算机的对话方式执行 实现提示以链表表示集合 选作内容 集合的元素判定和...
  • 实用文案 问题描述 编制一个能演示执行集合的并运算的程序 基本要求 1 集合的元素限定为小写字母字符 [ 'a'z' ] 2 演示程序以用户和计算机对话的方式执行 测试数据 实现提示 以有序链表表示集合 代码过程 1先...
  • 编制一个能演示执行集合的并、运算的程序。 (1)设计集合的并、运算函数(集合的元素不能重复) (2)编制测试函数测试集合运算 (3)提示:以有序链表表示集合
  • 数据结构(C语言版)实验报告-集合的.docx数据结构(C语言版)实验报告-集合的.docx数据结构(C语言版)实验报告-集合的.docx数据结构(C语言版)实验报告-集合的.docx数据结构(C语言版)实验报告-...
  • 数据结构(C语言版)实验报告-集合的.pdf数据结构(C语言版)实验报告-集合的.pdf数据结构(C语言版)实验报告-集合的.pdf数据结构(C语言版)实验报告-集合的.pdf数据结构(C语言版)实验报告-集合的...
  • 封闭多边形的并、运算,李旭健,韩丛英,提出了一种基于交点的凹凸性求封闭多边形的并、的算法。首先给出了环、并、、凹凸点的定义;然后描述了算法。该算法
  • 集合的运算.exe

    2021-12-11 11:56:31
    集合的运算.exe
  • 大二上学期老师要求做的作业,用java实现集合之间的
  • 实习报告 题目编制一个演示集合的并运算的程序 班级 95001 姓名 张三 学号9500101完成日期 2008-6-16 一需求分析 1. 本程序中集合的元素限定为小写字母字符 ['a'z']集合的大小n集合输入的形式为一个以"回车符...
  • 1、并:设有两个关系R和S,它们具有相同的结构。R和S的并是由属于R或属于S的元组组成的集合,运算符为∪。...并、属于关系的基本运算中的传统的集合运算,除此以外关系基本运算的另一类是专门的关...

    1、并:设有两个关系R和S,它们具有相同的结构。R和S的并是由属于R或属于S的元组组成的集合,运算符为∪。记为T=R∪S。

    2、差:R和S的差是由属于R但不属于S的元组组成的集合,运算符为-。记为T=R-S。

    3、交:R和S的交是由既属于R又属于S的元组组成的集合,运算符为∩。记为T=R∩S。R∩S=R-(R-S)。

    并、差、交属于关系的基本运算中的传统的集合运算,除此以外关系基本运算的另一类是专门的关系运算(选择、投影、联接等),有些查询需要几个基本运算的组合,要经过若干步骤才能完成。

    5975b3719e878f7c168ab62de25620af.png

    扩展资料:

    在关系代数运算中,有5种基本运算,它们是并(U)、差(—)、投影、选择、笛卡尔积(X),其它运算即交、连接和除,均可通过5种基本的运算来表达。

    选择运算:

    从关系中找出满足给定条件的那些元组称为选择。其中的条件是以逻辑表达式给出的,值为真的元组将被选取。这种运算是从水平方向抽取元组。在FOXPRO中的短语FOR和WHILE均相当于选择运算。

    如:LISTFOR出版单位='高等教育出版社'AND单价<=20

    投影运算:

    从关系模式中挑选若干属性组成新的关系称为投影。这是从列的角度进行的运算,相当于对关系进行垂直分解。在FOXPRO中短语FIELDS相当于投影运算。如:LISTFIELDS单位,姓名

    选择和投影运算都是属于一目运算,它们的操作对象只是一个关系。

    连接运算属于二目运算,是从两个关系元组的所有组合中选取满足一定条件的元组,由这些元组形成连接运算的结果关系,其中条件表达式涉及到两个关系中属性的比较,该表达式的取值为真或假。

    参考资料:百度百科-基本运算

    展开全文
  • 实现集合之间的 并 补 对称

    千次阅读 2021-04-01 12:37:44
    通过使用c++的类 ,容器等相关知识来实现集合间的: 并 补 对称这五种关系 这里不直接set中有关集合关系的函数 相关数学知识 并集:设AB是任意两个集合,由至少属于集合A集合B之一的一切元素构成的集合...

    题目

    通过使用c++的类 ,重载,vector容器等相关知识来实现集合间的:交 并 补 差 对称差这五种关系
    这里不直接set使用有关集合关系的函数

    相关数学知识

    并集:设A与B是任意两个集合,由至少属于集合A与集合B之一的一切元素构成的集合成为A与B的并集,记作A∪B(或B∪A),读作“A并B”(或“B并A”),即A∪B={x|x∈A,或x∈B}。

    交集:对于给定的两个集合A 和 集合B 的交集是指含有所有既属于 A 又属于 B 的元素所构成的集合。由属于A且属于B的相同元素组成的集合,记作A∩B(或B∩A)读作“A交B”(或“B交A”),即A∩B={x|x∈A,且x∈B}。

    差集:设A与B是任意两个集合,由属于A但不属于B的一切元数构成的集合称为A与B的差集,记为A\B或A-B,即A\B={x|x∈A且x∉B}。

    补集:设S是一个集合,A是S的一个真子集,由S中所有不属于A的元素组成的集合,叫做子集A在S中的补集,于集也称为补集,记作CsA或Ac或A’。即Ac=S\A。

    对称差:两个集合的对称差是只属于其中一个集合,而不属于另一个集合的元素组成的集合。设A与B是任意两个集合,集合 A 和 B 的对称差可记为 AΔB,对称差相当于两个相对补集的并集,即AΔB=(A-B)∪(B-A)。也可以表示为两个集合的并集减去它们的交集,即AΔB=(A∪B)-(B∩A)。

    功能实现

    通过创建两个类,一个学生类,一个学生集合类,分别代表元素和集合,将学生类里面的数据放在一个vector的容器中可以在学生集合类里进行储存及使用。

    头文件以及实现

    学生类

    创建一个学生类

    class Student
    {
    private:
    	int m_uiId;
    public:
    	Student();
    	Student(int id);
    	Student(const Student& student);
    	Student& operator=(const Student& student);
    	bool operator==(const Student& student) const;
    	bool operator!=(const Student& student) const;
    	int GetID() const { return m_uiId; }
    };
    

    学生类实现

    默认构造:为其赋初值,在使用rand () 函数在使用时是已经固定的值,所以创建一个随机种子来改变其值,同时用srand(time(NULL))实现随机种子,根据时间变化而产生学号,这个可以避免学号创建出来是一样的情况

    Student::Student(){
    	srand((unsigned int)time(NULL));
     	m_uiId = rand() % 20 + 1;
    }
    

    随机产生学生学号范围在1-20之间

     rand() % 20 + 1;
    

    有参构造
    实现参数id保证传入的参数的准确性

    Student::Student(int id){
      m_uiId=id;
    }
    

    拷贝构造函数
    传入进来的是一个对象,通过引用的方式进行传入,并的将传进来的对象的m_uiId赋值给本身的m_uiId进而来实现拷贝效果

    Student::Student(const Student & student){
      m_uiId=student.m_uiId;
    }
    

    重载赋值运算符
    这个重载赋值和拷贝函数很像,在返回值上有区别,要实现一个链式编程的思想,为了将重载赋值运算符可以链式的使用下去,所以我们需要将其返回一个指针的形式

    Student &Student::operator=(const Student &student){
       m_uiId=student.m_uiId;
       return *this;
    }
    

    重载关系运算符
    是一个bool类型的函数,判断是否相等,相等则返回true,否则返回false类型

    bool Student::operator==(const Student &student)const{
         if(student.m_uiId==m_uiId) return true;
         return false;
    }
    bool Student::operator!=(const Student &student)const{
         if(student.m_uiId!=m_uiId) return true;
         return false;
    }
    

    学生集合类

    接着创建 学生集合类 在学生集合类里面实现相应函数
    我们创建一个Student类型的容器去存放数据

    在创建学生集合类时使用了vector容器,需要加入头文件#include<vector>

    class StudentSet
    {
    private:
    	vector<Student>m_vecData;
    public:
    	StudentSet();
    	StudentSet(const StudentSet&studentset);
    	StudentSet& operator=(const StudentSet&studentset);
    	bool Insert(const Student student);
    	bool Remove(const int id);
    	StudentSet Union(const StudentSet&studentset) const;
    	StudentSet InterSect(const StudentSet&studentset) const;
    	StudentSet Difference(const StudentSet&studentset) const;
    	StudentSet Complement() const;
    	StudentSet SymDifference(const StudentSet&studentset) const;
    	bool IsEmpty() const;
    	void Clear();
    	void Output() const;
    };
    

    学生集合类实现

    学生集合类的三个构造函数和学生类的一样,在学生集合类中,默认构造函数让其清空
    注意在重载赋值函数中,要清空函数,否则会保留上一次的数据

    StudentSet::StudentSet(){
       m_vecData.clear();
    }
    StudentSet::StudentSet(const StudentSet &studentset){
       int len=studentset.m_vecData.size();
       for(int i=0;i<len;i++){
        m_vecData.push_back(studentset.m_vecData[i]);
       }
    }
    StudentSet& StudentSet::operator=(const StudentSet & studentset){
    	m_vecData.clear();//清空防止在下一次的使用时仍含有上一次的值
       int len=studentset.m_vecData.size();
       for(int i=0;i<len;i++){
        m_vecData.push_back(studentset.m_vecData[i]);
       }
       return *this;
    }
    
    

    插入和删除函数,是bool类型的函数,需要判断该集合中是否有与我们插入的id重复,如果有,则返回false,没有则返回true,同理删除函数一样
    插入和删除都用到了vector容器里面的push_back函数和erase函数

    判断是否有重复的思路
    所使用的方法:我使用了map容器,通过map容器的两个参数值key和value,是键值对,他们之间有着一一对应的关系,同时在map容器中key 值是没有重复的。将m_vecData[i].GetID()全标记为1,此时m_vecData[i].GetID()就相当于map容器里的key值,标记的1就是相当于value值,这样在通过判断传进来的id的value值是否是1,如果是1,代表有重复的,之没有,没有重复的我们将其插入并返回true。

    删除函数:就是在本身的范围内开始遍历,如果有和传入的id相同的,记录一下当前的遍历的位置,使用m_vecData.erase(m_vecData.begin()+i);的方法删除重复的那个

    注:m_vecData[i].GetID()==id的要注意私有成员函数只能由该类内部成员函数调用

    bool StudentSet::Insert(const Student student){//插入
    	int len =m_vecData.size();
    	map<int ,int >mp;
    	
    	for(int i=0;i<len;i++){
    		mp[m_vecData[i].GetID()]=1;
    	}
    	if(!mp[student.GetID()]){
    		m_vecData.push_back(student);
         	return true;
    	}else {
    		return false;
    	}
    }
    bool StudentSet::Remove(const int id){//删除
         int len=m_vecData.size();
         for(int i=0;i<len;i++){
         if(m_vecData[i].GetID()==id){   ///私有成员函数只能被该类内部成员函数调用
             m_vecData.erase(m_vecData.begin()+i);
             return true;
            }
         }
         return false;
    }
    

    并 交 差 补 对称差

    实现方式和插入函数的逻辑类似都是通过map函数的key值和value值进行判断的

    并集:在本身这个集合内进行遍历将其全部插入到我们创建的的新的集合st里面,并且我们将map函数的key值为那个本身的学号,并将其的value值标记为1
    int len=m_vecData.size(); for(int i=0;i<len;i++){ st.Insert(m_vecData[i]); mp[m_vecData[i].GetID()]=1; }再在传入进来的集合中进行遍历,如果在这个传入的集合中的id(key值)没有等于1的(value值),就意味着传入集合中的元素和我们本身的元素之间没有重复的,那么我们就将其插入进来 ,这样就可以得到我们这个并集了,

    
    StudentSet StudentSet::Union(const StudentSet&studentset) const{//并集
         StudentSet st;
         map<int,int>mp;
         int len=m_vecData.size();
         for(int i=0;i<len;i++){
            st.Insert(m_vecData[i]);
            mp[m_vecData[i].GetID()]=1;
         }
         len=studentset.m_vecData.size();
         for(int i=0;i<len;i++){
            if(!mp[studentset.m_vecData[i].GetID()]){
                st.Insert(studentset.m_vecData[i]);
            }
         }
         return st;
    }
    

    交集: 同样在本身这个集合中进行遍历并将其标记为1,,然后在传入的集合中进行遍历,如果有一样被标记为1的我们就将其插入到我们所新建的那个集合中

    StudentSet StudentSet::InterSect(const StudentSet&studentset) const{//交集
         StudentSet st;
         map<int,int>mp;
         for(int i=0;i<m_vecData.size();i++) {
         	mp[m_vecData[i].GetID()]=1;
    	 }
         for(int i=0;i<studentset.m_vecData.size();i++){
            if(mp[studentset.m_vecData[i].GetID()]) {
            	st.m_vecData.push_back(studentset.m_vecData[i]);
    		}
         }
         return st;
    }
    
    

    差集:在一个集合中把含有另一个集合的元素去除,我们这里是如果没有一样的元素我就插入进来
    在传入的集合中进行遍历并将其标记为1,再在本身这个集合中进行遍历,如果这里面没有等于1的我们就将其插入到我们创建的新的集合中来

    StudentSet StudentSet::Difference(const StudentSet&studentset) const{//差集
         StudentSet st;
         map<int,int>mp;
         int len=studentset.m_vecData.size();
         for(int i=0;i<len;i++) 
         mp[studentset.m_vecData[i].GetID()]=1;
         len=m_vecData.size();
         for(int i=0;i<len;i++){
            if(!mp[m_vecData[i].GetID()])
    		st.m_vecData.push_back(m_vecData[i]);
         }
         return st;
    }
    

    补集:在全集是:IDMAX是0-20之间,求补集,我们在本身这个集合中遍历,并将其标记为1,再在全集中遍历,如果有不等于1的我们就将其插入到我们创建的新集合中来

    StudentSet StudentSet::Complement() const{//补集
         StudentSet st;
         map<int ,int >mp;
         int len=m_vecData.size();
        for(int i=0;i<len;i++) 
    	mp[m_vecData[i].GetID()]=1;
        for(int i=0;i<=IDMAX;i++){
    		if(!mp[i]){
    			Student a(i);
    			st.m_vecData.push_back(a);
        	}
    	}
         return st;
    }
    

    对称差实际上是两个集合的并集和交集再做一下差集
    实现:创建一个新的集合a存放st和传入参数的并集,集合b存放的是st和传入参数的交集,完了再让a和b做差集,这样我们就得到了对称差

    StudentSet StudentSet::SymDifference(const StudentSet&studentset) const{//对称差
         StudentSet st;
         int len=m_vecData.size();
         for(int i=0;i<len;i++) st.m_vecData.push_back(m_vecData[i]);
         StudentSet a=st.Union(studentset);
         StudentSet b=st.InterSect(studentset);
         StudentSet res=a.Difference(b);
         return res;
    }
    

    判断是否为空,清空函数以及输出函数
    是否为空就是看vector.size()==0是否成立

    bool StudentSet::IsEmpty() const{
         if(m_vecData.size()==0) return true;
         return false;
    }
    void StudentSet::Clear(){
         m_vecData.clear();
    }
    void StudentSet::Output() const{
         int len=m_vecData.size();
         for(int i=0;i<len;i++)
    		cout<<m_vecData[i].GetID()<<endl;
    }
    

    主函数

    int main()
    {
    	srand((unsigned int)time(NULL));
    	StudentSet set1, set2, set3;
    	set1.Clear();
    	set2.Clear();
    	set3.Clear();
    	for (unsigned int i = 0; i < 5; i++)
    	{
    		Student tmpstudent(i);
    		set1.Insert(tmpstudent);
    	}
    	set1.Output(); 
    	system("pause");
    	Student tmpstudent1(3);
    	cout << set1.Insert(tmpstudent1) << endl;
    	system("pause");
    	Student tmpstudent2(10);
    	cout << set1.Insert(tmpstudent2) << endl;
    	system("pause");
    	for (unsigned int i = 7; i < 12; i++)
    	{
    		Student tmpstudent(i);
    		set2.Insert(tmpstudent);
    	}
    	set2.Output();
    	system("pause");
    	set3 = set1.Union(set2);
    	set3.Output();
    	system("pause");
    	set3 = set1.InterSect(set2);
    	set3.Output();
    	system("pause");
    	set3 = set1.Difference(set2);
    	set3.Output();
    	system("pause");
    	set3 = set3.Complement();
    	set3.Output();
    	system("pause");
    	set3 = set1.SymDifference(set2);
    	set3.Output();
    	system("pause");
    	return 0;
    }
    

    总结

    这个实验中主要使用的就是vector容器 插入、删除、清空、容量等一系列函数,运算符重载,以及map函数间的key值和value值之间的一一对应关系,以及我们对集合之间关系的掌握与理解.

    注意注意
    map里面有一种插入方法:(这里所有map的插入方式全都是这种)

    map<int ,int>mp;
    mp[1]=10;//key=1;value=10,
    

    map中输出元素:如果是输出该容器内含有的元素,可以正常输出其value值,但是如果输出其中没有的,不会进行报错,会输出是0

    展开全文
  • 数据结构试验报告-集合的.doc
  • 数据结构课程设计 集合的运算 编 号730 拉桂宅孑科弑火遂 GUILIN UNIVERSITY OF ELECTRONIC TECHNOLOGY 数据结构算法课程设计 说明书 集合的运算 学 院 海洋信息工程学院 专 业 四络工程 学生姓名 xx ...
  • 链表.cpp

    2012-04-17 14:47:06
    链表.cpp 数据结构课程的实验源码
  • 数据结构课程设计-集合的运算.docx
  • 数据结构课程设计报告集合的运算.doc
  • 集合的运算

    2018-11-17 23:14:49
    数据结构中集合的运算,使用C++实现,并且设置了良好的界面
  • 可以对简单多边形实现求并、,复杂多边形之间的并、
  • CAD中封闭区域的并、运算.pdf
  • C++语言集合运算

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 167,989
精华内容 67,195
热门标签
关键字:

交且与差