C++代码示例:排列数简单生成工具

news2024/12/23 9:00:35

文章目录

  • 前言
  • 代码仓库
  • 内容
  • 代码(有详细注释)
  • 编译和运行命令
  • 结果
  • 总结
  • 参考资料
  • 作者的话

前言

C++代码示例:排列数简单生成工具。


代码仓库

  • yezhening/Programming-examples: 编程实例 (github.com)
  • Programming-examples: 编程实例 (gitee.com)

内容

  • 简单地生成排列数
  • 有详细的步骤解析

代码(有详细注释)

cpermutation.cpp

#include <vector>
#include <iostream>
#include <unordered_set>

using std::cout;
using std::endl;
using std::unordered_set;
using std::vector;

class CPermutation
{
public:
    CPermutation(const int &n, const int &m) : n(n), m(m), flags(0), curPerm(0), permCount(0) {}

    bool next()
    {
        // 第一次进入初始化当前排列,如m=3,this->curPerm为012,从012开始遍历
        if (this->curPerm.empty() == true)
        {
            for (int i = 0; i < this->m; ++i)
            {
                this->curPerm.push_back(i);
                this->flags.insert(i); // 记录哈希
            }

            ++this->permCount;
            return true;
        }

        // 1. 首先,确定某个位置是否已经达到了当前意义下的“最大值”—“当前” 的意义:前面的位置数值固定之后
        // 求当前位置应当的最大值
        // 注意理解:如014,索引2位置可取23,最大值为3;索引1位置可取234,最大值为4;索引0位置可取1234,最大值为4,左边位置的取值范围要包括右边的位置
        // 从后往前大到小遍历,如果这个数不在哈希表中就是应该的最大值

        // 2. 然后,从后向前寻找第一个不是当前最大值的位置
        // 修正:小于当前应当最大值的位置
        // 如014,则求得的位置是索引1
        int curPos = this->m - 1;
        int curMax = 0;
        while (curPos >= 0)
        {
            // 1.
            for (int i = this->n - 1; i >= 0; --i)
            {
                if (flags.find(i) == flags.end())
                {
                    curMax = i;
                    break; // 找到就退出for
                }
            }

            // 2.
            if (this->curPerm.at(curPos) >= curMax) // 未找到位置移动
            {
                flags.erase(this->curPerm.at(curPos)); // 哈希表减少
                --curPos;
            }
            else // 找到位置退出while
            {
                break;
            }
        }

        if (curPos < 0) // 没找到位置搜完排列
        {
            return false;
        }

        // 3.这个位置上的数值最小限度地增加—“最小限度”,前面的数值排除之后,取剩余的、大于该值的最小值
        // 从前往后小到大遍历,如果这个数不在哈希表中就是应该变换的值
        // 注意:此时可能处理左边的位置,哈希表还是删减状态以让左边位置可以取到右边的值
        // 如014,遍历012到2最小且不在哈希表,将索引1位置元素1换成2,该位置后续可以取到右边的值4,右边的值相应的会减小不再是4保证不重复
        for (int i = this->curPerm.at(curPos); i < this->n; ++i)
        {
            if (flags.find(i) == flags.end())
            {
                this->flags.erase(this->curPerm.at(curPos)); // 哈希删除
                this->curPerm.at(curPos) = i;
                this->flags.insert(i); // 哈希插入
                break;
            }
        }

        // 归位哈希表。因为右边的数要填充了
        // 如034,位置1可以取到4,但此时哈希表是没有4的,将3变为4后,需要加入哈希表,右边的值填充时不能再是4,不是044而是041
        for (const int p : this->curPerm)
        {
            flags.insert(p);
        }

        // 4. 该位置确定后,后面的位置依次取剩余数值的最小几个
        // 对右边的所有位置
        // 从前往后小到大遍历,如果这个数不在哈希表中就是应该变换的值
        // 如024,遍历01到1最小且不在哈希表,
        for (int i = curPos + 1; i < this->m; ++i)
        {
            for (int j = 0; j < this->n; ++j)
            {
                if (flags.find(j) == flags.end())
                {
                    this->flags.erase(this->curPerm.at(i)); // 哈希删除
                    this->curPerm.at(i) = j;
                    this->flags.insert(j); // 哈希插入
                    break;
                }
            }
        }

        ++this->permCount;
        return true;
    }

    inline void printCurPerm()
    {
        for (const int p : this->curPerm)
        {
            cout << p << " ";
        }
        cout << endl;
    }

    inline void printPermCount()
    {
        cout << this->permCount << endl;
    }

private:
    const int n; // 从n个取m个
    const int m;

    vector<int> curPerm;      // 当前排列,存储排列的索引
    unordered_set<int> flags; // 哈希标志,标记已在排列中的索引
    int permCount;            // 排列数的数量
};

int main()
{
    const int n = 5;
    const int m = 3;
    CPermutation perm(n, m);

    while (perm.next())
    {
        perm.printCurPerm();
    }
    perm.printPermCount();

    return 0;
}

编译和运行命令

g++ -o cpermutation cpermutation.cpp
./cpermutation.exe

结果

在这里插入图片描述
在这里插入图片描述


总结

C++代码示例:排列数简单生成工具。


参考资料

  • 学校《高级算法设计与分析》课程课件的算法思路

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

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

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

相关文章

PHP 数码公司运营管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 数码公司运营管理系统系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 php 数码公司运营管理系统 代码 https://download.csdn.net/download/qq_41…

实战教程:如何在API监控中实现高效报警和通知

问题 因一业务需要&#xff0c;想要对API服务接口添加一些监控&#xff0c;以帮助跟踪应用程序的性能、问题和用户活动等。实现监控的方式有多种多样的方式&#xff0c;以下是一些常用的方法&#xff1a; 日志记录&#xff1a; 在应用程序中添加详细的日志记录&#xff0c;包括…

如何开发一个微信小程序

微信小程序是微信公众平台推出的一种全新的应用形态&#xff0c;它具有跨平台、小巧、高效等特点&#xff0c;深受用户喜爱。 一直想学习开发小程序&#xff0c;最近找了一个教程来看&#xff0c;发现原生小程序写起来还是挺简单的&#xff0c;主要分为以下几步。 准备开发环境…

SpringCloud Alibaba - Sentinel 限流规则(案例 + JMeter 测试分析)

目录 一、Sentinel 限流规则 1.1、簇点链路 1.2、流控模式 1.2.1、直接流控模式 1.2.2、关联流控模式 a&#xff09;在 OrderController 中新建两个端点. b&#xff09;在 Sentinel 控制台中对订单查询端点进行流控 c&#xff09;使用 JMeter 进行测试 d&#xff09;分…

C语言 Cortex-A7核 PWM实验

1 实验目的 驱动开发板蜂鸣器风扇、马达进行工作 2 代码 pwm.h #ifndef __PWM_H__ #define __PWM_H__ #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_ti…

网页一直跳转到国家反诈中心页面

很明显&#xff0c;我进入的是vscode的官方下载地址。 但是一直会出现反诈中心的拦截 我们需要在控制面板中&#xff0c;找到网络&#xff0c; 将Internet 协议版本 4 (TCP/IPv4)的属性改成 使用下面的DNS 服务地址(E)&#xff1a;8.8.8.8 这样就可以正常访问相关的页面了

【day10.01】使用select实现服务器并发

用select实现服务器并发&#xff1a; linuxlinux:~/study/1001$ cat server.c #include <myhead.h>#define ERR_MSG(msg) do{\printf("%d\n",__LINE__);\perror(msg);\ }while(0)#define PORT 8880#define IP "192.168.31.38"int main(int argc, c…

动态规划算法(1)--矩阵连乘和凸多边形剖分

目录 一、动态数组 1、创建动态数组 2、添加元素 3、删除修改元素 4、访问元素 5、返回数组长度 6、for each遍历数组 二、输入多个数字 1、正则表达式 2、has.next()方法 三、矩阵连乘 1、什么是矩阵连乘&#xff1f; 2、动态规划思路 3、手推m和s矩阵 4、完…

Vue封装全局SVG组件

1.SVG图标配置 1.安装插件 npm install vite-plugin-svg-icons -D 2.Vite.config.ts中配置 import { createSvgIconsPlugin } from vite-plugin-svg-icons import path from path export default () > {return {plugins: [createSvgIconsPlugin({// Specify the icon fo…

cesium 热力图(CesiumHeatmap)

cesium 热力图 可添加、删除、显示、隐藏 完整代码 <!DOCTYPE html> <html lang="en"><head><meta charset="utf-8">

计算机毕设 大数据B站数据分析与可视化 - python 数据分析 大数据

文章目录 0 前言1 课题背景2 实现效果3 数据获取4 数据可视化5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做…

C++指针的使用

文章目录 1.C指针1.1 定义指针1.2 使用指针 2.空指针和野指针2.1 空指针2.2 野指针 3.指针所占空间4.使用const修饰指针4.1 const修饰指针4.2 const修饰常量4.3 const 既修饰指针也修饰常量 5.指针操作数组6.指针做函数参数7.使用指针知识实现冒泡排序 1.C指针 指针其实就是一…

基础数据结构之——【顺序表】(上)

从今天开始更新数据结构的相关内容。&#xff08;我更新博文的顺序一般是按照我当前的学习进度来安排&#xff0c;学到什么就更新什么&#xff08;简单来说就是我的学习笔记&#xff09;&#xff0c;所以不会对一个专栏一下子更新到底&#xff0c;哈哈哈哈哈哈哈&#xff01;&a…

掌动智能:替代JMeter的压力测试工具有哪些

JMeter是一个广泛使用的开源压力测试工具&#xff0c;但在实际应用中&#xff0c;也有一些其他优秀的替代品可供选择。本文将介绍几个可替代JMeter的压力测试工具&#xff0c;它们在功能、性能和易用性方面都具有独特优势&#xff0c;可以满足不同压力测试需求的选择。 一、Gat…

使用ExLlamaV2在消费级GPU上运行Llama2 70B

Llama 2模型中最大也是最好的模型有700亿个参数。一个fp16参数的大小为2字节。加载Llama 270b需要140 GB内存(700亿* 2字节)。 只要我们的内存够大&#xff0c;我们就可以在CPU上运行上运行Llama 2 70B。但是CPU的推理速度非常的慢&#xff0c;虽然能够运行&#xff0c;速度我…

[管理与领导-108]:IT人看清职场中的隐性规则 - 5 - 你会在不经意间被归属在不同的分类中,一旦分类定型,你就会被打上了某种标签(职场分类方法大全)

目录 前言&#xff1a; 一、关于分类 1.1 什么是分类 1.2 分类是人们理解复杂问题的一种常见方式 1.3 分类的优点与缺点 1.4 职场中的分类方法 二、职场对人的分类方法1&#xff1a;组织架构 2.1 职位和职级分类 2.2 按照部门、岗位进行分类 三、职场对人的分类方法2…

java Spring Boot按日期 限制大小分文件记录日志

上文 java Spring Boot 将日志写入文件中记录 中 我们实现另一个将控制台日志写入到 项目本地文件的效果 但是 这里有个问题 比如 我项目是个大体量的企业项目 每天会有一百万用户访问 那我每天的日志都记载同一个文件上 那不跟没记没什么区别吗&#xff1f; 东西怎么找&#x…

C++11之可变参数模板

可变参数模板 可变参数模板概念可变参数模板定义参数包展开方式递归展开参数包逗号表达式展开参数包 STL容器中的emplace相关接口函数 可变参数模板概念 C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板&#xff0c;相比C98/03&#xff0c;类模版和函…

Java进阶02 Array、内存分析、this、面向对象、继承、override、super、实例化、多态、向下转型、Object

文章目录 一、数组(Array)二、数组的内存分析三、Array工具类四、面向对象的一些小知识五、进阶知识补充1. this关键字2.继承3.方法重写4.super关键字的使用5.子类对象实例化6.多态性的体现7.向下转型8.Object类 一、数组(Array) 数组&#xff1a;多个相同类型数据按照一定顺序…

基于 SpringBoot 2.7.x 使用最新的 Elasticsearch Java API Client 之 ElasticsearchClient

1. 从 RestHighLevelClient 到 ElasticsearchClient 从 Java Rest Client 7.15.0 版本开始&#xff0c;Elasticsearch 官方决定将 RestHighLevelClient 标记为废弃的&#xff0c;并推荐使用新的 Java API Client&#xff0c;即 ElasticsearchClient. 为什么要将 RestHighLevelC…