指纹锁---带你见识set的强大

本文介绍了一种使用C++ STL中的Set数据结构解决大数据量查找问题的方法,通过自定义比较器实现误差范围内的元素查找,有效避免了超时问题,大幅提升了查找效率。

在这里插入图片描述

对于100%的测试数据: 1 ≤ k,m ≤ 1000000 数据量较大,注意使用更快的输入输出方式。

这题也是模拟题,难点在于如何存数据,以及数据范围较大时,如果直接查找可能会超时
还在犹豫要不要二分查找时,看到了下面的题解,我才知道set居然这么强大,确实在这里使用set非常的合适,set内置的find()函数,复杂度是**O(nlogn)**的,不用担心查找会超时。同时set是默认不同的才能插入,但这里不同的是,它定义的“不同”是在误差k内的。
所有需要像sort函数中的cmp一样,单独写一个结构体cmp用于set中的互异判断,真的太强大了,有了这个set,增删操作就是一个函数的问题,查询操作也是find一下就行了,太舒服了!
会用STL真的能节省很多时间。

参考题解:
在这里插入图片描述

using namespace std;
#include<bits/stdc++.h>
int m,k,x;
struct cmp {
    bool operator () (const int& u, const int& v) const {
        if (abs(u - v) <= k) return false;
        return u < v;
    }
};
set<int,cmp> s;

int main(){
    ios::sync_with_stdio(false);
    string op;
    cin>>m>>k;
    while(m--)
    {
        cin>>op>>x;
        if(op == "add")
        {
            s.insert(x);
        }
        else if(op == "del")
        {
            s.erase(x);
        }
        else if(op == "query")
        {
            if(s.find(x) != s.end()) cout<<"Yes\n";
            else cout<<"No\n";
        }
    }
    return 0;
}
花了10块钱买的,希望对大家有帮助。/*############################################################################# * 文件名:file.c * 功能: 实现了指纹相关文件的操作 * modified by PRTsinghua@hotmail.com #############################################################################*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "file.h" /* 对象的这些接口实现是私有的,不必为用户所知 */ typedef struct iFvsFile_t { FILE *pf; /* 文件指针 */ } iFvsFile_t; /****************************************************************************** * 功能:创建一个新的文件对象,只有在创建之后,文件对象才能为其它函数所用。 * 参数:无 * 返回:若创建失败,返回NULL;否则返回新的对象句柄。 ******************************************************************************/ FvsFile_t FileCreate() { iFvsFile_t* p = NULL; p = (iFvsFile_t*)malloc(sizeof(iFvsFile_t)); if (p!=NULL) p->pf = NULL; return (FvsFile_t)p; } /****************************************************************************** * 功能:破坏一个已经存在的文件对象,在毁坏之后,文件对象不能再为其它函数所用。 * 参数:file 即将删除的文件对象指针 * 返回:无返回值 ******************************************************************************/ void FileDestroy(FvsFile_t file) { iFvsFile_t* p = NULL; if (file==NULL) return; /* 关闭文件,如果它还打开着 */ (void)FileClose(file); p = file; free(p); } /****************************************************************************** * 功能:打开一个新的文件。一个文件可以读打开,写打开,或者被创建。 * 参数:file 文件对象 * name 待打开文件的名字 * flags 打开标志 * 返回:错误编号 ******************************************************************************/ FvsError_t FileOpen(FvsFile_t file, const FvsString_t name, const FvsFileOptions_t flags) { iFvsFile_t* p = (iFvsFile_t*)file; char strFlags[10]; int nflags = (int)flags; /* 关闭文件,如果已经打开 */ (void)FileClose(p); strcpy(strFlags, ""); if ( (nflags & FvsFileRead)!=0 && (nflags & FvsFileWrite)!=0 ) strcat(strFlags, "rw"); else { if ((nflags & FvsFileRead)!=0) strcat(strFlags, "r"); if ((nflags & FvsFileWrite)!=0) strcat(strFlags, "w"); } strcat(strFlags, "b"); if ((nflags & FvsFileCreate)!=0) strcat(strFlags, "+"); p->pf = fopen(name, strFlags); if (FileIsOpen(file)==FvsTrue) return FvsOK; return FvsFailure; } /****************************************************************************** * 功能:关闭一个文件对象,文件关闭之后,文件不再可用。 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileClose(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; int nerr = -1; if (p->pf!=NULL) { nerr = fclose(p->pf); p->pf = NULL; } if (nerr==0) return FvsOK; return FvsFailure; } /****************************************************************************** * 功能:测试一个文件是否打开 * 参数:file 文件对象 * 返回:文件打开,则返回true;否则返回false ******************************************************************************/ FvsBool_t FileIsOpen(const FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (p->pf!=NULL)?FvsTrue:FvsFalse; } /****************************************************************************** * 功能:测试是否到了文件结尾 * 参数:file 文件对象 * 返回:到了结尾,返回true;否则返回false ******************************************************************************/ FvsBool_t FileIsAtEOF(const FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsFalse) return FvsFalse; return (feof(p->pf)!=0)?FvsTrue:FvsFalse; } /****************************************************************************** * 功能:提交对文件所作的更改 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileCommit(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (fflush(p->pf)==0)?FvsOK:FvsFailure; } /****************************************************************************** * 功能:跳到文件的开头 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeekToBegin(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, 0, SEEK_SET)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:跳到文件的结尾 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeekToEnd(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, 0, SEEK_END)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:得到当前的文件指针位置 * 参数:file 文件对象 * 返回:当前的指针位置 ******************************************************************************/ FvsUint_t FileGetPosition(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) return (FvsUint_t)ftell(p->pf); return 0; } /****************************************************************************** * 功能:跳到文件的指定位置 * 参数:file 文件对象 * position 指定的文件位置 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeek(FvsFile_t file, const FvsUint_t position) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, (long int)position, SEEK_SET)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:从文件中读数据,所读取的字节数由length决定。读取的数据保存于指针data。 * 参数:file 文件对象 * data 指向存储数据的数组 * length 要读取的字节数 * 返回:实际读取的字节数 ******************************************************************************/ FvsUint_t FileRead(FvsFile_t file, FvsPointer_t data, const FvsUint_t length) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsUint_t)fread(data, (size_t)1, (size_t)length, p->pf); } /****************************************************************************** * 功能:往文件中写数据,所写的字节数由length决定。要写入的数据保存于指针data。 * 参数:file 文件对象 * data 指向存储数据的数组 * length 要写入的字节数 * 返回:实际写入的字节数 ******************************************************************************/ FvsUint_t FileWrite(FvsFile_t file, const FvsPointer_t data, const FvsUint_t length) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsUint_t)fwrite(data, (size_t)1, (size_t)length, p->pf); } /****************************************************************************** * 功能:从文件中得到一个字节 * 参数:file 文件对象 * 返回:读取的字节 ******************************************************************************/ FvsByte_t FileGetByte(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsByte_t)fgetc(p->pf); } /****************************************************************************** * 功能:从文件中读取一个字 * 参数:file 文件对象 * 返回:读取的字 ******************************************************************************/ FvsWord_t FileGetWord(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; FvsWord_t w = (FvsWord_t)fgetc(p->pf); return (w<<8)+fgetc(p->pf); }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值