怎么证明两个集合的并集等于它们的交集?

string 是 redis 中最基础的数据类型, redis 字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你可以存储任何东西,512兆为上限。

SET指令是将字符串值 value 关联到 key 。语法格式:


  
# 对不存在的键进行设置
 
 

  
 

MSET指令可以同时设置一个或多个 key-value 对,如果某个给定 key 已经存在,那么MSET会用新值覆盖原来的旧值,语法格式:

  
 


MSET是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
执行MGET指令,将返回所有(一个或多个)给定 key 的值,语法格式:


  
 
如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。
STRLEN指令将会返回 key 所储存的字符串值的长度,语法格式:

  
 
示例 - 获取say值的长度。

  
 
当 key 储存的不是字符串值时,返回一个错误。
除了前面我们提到的那些常用指令以外,还有很多其他的指令,这些指令只作了解即可,当我们真正用到的时候再来详细了解如何使用它。
设置键的字符串值,并返回旧值。
得到字符串的子字符串存放在一个键。
对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
将 key 中储存的数字值增一。
将 key 所储存的值加上指定增量。
为 key 中所储存的值加上指定浮点数增量。
将 key 中储存的数字值减一。
将 key 所储存的值加上指定增量。

什么是hash? Redis的哈希值是字符串字段和字符串值之间的映射。

相比string等数据类型,它提供很多方便的域操作,因此在表示对象时,它是非常适合的数据类型。

在Redis中的哈希值存储容量也是非常大的,可存储超过400十亿键值对。


  

如果 key 不存在,一个新的哈希表被创建并进行HSET操作。

如果字段 field 已经存在于哈希表中,旧值将被覆盖。

redis 中如何获取key的值呢?HGET是用来获取指定 key 值的命令,语法如下:


  

示例 - 获取字段name的值。


  

除了HSET命令,HMSET命令的用途也是用来设置值,不同的是,HMSET一次可以设置多个 field-value (字段-值)对设置到哈希表 key 中,语法如下:


  

  

如果 key 不存在,将会创建一个空的哈希表并执行HMSET操作。

如果添加的字段已存在哈希表中,那么它将被覆盖。

作为HMSET命令对应的获取命令,HMGET可以一次性获取哈希表 key 中,一个或多个给定域的值,基本语法:


  

  

如果我们想要一次性获取全部域的值,很显然 HGET 和 HMGET 都是不合适的,所幸的是我们还有HGETALL指令,通过它,我们可以轻松的获取到全部域值,基本语法如下:


  

示例 - 获取person全部域的值。


  

在应用环境中,我们经常会需要知道一个 key 中是否存在某个 field ,HEXISTS命令可以帮助我们达到这个目的,基本语法:


  

示例 - 验证键name是否存在。


  

查看哈希表`key 中,给定域 field 是否存在。

如果哈希表含有给定字段,返回 1 。

如果哈希表不含有给定字段,或 key 不存在,返回 0 。

我们经常会遇见这样的应用场景,比如在线用户列表、课堂列表等等,这时候我们可以使用HKEYS来获取哈希表 key 中的所有域,基本语法:


  

示例 - 查看键person中所有的字段。

HLEN命令将返回哈希表 key 中域的数量,什么时候会用到它呢?比如:在线聊天室,显示在线用户数,基本语法:


  

示例 - 查看db键中域的个数。


  

当 key 存在时,将返回哈希表中域的数量。 当 key 不存在时,返回 0 。

有添加就必定有删除的需求,当我们想要删除哈希表 key 中的一个或多个指定域时,可以使用HDEL命令,基本语法:


  

  

如果是不存在的域,那么它将被忽略掉。

Redis 列表是简单的字符串列表,按照插入顺序排序。

你可以添加一个元素导列表的头部(左边)或者尾部(右边) LPUSH 命令插入一个新的元素导头部, 而RPUSH插入一个新元素导尾部.

当一个这两个操作在一个空的Key上被执行的时候一个新的列表被创建。

从时间复杂度的角度来看 Redis 列表的主要特征是在头和尾的元素插入和删除是固定时间,即便是数以百万计的插入。. 在列表的两端访问元素是非常快的但是如果你试着访问一个非常大的列表的中间的元素是很慢的,因为那是一个O(N)操作。 你可以用 Redis 列表做很多有趣的事情,比如你可以:

  • 在一个微博中建立一个时间线模型,使用 LPUSH 去添加新的元素到用户的时间消息列表, 使用 LRANGE 去查找最近插入的元素。

LPUSH的作用是将一个或多个值 value 插入到列表 key 的左边,基本语法:


  

示例:将zpfx添加到朋友列表。


  

如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头,比如说,对空列表 msg 执行命令 LPUSH msg a b c ,列表的值将是 c b a 。

如果 key 不存在,一个空列表会被创建并执行LPUSH操作。

执行成功时,返回列表长度,当 key 存在但不是列表类型时,返回一个错误。

LSET可以将列表 key 下标为index的元素的值设置为 value ,基本语法:


  

  

需要注意的是,列表 key 必须是已存在的,而且index不能超出列表长度范围。

LPOP命令执行时会移除列表第一个元素,并将其返回,基本语法:


  

示例 - 取出friends中的第一个元素。


  

请注意,LPOP命令会移除列表中的元素,如果仅仅是想要获取该元素,那么就不应该使用LPOP操作,因为redis中有专门获取元素的命令。

如果要获取列表元素,LINDEX命令是比较常用的,使用LINDEX,我们可以获取到指定位置的 value ,基本语法:


  

示例 - 获取friends的第一个元素。

下标 (index)为正数时,0表示第一个元素,1表示第二个元素,以此类推。

下标 可以是负数,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

插入元素是一个必要功能,LINSERT可以将值 value 插入到列表 key 当中,位于值 apple 之前或之后,基本语法:


  

  

当 Apple 不存在于列表 key 时,不执行任何操作。

当 key 不存在时, key 被视为空列表,不执行任何操作。

如果 key 不是列表类型,返回一个错误。

在redis中,移除列表元素使用LREM命令,根据参数 count 的值,移除列表中与参数 value 相等的元素,基本语法:


  

  

现在fruits列表中记载着我所有水果的名称,可是要怎样才能知道我现在拥有多少种水果呢?

在redis中,LLEN命令可以获取到列表的长度,基本语法:


  

  

返回列表 key 的长度。

如果 key 不存在,则 key 被解释为一个空列表,返回 0 。

如果 key 不是列表类型,返回一个错误。

LTRIM可以对一个列表进行修剪,就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除,基本语法:


  

示例 - 只保留列表 list 的前三个元素,其余元素全部删除。


  

下标(index)参数start和stop都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。

你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

Redis 集合(Set)是一个无序的字符串集合. 你可以快速的完成添加、删除、以及测试元素是否存在。

Redis 集合多次添加相同的元素,最终在集合里只会有一个元素。 实际上说这些就是意味着在添加元素的时候无须检测元素是否存在。 一个Redis集合的非常有趣的事情是他支持一些服务端的命令从现有的集合出发去进行集合运算, 可以求交集,并集或差集。

  • 使用集合追踪一件(独一无二的)事情,比如想要知道所有访问一个博客文章的独立IP? 每次当你处理一个页面访问时非常简单,因为可以肯定重复的IP是不会被插入的。
  • Redis 集合是很擅长表现关系的。你可以使用Redis集合创建一个标签系统去表现每一个标签。 接下来你能够使用SADD命令将有一个给定tag的所有对象的所有ID添加到一个用来展现这个特定tag的集合里。 你想要同时有三个不同tag的所有对象的ID吗?使用SINTER就好了。
  • 使用 SPOP 或者 SRANDMEMBER 命令你可以使用集合去随意的抽取元素。

集合操作中,SADD命令可以将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略,基本语法:


  

  

假如 key 不存在,则创建一个只包含 member 元素作成员的集合。

当 key 不是集合类型时,返回一个错误。

如果我们需要随机取出集合中的某个元素,可以使用SPOP命令,基本语法:


  

示例:随机取出website集合中的元素。


  

需要注意的是,执行SPOP命令返回的元素将被移除该集合。

如果要获取集合中全部的元素,则需要使用SMEMBERS命令,基本语法如下:


  

示例 - 获取tags集合中全部的元素。


  

SMEMBERS命令只会返回集合中的全部成员,并不会移除它们,如果集合不存在,则视为空集合。

如果想要查看集合中元素的数量,可以使用SCARD命令,基本语法:


  

示例 - 查看tags集合中元素的数量。


  

执行SCARD命令,当集合存在时,返回集合中元素的数量,若集合不存在,则返回0。

假如现在有两个集合,我们想要获取到它们之间不同的元素,通常情况下,我们需要通过循环集合来比较,然后取得不同的元素。

在redis里面取得集合的差集非常简单,通过SDIFF命令即可轻松实现,基本语法:

如果 key 都存在,则返回一个集合的全部成员,该集合是所有给定集合之间的差集。

不存在的 key 被视为空集。

在 redis 中获取集合的交集也是非常简单的,执行SINTER命令将返回集合的交集,基本语法:


  

当集合都存在时,将返回一个集合的全部成员,该集合是所有给定集合的交集。

不存在的集合被视为空集。因此,当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。

既然有差集和交集运算,当然少不了并集,在 redis 中,执行SUNION命令将返回给定集合的并集,基本语法:


  

示例:获取集合tag1和tag2的并集。


  

如果给定的集合都存在,则返回一个集合的全部成员,该集合是所有给定集合的并集。

同样,不存在的集合被视为空集。

如果要判断集合是否包含某个元素也不需要循环对比了,因为 redis 提供SISMEMBER命令可以实现这个功能,基本语法:


  

  

执行SMOVE可以移动元素,基本语法:


  

示例 - 将tag1集合中的歌曲‘a’移动到‘tag2’集合。

如果 source 集合不存在或不包含指定的 member 元素,则SMOVE命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。

执行命令SREM可以将元素从集合中移除,基本语法:


  

示例 - 从tags集合中移除a。


  

移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。

当 key 不是集合类型,返回一个错误。

Redis 有序集合与普通集合非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分,这个评分被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但评分可以重复。

使用有序集合你可以以非常快的速度 添加 、 删除 和 更新 元素。因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。

访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。在有序集合中,你可以很快捷的访问一切你需要的东西:有序的元素,快速的存在性测试,快速访问集合的中间元素! 简而言之使用有序集合你可以做完成许多对性能有极端要求的任务,而那些任务使用其他类型的数据库真的是很难完成的。 使用有序集合你可以:

  • 在一个大型的在线游戏中展示一个排行榜,在那里一旦一个新的分数被提交,你可以使用ZADD命令去更新它.你也可用使用ZRANGE命令来得到顶级的用户,你还可以使用ZRANK命令根据用户名返回该用户在排行榜中的位次。
  • 有序集合常常被用来索引存储在 Redis 中的数据。举个例子,如果你有许多的 哈希 (Hashes)来代表用户,你可以使用一个有序集合,这个集合中的元素的年龄字段被用来当做评分,而ID作为值。因此,使用ZRANGEBYSCORE命令,那是微不足道的并且能够很快的接收到给定年龄段的所有用户。

在redis中,使用ZADD命令将一个或多个 member 元素及其 score 值加入到有序集 key 当中,基本语法:


  

  

如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。

score 值可以是整数值或双精度浮点数。

如果 key 不存在,则创建一个空的有序集并执行ZADD操作。

当 key 存在但不是有序集类型时,返回一个错误。

ZREM命令可以移除指定成员,基本语法如下:


  

  

执行成功,zhangsan元素将从student集合中移除,如果zhangsan不存在,将被忽略。

如果 rank 集合存在但不是有序集类型时,返回一个错误。

redis中使用ZSCORE命令来获取成员评分,基本语法:


  

  

如果想要获取集合成员,可以使用ZRANGE命令,基本语法:


  

示例 - 获取student集合的全部成员。


  

返回的成员的位置按 score 值递增(从小到大)来排序。

如果需要查看集合成员的数量,那么我们需要使用到ZCARD命令,基本语法如下:


  

示例 - 查看student集合的成员数量。


  

执行成功,将返回有序集 student 的成员总数。

除了ZCARD命令以外,ZCOUNT命令也可以查看成员的数量,和前者不同的是,ZCOUNT命令可以设定评分的最小和最大值:


  

示例 - 查看分数在80-90之间的人数。

ZRANK命令可以获取到给定元素在集合中的排名,排名依据 评分(score) 值递增(从小到大)顺序排列,语法格式:


  

排名以 0 为底,也就是说, score 值最小的成员排名为 0 。

使用 ZREVRANK 命令可以获得成员按 score 值递减(从大到小)排列的排名。

ZINCRBY命令可以为给定的成员评分值加上增量,语法格式:


  

  

当 key 不是有序集类型时,返回一个错误。

score 值可以是整数值或双精度浮点数。


  

示例 - 查找包含o的键。


  

特殊符号用 \ 隔开。

EXISTS命令的作用是判断指定key是否存在,语法格式如下:


  

排序是很常见的需求,在 redis 中可以使用SORT命令来实现排序,语法格式如下:

使用SORT命令,可以返回或保存给定列表、集合、有序集合 key 中经过排序的元素。

排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。

为key设置生存时间需要使用EXPIRE命令,语法格式:


  

示例 - 设置rank的过期时间为30秒。


  

为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。

生存时间可以通过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆写(overwrite),这意味着,如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话,那么生存时间不会被改变。


  

示例 - 查看key剩余生存时间。


  

当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。

}

谢谢你朋友,我后来想了好久,想出的思路和你的思路差不多,我要是早点看到你的回答就好啦。 不过我的题意不是“ 集合内的集合两两相交”,而是集合内这些集合有公共的交集。 其实除了集合间的交集关系表,每个集合的元素内容也是已知的,我需要找到所有的划分方式,使得划分出的每个集合堆内的"集合们"有公共的交集,也可以说使得划分出的每个集合堆内的"集合们"有公共的子集。 容易看出,划分为两堆的话,这五个集合最终只有一种划分方式。如果对于其他集合,程序需要判断出所有的划分方式。 ”集合两两相交“不一定代表它们之间有公共集合哦。比如(1,2,3),(3,4,5),(5,1) 不过,解法思路总体还是一样的。首先找出与其他集合的个数最小的那个集合(最短),以这个集合为准,遍历它的子集,看那个子集能求出公共交集,如果能,那么看全集的补集是否有公共交集,如果也能,就是一种划分方式。 比如对于相交关系 1:2,3,6,7 (2,3,6,7分别与1存在交集) 2:1,3,6,4 3:1,2,6,5 4:5,7,2,6 5:4,7,3 6:1,2,3,4 7:4,5,1 找出最短的其中一组 5:4,7,3,它们两个有公共的交集,它们的子集有(5,4),(5,5),(5,7,),(5,3),(5,4,7),(5,4,3),(5,7,3),(,5,4,7,3)…… 判断子集有交集的话,再判断补集合,比如(5,4,7)有公共交集,那么判断一下(1,2,3,6)有没有公共交集。 实际操作的时候,也不需要全部遍历,比如最短的那堆集合是编号为5:4,7,3 这5个集合,如果5,4,7集合没有交集,那么5,4,7,3是不用进行判断的,所以在遍历的时候,可以使用回溯剪枝算法减小运算速度。 你提到的”每个元素集的值要大于划分的个数-1“给我提供了预判断的参考,因为如果两两都没有集合,那更不可能存在公共交集了。加入这个预先的判断也许会提高算法的速度。 我现在正在详细设计这个算法并准备进行代码研究,看看能不能解决我的问题(因为我的问题集合数量比较多,即使使用这种算法减小遍历次数亦可能非常多),希望自己能成功。哈哈。 再此感谢你朋友!

}

我要回帖

更多关于 并集和交集的区别图解 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信