随机生成100组N个数并对比,C++,python,matlab,pair,std::piecewise_construct

news/2024/11/5 11:23:02 标签: c++, python, 开发语言, matlab

随机生成100组N个数,数的范围是1到35,并检查是否包含目标数组的数字

python_1">python版本

python">import numpy as np
def count_groups_containing_obj(N, obj):
    # 随机生成100组N个数,数的范围是1到35
    groups = np.random.randint(1, 36, size=(1000, N))
    #print(groups)
    
    # 目标数组obj转换为numpy数组
    obj = np.array(obj)
    
    # 初始化包含obj的组数计数
    count = 0
    k=0
    ks=[]
    
    # 遍历每组,检查是否包含目标数组obj中的所有数
    for group in groups:
        k+=1
        # 使用np.isin检查组中的每个数是否都在obj中
        #print(np.all(np.isin(obj,group)))
        ii = np.all(np.isin(obj,group))
        if ii:
            count += 1
            ks.append(group)
    
    return count,ks

# 输入N和obj
N = 8  # 每组的数的个数
obj = [2,3,10,16,28]  # 目标数组

# 调用函数并打印结果
result,ks = count_groups_containing_obj(N, obj)
print(f"包含目标数组的组数: {result}",result/10000)
print(ks)

matlab_39">matlab版本

matlab">function [count, ks] = count_groups_containing_obj(N, obj)
    % 随机生成100组N个数,数的范围是1到35
    groups = randi(35, 20000, N);
    
    % 目标数组obj转换为列向量
    obj = obj(:);
    
    % 初始化包含obj的组数计数
    count = 0;
    ks = [];
    
    % 遍历每组,检查是否包含目标数组obj中的所有数
    for i = 1:size(groups, 1)
        group = groups(i, :);
        % 使用ismember检查组中的每个数是否都在obj中
        if all(ismember(obj, group))
            count = count + 1;
            ks = [ks; group]; %#ok<AGROW>
        end
    end
    
    % 打印结果
    fprintf('包含目标数组的组数: %d\n', count);
    fprintf('比例: %.4f%%\n', count / 20000 * 100);
end

C++版本

把这个转C++,将Python代码转换为C++代码需要一些调整,特别是由于C++中没有直接对应的NumPy库。不过,我们可以使用标准库中的容器和算法来实现类似的功能。以下是一个C++版本的实现:

#include <iostream>  
#include <vector>  
#include <cstdlib>  
#include <ctime>  
#include <algorithm>  
#include <numeric>  
  
// 生成一个包含N个1到35之间随机数的组  
std::vector<int> generateGroup(int N) {  
    std::vector<int> group(N);  
    std::generate(group.begin(), group.end(), std::rand); // 生成随机数,但未限制范围  
    std::transform(group.begin(), group.end(), group.begin(), [](int x) { return x % 35 + 1; }); // 将随机数映射到1-35  
    return group;  
}  
  
// 检查一个组是否包含目标数组中的所有数  
bool containsAll(const std::vector<int>& group, const std::vector<int>& obj) {  
    for (int num : obj) {  
        if (std::find(group.begin(), group.end(), num) == group.end()) {  
            return false;  
        }  
    }  
    return true;  
}  
  
// 统计包含目标数组的组的数量  
std::pair<int, std::vector<std::vector<int>>> countGroupsContainingObj(int N, const std::vector<int>& obj) {  
    std::srand(std::time(0)); // 初始化随机数种子  
    int count = 0;  
    std::vector<std::vector<int>> ks;  
  
    for (int i = 0; i < 1000; ++i) {  
        std::vector<int> group = generateGroup(N);  
        if (containsAll(group, obj)) {  
            count++;  
            ks.push_back(group);  
        }  
    }  
  
    return {count, ks};  
}  
  
int main() {  
    int N = 8; // 每组的数的个数  
    std::vector<int> obj = {2, 3, 10, 16, 28}; // 目标数组  
  
    auto [result, ks] = countGroupsContainingObj(N, obj);  
    double percentage = static_cast<double>(result) / 1000;  
  
    std::cout << "包含目标数组的组数: " << result << ", 百分比: " << percentage << std::endl;  
  
    // 输出包含的组(为了简洁,这里不打印所有组,只打印组数)  
    std::cout << "包含的组数: " << ks.size() << std::endl;  
  
    // 如果需要打印所有组,可以取消下面的注释  
    /*  
    for (const auto& group : ks) {  
        for (int num : group) {  
            std::cout << num << " ";  
        }  
        std::cout << std::endl;  
    }  
    */  
  
    return 0;  
}

几种初始化 std::pair 的方法:

在 C++ 中,std::pair 是一个模板类,用于存储两个元素的容器,这两个元素可以是不同的类型。std::pair 通常用于函数返回多个值,或者在标准库算法中作为键值对存储在容器中。

使用构造函数

#include <utility> // 或者 <pair>

int main() {
    // 直接使用构造函数初始化
    std::pair<int, std::string> p(1, "one");

    return 0;
}

使用花括号 {} 初始化(列表初始化)

#include <utility> // 或者 <pair>

int main() {
    // 使用花括号初始化
    std::pair<int, std::string> p = {1, "one"};

    return 0;
}

使用 make_pair 函数

#include <utility> // 包含 make_pair

int main() {
    // 使用 make_pair 创建 pair
    std::pair<int, std::string> p = std::make_pair(1, "one");

    return 0;
}

使用 std::piecewise_construct(C++11 及以后版本)

如果你需要使用不同的构造函数来初始化 pair 的两个元素,可以使用 std::piecewise_construct

#include <utility> // 包含 piecewise_construct

struct MyStruct {
    int x;
    std::string y;
};

int main() {
    // 使用 piecewise_construct 初始化
    std::pair<MyStruct, int> p(std::piecewise_construct,
                             std::forward_as_tuple(1), // 使用 MyStruct 的构造函数
                             std::forward_as_tuple(2)); // 使用 int 的默认构造函数

    return 0;
}

在这些例子中,std::pair 被用来存储不同类型的值。你可以根据需要选择最适合你的场景的初始化方法。

std::piecewise_construct

std::piecewise_construct 是 C++11 引入的一个实用工具,它用于构造 std::pairstd::tuple 等容器时,分别对每个元素使用不同的构造参数。这在你需要使用不同类型或不同构造函数初始化容器中的元素时非常有用。

用途和场景

  1. 不同构造参数:当你需要构造一个包含多种类型的 pairtuple 时,std::piecewise_construct 允许你为每个类型提供特定的构造参数。

  2. 效率:它可以帮助避免不必要的临时对象和拷贝,特别是在构造复杂对象时。

  3. 灵活性:它提供了一种灵活的方式来构造容器,特别是当元素的构造需要不同的参数或条件时。

示例

以下是使用 std::piecewise_construct 来构造 std::pair 的示例:

#include <utility>
#include <iostream>

struct Person {
    std::string name;
    int age;

    Person(const std::string& name, int age) : name(name), age(age) {}
};

int main() {
    // 使用 piecewise_construct 来构造 pair
    std::pair<std::string, Person> personPair(
        std::piecewise_construct,
        std::forward_as_tuple("John Doe"),  // 第一个元素的构造参数
        std::forward_as_tuple("John Doe", 30)  // 第二个元素的构造参数
    );

    std::cout << "Name: " << personPair.first << ", Age: " << personPair.second.age << std::endl;

    return 0;
}

在这个例子中,std::pair 的第一个元素是一个 std::string,只需要一个字符串参数来构造。第二个元素是 Person 类型,需要两个参数:一个字符串和一个整数。std::piecewise_construct 允许我们分别为这两个元素提供不同的构造参数。

注意事项

  • std::piecewise_construct 需要包含头文件 <utility>
  • 使用 std::forward_as_tuple 来确保参数以正确的方式传递给构造函数。
  • 这种方法在构造包含复杂对象的 pairtuple 时特别有用,尤其是当这些对象的构造函数参数不同时。

std::piecewise_construct 提供了一种高效且灵活的方式来构造包含多种类型元素的容器,使得代码更加清晰和易于维护。


http://www.niftyadmin.cn/n/5739409.html

相关文章

Linux高阶——1103—修改屏蔽字信号到达及处理流程时序竞态问题

目录 1、练习&#xff1a;修改屏蔽字&#xff0c;实现人为阻塞信号 1、定义两个信号集类型set和oset 2、将信号集初始化 3、设置set集合中的signo对应的位置 4、判断某一位的位码是0还是1 5、替换 总代码 2、信号失效的方法 3、高级信号 4、查看未决信号集 总代码 5、…

练习LabVIEW第三十八题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十八题&#xff1a; 创建一个VI&#xff0c;实现对按钮状态的指示和按钮“按下”持续时间简单计算功能&#xff0c;按…

C#属性 Property

属性Property不是变量。 它们是由名为访问器方法来实现的一种方法。 实例属性表示的是实例的某个数据&#xff0c;通过这个数据反映实例当前的状态 静态属性表示的是类型的某个数据&#xff0c;通过这个数据反映类型当前的状态 意义&#xff1a; 防止恶意赋值(通过属性间接访问…

微服务day01

MybatisPlus Mp入门 基本步骤 引入MybatisPlus依赖&#xff0c;代替Mybatis依赖 <dependency> <groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </…

命令kill

kill命令用于终止进程 kill [options] <PID> options 选项 kill -9 要强制终止进程 默认情况下&#xff0c;kill 命令发送的是终止信号&#xff08;SIGTERM&#xff0c;信号编号 15&#xff09;&#xff0c;大多数进程在接收到这个信号后会正常结束。 如果进程没有响应…

arm64-v8a 和 armeabi-v7a 有啥区别?

ARM64-v8a 和 ARMEABI-v7a 是 Android 平台上两种不同的 ARM 架构&#xff0c;用于支持应用程序的运行。它们之间有几个关键的区别&#xff1a; 1. 架构类型 ARM64-v8a&#xff1a;代表的是 64 位的 ARM 架构&#xff08;ARMv8-A&#xff09;。它能够处理更大范围的地址空间和…

angular实现list列表和翻页效果

说明&#xff1a;angular实现list列表和翻页效果 上一页 当前页面 下一页 效果图&#xff1a; step1: E:\projectgood\ajnine\untitled4\src\app\car\car.component.css .example-form-fields {display: flex;align-items: flex-start; }mat-list-item{background: antiquew…

MongoDB笔记02-MongoDB基本常用命令

文章目录 一、前言二、数据库操作2.1 选择和创建数据库2.2 数据库的删除 3 集合操作3.1 集合的显式创建3.2 集合的隐式创建3.3 集合的删除 四、文档基本CRUD4.1 文档的插入4.1.1 单个文档插入4.1.2 批量插入 4.2 文档的基本查询4.2.1 查询所有4.2.2 投影查询&#xff08;Projec…