(使用C语言详解)求一个集合的全部子集(leetcode编程笔记)

原题链接:子集 (Subsets) - 力扣 (LeetCode)

原码于文章末尾会给出。

本文通过位运算,实现题目要求,之后可能更新其他方法,敬请关注......

题目:

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 :

输入:{1,3,6,9}
输出:[] [1] [3] [1,3] [6] [1,6] [3,6] [1,3,6] [9] [1,9] [3,9] [1,3,9] [6,9] [1,6,9] [3,6,9] [1,3,6,9]

具体步骤如下:
        1. 首先,我们需要了解什么是集合的子集。集合的子集是指原集合中的元素可以任意个数(包括0个或全部)挑选出来组成的集合。
        2. 对于一个有n个元素的集合,它的子集数量为2^n个。因此,我们需要遍历从0到2^n-1的所有数字,每个数字代表一个子集。
        3. 利用位运算,我们可以很容易地得到一个数字表示的子集。例如,数字1的二进制表示为0001,它表示集合中的第一个元素;数字3的二进制表示为0011,它表示集合中的第一个和第三个元素。
        4. 在遍历所有数字后,我们可以得到所有的子集。每个子集都是一个长度为n的数字序列,表示集合中的元素是否包含在当前子集中。
        5. 最后,我们将所有子集输出即可。
这里比较难的点在于,如何通过位运算得到我们想要的结果。

        下面先将我们代码实现功能的主要函数列出来:

void GetSubSet(int* num, int len, int tag) {int tmp;for (int i = 0; i < pow(2, len); i++) {tmp = tag;tag += 1;int is_first = 1;printf("[");for (int j = 0; j < len; j++) {if (tmp & 0x1) {if (is_first) {printf("%d", num[j]);is_first--;}else {printf(",%d", num[j]);}}tmp >>= 1;}printf("] ");}
}
  • 函数GetSubSet接受三个参数
  1. int* num:指向整数数组的指针,该数组包含了要生成子集的元素。
  2. int len:整数数组的长度,即数组中元素的个数。
  3. int tag:用于跟踪当前生成子集的标记,初始时它被设置为0。
  • 初始化

        函数开始时,tag被设置为0,表示空集。

  • 循环遍历所有子集:

        使用一个for循环,循环2^len次,每次循环代表一个子集。


重点来了

  • 位运算:

        在每次循环中,使用tmp变量来暂存tag的值,然后通过tag += 1来计算下一个子集的tag

        这里实际上是在对tag进行二进制位操作,每次循环将tag的最低位设置为1,

        然后通过tmp >>= 1tag右移一位。


关于位运算这里可能理解比较困难,下面我将画图讲解。

        刚开始的时候我们设置了输入集合的元素总个数n,这个n会在GetSubSet函数位运算操作中生成n个二进制位。比如我们设置的n=4,那么我们下面就产生4个二进制位。

        在遍历第一层第一次for循环时,临时变量tmp=0,即4位二进制都为0

0000

        在遍历第一层第二次for循环时,临时变量tmp=1,即4位二进制变为0001

0001

        以此类推......

        此时符合条件tmp & 0x1(意思是:用于检查变量 tmp 的最低位(二进制的第0位)是否为1。)

        is_first用于判断是否是第一次进入到这个for循环。

        在遍历第一层第二次for循环时,临时变量tmp=1,即4位二进制变为0001,相对应的num[j]=子集元素中的第一个元素——1。

        每执行完一次for循环,tmp >>= 1,也就是说tmp=0001会向右移动一位,变为000。

以上就是位运算的原理。


  • 打印子集:在循环内部,使用另一个for循环来遍历数组num中的每个元素。如果当前tag的二进制表示中的第j位是1,说明元素num[j]应该被包含在子集中。如果这是子集列表中的第一个元素,则直接打印,否则打印逗号和元素。
  • 递归调用:虽然这段代码中没有递归调用,但这个思想可以用来生成子集树,每个子集都可以作为下一个子集的父集。

        这个算法的关键在于理解如何使用二进制数来表示和生成子集。每个子集都可以通过改变tag的某一位来得到下一个子集。当tag的某一位被设置为1时,表示对应数组元素被包含在子集中;当该位被设置为0时,表示对应元素不被包含。通过这种方式,我们可以遍历所有可能的子集。

实现代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>#define MAX_SIZE 100void GetSubSet(int* num, int len, int tag);int main() {int len;int num[MAX_SIZE];while (scanf("%d", &len) && len != 0) {for (int i = 0; i < len; i++) {scanf("%d", num + i);}GetSubSet(num, len, 0);printf("\n");}return 0;
}void GetSubSet(int* num, int len, int tag) {int tmp;for (int i = 0; i < pow(2, len); i++) {tmp = tag;tag += 1;int is_first = 1;printf("[");for (int j = 0; j < len; j++) {if (tmp & 0x1) {if (is_first) {printf("%d", num[j]);is_first--;}else {printf(",%d", num[j]);}}tmp >>= 1;}printf("] ");}
}

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

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

相关文章

C++类的6个默认成员函数(构造)

C类和对象基础-CSDN博客https://blog.csdn.net/lh11223326/article/details/136834917?spm1001.2014.3001.5501 目录 1.构造函数 概念 特性 2.析构函数 概念 特性 3.拷贝构造函数 概念 特征 4.赋值运算符重载&#xff08;构造实现&#xff09; 运算符重载 赋值运算…

Kafka快速入门及使用

入门 官网 简介 Kafka是一个分布式的流媒体平台应用&#xff1a; 消息系统日志收集用户行为追踪流式处理 特点 高吞吐量消息持久化高可靠性高扩展性 常用术语 Broker&#xff1a;集群中的服务器Zookeeper&#xff1a;服务管理Topic&#xff1a;主题&#xff0c;Kafka发…

Linux/openEuler系统部署spring boot+vue前后端分离项目(nginx均衡代理)

Linux/openEuler系统部署spring bootvue前后端分离项目&#xff08;nginx均衡代理&#xff09; 1、系统环境准备&#xff0c;安装openjdk和nginx还有MySQL&#xff0c;咱们本文先连接主机mysql进行登录&#xff08;linux上的mysql服务可以先不安装&#xff09; 可以看我前面的…

springboot精品源码

springboot精品源码 所有项目都包括&#xff1a;源码数据库文件开题LW说明文档运行视频 请看主页资料联系。 项目类型包括: 1 SpringBoot学生心理咨询评估系统 2 基于SpringBoot的网上订餐系统 3 大学生租房平台的设计与实现 4 SpringBoot房屋租赁系统 5 基于SpringBoot的课…

SpringCloud之网关组件Gateway学习

SpringCloud之网关组件Gateway学习 GateWay简介 Spring Cloud Gateway是Spring Cloud的⼀个全新项目&#xff0c;目标是取代Netflix Zuul&#xff0c;它基于Spring5.0SpringBoot2.0WebFlux&#xff08;基于高性能的Reactor模式响应式通信框架Netty&#xff0c;异步⾮阻塞模型…

STM32---DHT11温湿度传感器与BH1750FVI光照传感器(HAL库、含源码)

写在前面&#xff1a;本节我们学习使用两个常见的传感器模块&#xff0c;分别为DHT11温湿度传感器以及BH1750FVI光照传感器,这两种传感器在对于环境监测中具有十分重要的作用&#xff0c;因为其使用简单方便&#xff0c;所以经常被用于STM32的项目之中。今天将使用分享给大家&a…

QGIS编译(跨平台编译)057:FastCGI编译(Windows、Linux、MacOS环境下编译)

文章目录 1、FastCGI介绍2、FastCGI下载3、Windows下编译4、linux下编译5、MacOS下编译1、FastCGI介绍 FCGI 是 FastCGI 的缩写,是一种用于改善 CGI(Common Gateway Interface)性能的协议。在传统的 CGI 中,每次请求都需要启动一个新的进程来处理,这导致了较高的资源消耗和…

【测试思考】设计测试用例时,你在想什么

突然想写这篇文章是因为&#xff0c;前两天看到一篇文章【像用户一样测试】 然后想起事儿 .. 想到在2020年上海爆发疫情后&#xff0c;开始频繁使用买菜软件&#xff0c;在一个深夜从某团紧急挑选加购商品&#xff0c;看到提醒自己账户还有一张满减优惠券&#xff0c;挺高兴的…

claude3国内怎么用

你是否苦恼没有渠道接触最牛的AI——Claude3&#xff0c;这个已经被媒体刷屏的彻底吊打了ChatGPT-4的地表最强AI。 最近&#xff0c;一个国内的claude3镜像站出现了&#xff0c;国内的小伙伴也可以体验了。 无论你用它写文案、做PPT、写代码、调bug、还是画图&#xff0c;都不…

【Linux】调试器-gdb的安装与使用

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 GDB的安装 在开始之前&#xff0c;确保已经安装了GDB。如果没有安…

Android 观察者模式

在Android中&#xff0c;观察者模式&#xff08;Observer Pattern&#xff09;是一种常用的设计模式&#xff0c;用于在对象之间建立一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。在Android开发中&#xff0…

HTML5和CSS3笔记

一&#xff1a;网页结构(html)&#xff1a; 1.1&#xff1a;页面结构&#xff1a; 1.2&#xff1a;标签类型&#xff1a; 1.2.1&#xff1a;块标签&#xff1a; 1.2.2&#xff1a;行内标签&#xff1a; 1.2.3&#xff1a;行内块标签&#xff1a; 1.2.4&#xff1a;块标签与行…

独孤思维:流量暴涨,却惨遭违规

最近独孤操作虚拟资料短视频&#xff0c;有个很深的感悟。 每天发10条短视频&#xff0c;积累到20天左右&#xff0c;播放量和粉丝数开始暴涨。 虽然很多牛比的比我数据好&#xff0c;但是对于刚做短视频的独孤来说&#xff0c;我已经满足了。 但是又发了10来天&#xff0c;…

如何用VSCode和Clangd与Clang-Format插件高效阅读Linux内核源码及写驱动

一、如何高效阅读Linux源码&#xff1a;基于clangd uboot/busybox等都可以用这种方式&#xff0c;理论上说所有基于Make和Cmake的源码工程都可以用这套方案 阅读Linux源码最大问题在于调用链太复杂&#xff0c;一个函数或变量引用太多&#xff0c;source insight和cscope等基于…

Pink老师Echarts教学笔记

可视化面板介绍 ​ 应对现在数据可视化的趋势&#xff0c;越来越多企业需要在很多场景(营销数据&#xff0c;生产数据&#xff0c;用户数据)下使用&#xff0c;可视化图表来展示体现数据&#xff0c;让数据更加直观&#xff0c;数据特点更加突出。 01-使用技术 完成该项目需…

阿里云服务器(Ubuntu22)上的MySQL8数据库下载,安装和远程连接

最近阿里云centos主机到期了改为使用Ubuntu操作系统&#xff0c;在上面安装mysql并远程连接出现了一系列问题并解决。 之前在centos系统上下载mysql8的教程如下&#xff1a; 阿里云服务器&#xff08;centos7&#xff09;上的MySQL8数据库下载&#xff0c;安装和远程连接 主机操…

rollup打包起手式

使用Rollup打包JavaScript rollup是一款小巧的javascript模块打包工具&#xff0c;更适合于库应用的构建工具;可以将小块代码编译成大块复杂的代码&#xff0c;基于ES6 modules,它可以让你的 bundle 最小化&#xff0c;有效减少文件请求大小,vue在开发的时候用的是webpack,但是…

【小沐学Python】Python实现Web图表功能(Lux)

文章目录 1、简介2、安装3、测试3.1 入门示例3.2 入门示例2 结语 1、简介 https://github.com/lux-org/lux 用于智能可视化发现的 Python API Lux 是一个 Python 库&#xff0c;通过自动化可视化和数据分析过程来促进快速简便的数据探索。通过简单地在 Jupyter 笔记本中打印出…

招聘自媒体编辑岗位的人才测评方案

人才测评工具在招聘入职的方案&#xff0c;在线工具网根据自媒体岗位的特性和需求来分析&#xff0c;并制定自媒体主编的测评方案。 自媒体作为互联网时代的产物&#xff0c;自然也为我们带来了很多的福利&#xff0c;例如&#xff1a;海量的信息、快捷的传媒方式&#xff0c;那…

百度网盘联盟申请盘主的方法

在百度网盘联盟目前有3种赚钱方式&#xff0c;第一种是自己售卡赚佣金&#xff1b;第二种是外链分享&#xff08;分销联盟&#xff09;&#xff1b;第三种是邀请好友加盟&#xff0c;好友售卡&#xff0c;自己得提成收入&#xff0c;需要申请盘主后即可开始 申请盘主&#xff1…