[Object-C]_[C/C++]_[集合操作对比]

场景

  1. 比如编辑联系人, 联系人需要加入某个分组, 这时候界面操作就需要复选框来选择加入某个分组, 但是有可能这个联系人之前已经加入了某个分组, 现在只是需要加入新的分组即可, 但是界面操作往往用户可能并不知道这个联系人已经加入过哪些分组, 所以他会把想加入的分组都勾选一边, 这样我们程序在提交时就需要过滤出未加入过的分组,也就是”相对补集”;

  2. 再比如, 修改用户资料时, 我们需要勾选多个爱好兴趣, 也会发生用户重复勾选已经选择过的爱好兴趣的情况.

  3. 再比如,用户也有可能取消勾选, 这样还是得计算”相对补集”作为需要删除得集合, 所以相对补集是比较常见的.

说明

这里写图片描述

  1. C++ 的 stl algorithm 里提供了这类操作的模板函数, 而 Object-C就少写, 它作为 NSMutableSet的方法出现.

  2. C++ 的 集合模板函数在使用前需要排序, 而 NSMutableSet 的方法却不用, 执行效率还是CPP更快, 当然 NSLog删除后性能有所提升, 但是还是不如删除 std::cout的 CPP实现.10倍左右.

例子

//
//  TestSet.h
//  TestObject-C
//
//  Created by sai on 10/26/17.
//  Copyright (c) 2017 sai. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface TestSet : NSObject

+(void)testSet;

@end
//
//  TestSet.mm
//  TestObject-C
//
//  Created by sai on 10/26/17.
//  Copyright (c) 2017 sai. All rights reserved.
//

#import "TestSet.h"
#include <vector>
#include <chrono>
#include <iostream>
#include <sstream>
#include <algorithm>

@implementation TestSet

+(void)testCppSet
{
    std::cout << "======== testCppSet ========" << std::endl;
    auto beg =  std::chrono::system_clock::now();
    std::vector<int> v1 = {1,3,4,5,7,9,2};
    std::vector<int> v2 = {2,3,6,7,7,10};
    std::stringstream ss;
    for (int one : v1) {
        ss << one << ",";
    }
    std::string str = ss.str();
    std::cout << "v1: " << str << std::endl;

    ss.clear();
    ss.str("");
    for (int one : v2)
        ss << one << ",";

    str = ss.str();
    std::cout << "v2: " << str << std::endl;

    std::vector<int> d1;
    auto last = std::unique(v1.begin(),v1.end());
    v1.erase(last, v1.end());
    d1.clear();
    last = std::unique(v2.begin(),v2.end());
    v2.erase(last, v2.end());


    std::cout << "=== v1和v2的交集 ===" << std::endl;
    ss.clear();
    ss.str("");
    std::sort(v1.begin(),v1.end());
    std::sort(v2.begin(),v2.end());
    std::vector<int> result;
    std::set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),std::back_inserter(result));
    for (int one : result)
        ss << one << ",";

    str = ss.str();
    std::cout << str << std::endl;

    std::cout << "=== v1在v2中的相对补集 ===" << std::endl;
    ss.clear();
    ss.str("");

    std::set_difference(v2.begin(),v2.end(),result.begin(),result.end(),std::back_inserter(d1),
                        [](const int first,const int second)->bool{
                            return first < second;
                        });

    for (int one : d1)
        ss << one << ",";

    str = ss.str();
    std::cout << str << std::endl;

    std::cout << "=== v1和v2的合集 ===" << std::endl;
    ss.clear();
    ss.str("");
    d1.clear();
    std::set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),std::back_inserter(d1));
    for (int one : d1)
        ss << one << ",";

    str = ss.str();
    std::cout << str << std::endl;

    auto end =  std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end-beg;
    std::cout << "elapsed_seconds: "<< elapsed_seconds.count() << "s" << std::endl;
}

+(void)testObjectCSet
{
    std::cout << "testObjectCSet" << std::endl;
    auto beg =  std::chrono::system_clock::now();

    NSMutableString* str = [NSMutableString new];
    [str autorelease];

    NSArray* a = [NSArray arrayWithObjects:@(1),@(3),@(4),@(5),@(7),@(9),@(2), nil];
    for (NSNumber* one in a) {
        [str appendFormat:@"%lld,",[one longLongValue]];
    }
    NSLog(@"v1: %@,",str);

    [str setString:@""];
    NSArray* b = [NSArray arrayWithObjects:@(2),@(3),@(6),@(7),@(7),@(10), nil];
    for (NSNumber* one in b) {
        [str appendFormat:@"%lld,",[one longLongValue]];
    }
    NSLog(@"v2: %@,",str);

    NSMutableSet* v1 = [NSMutableSet setWithArray:a];
    NSMutableSet* v1_copy = [NSMutableSet setWithSet:v1];

    NSMutableSet* v2 = [NSMutableSet setWithArray:b];
    NSMutableSet* v2_copy = [NSMutableSet setWithSet:v2];

    NSLog(@"=== v1和v2的交集 ===");
    [str setString:@""];
    [v1_copy intersectSet:v2];
    for (NSNumber* one in v1_copy) {
        [str appendFormat:@"%lld,",[one longLongValue]];
    }
    NSLog(@"%@,",str);

    [str setString:@""];
    NSLog(@"=== v1在v2中的相对补集 ===");
    [v2_copy minusSet:v1_copy];
    for (NSNumber* one in v2_copy) {
        [str appendFormat:@"%lld,",[one longLongValue]];
    }
    NSLog(@"%@,",str);

    [str setString:@""];
    NSLog(@"=== v1和v2的合集 ===");
    [v1 unionSet:v2];
    for (NSNumber* one in v1) {
        [str appendFormat:@"%lld,",[one longLongValue]];
    }
    NSLog(@"%@,",str);
    auto end =  std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end-beg;
    std::cout << "elapsed_seconds: "<< elapsed_seconds.count() << "s" << std::endl;
}

+(void)testSet
{
    @autoreleasepool {
        [self testObjectCSet];
        [self testCppSet];
    }
}

@end

输出

testObjectCSet
2017-10-26 17:00:56.129 TestObject-C[5957:303] v1: 1,3,4,5,7,9,2,,
2017-10-26 17:00:56.129 TestObject-C[5957:303] v2: 2,3,6,7,7,10,,
2017-10-26 17:00:56.130 TestObject-C[5957:303] === v1和v2的交集 ===
2017-10-26 17:00:56.131 TestObject-C[5957:303] 2,7,3,,
2017-10-26 17:00:56.131 TestObject-C[5957:303] === v1在v2中的相对补集 ===
2017-10-26 17:00:56.132 TestObject-C[5957:303] 6,10,,
2017-10-26 17:00:56.133 TestObject-C[5957:303] === v1和v2的合集 ===
2017-10-26 17:00:56.133 TestObject-C[5957:303] 9,5,1,10,6,2,7,3,4,,
elapsed_seconds: 0.004996s
======== testCppSet ========
v1: 1,3,4,5,7,9,2,
v2: 2,3,6,7,7,10,
=== v1和v2的交集 ===
2,3,7,
=== v1在v2中的相对补集 ===
6,10,
=== v1和v2的合集 ===
1,2,3,4,5,6,7,9,10,
elapsed_seconds: 0.000345s

参考

std::unique
std::difference
交集和补集

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter(阿斯拉达)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值