面向对象程序设计(荣誉)实验七 unordered_set

简介: 面向对象程序设计(荣誉)实验七 unordered_set

1. 十二生肖(map)


题目描述


我国十二生肖排序为:鼠、牛、虎、兔、龙、蛇、马、羊、猴、鸡、狗、猪


要求全程使用map完成十二生肖以及相互顺序的保存、还有比较、查询等功能


除了存放十二生肖名称使用数组,其他地方使用数组辅助求解,看程度扣分


输入


先输入n表示有n个测试,每个测试输入两行


第一行输入一个生肖,输出生肖对应的


如果生肖是不存在的,作为一种新生肖,并且顺序最后


第二行输入两个不同的生肖x和y(至少一个是已有的),输出x在y之前,或x在y之后


输出


每个测试输出两行


第一行输出生肖与位置,位置从0开始计算


第二行输出前后,看样例输出


样例输入


2

龙 虎

豹 马


样例输出


猫–12

龙在虎之后

马–6

豹在马之后


题解

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
    string animal[12] = {"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
    map<string,int> group;
    for (int i = 0; i < 12;i++)
    {
        group.insert({animal[i], i});
    }
    int t;
    cin>>t;
    while (t--)
    {
        string name;
        cin >> name;
        auto it = group.find(name);
        if(it==group.end())
        {
            group[name] = group.size();
            it = group.find(name);
        }
        cout << it->first << "--" << it->second << endl;
        string x, y;
        cin >> x >> y;
        auto it1 = group.find(x);
        auto it2 = group.find(y);
        if(it1==group.end())
        {
            cout << x << "在" << y << "之后" << endl;
        }
        else if(it2==group.end())
        {
            cout << x << "在" << y << "之前" << endl;
        }
        else
        {
            if(it1->second>it2->second)
            {
                cout << x << "在" << y << "之后" << endl;
            }
            else
            {
                cout << x << "在" << y << "之前" << endl;
            }
        }
    }
    return 0;
}

2. 集合(unordered_set)


题目描述


给定两个集合A,B,集合中的元素为长整型,集合中的元素个数不超过50000个。求两个集合的关系:A是B的真子集;B是A的真子集;A=B;A交B空集;A交B非空。


输入


测试次数


每组测试数据格式如下:


集合A的元素数n 集合B的元素数m


集合A的n个元素


集合B的m个元素


输出


对每组测试数据输出以下情况之一:


A是B的真子集;B是A的真子集; A=B; A交B空集;A交B非空。


样例输入


2

5 3

10 20 30 40 50

10 20 30

4 4

1 2 3 4

2 1 3 4


样例输出


B是A的真子集

A=B


题解

#include<bits/stdc++.h>
using namespace std;
unordered_set<long long> a,b;
bool AinB(){
  for(auto i:a){
    if(b.find(i)==b.end()){
      return false;
    }
  }
  return true;
}
bool BinA(){
  for(auto i:b){
    if(a.find(i)==a.end()){
      return false;
    }
  }
  return true;
}
int AcrossB(){
  int cnt=0;
  for(auto i:a){
    if(b.find(i)!=b.end()){
      cnt++;
    }
  }
  return cnt;
}
int main() {
  int n,m,num,t;
  cin>>t;
  for(int cs=0;cs<t;cs++){
    if(cs!=0) cout<<"\n";
    a.clear();b.clear();
    cin>>n>>m;
    for(int i=0;i<n;i++){
      cin>>num;
      a.insert(num);
    }
    for(int i=0;i<m;i++){
      cin>>num;
      b.insert(num);
    }
    int cross = AcrossB();
    if(cross == 0){
      cout<<"A交B空集";
      continue;
    }else{
      bool f1 = AinB(),f2 = BinA();
      if(f1&&f2){
        cout<<"A=B";
        continue;
      }
      if(f1 && a.size() < b.size()){
        cout<<"A是B的真子集";
        continue;
      }
      if(f2 && a.size() > b.size()){
        cout<<"B是A的真子集";
        continue;
      }
      cout<<"A交B非空";
    }
  }
}


3. 脱单年(set)


题目描述


传说中如果一个年份的四个数字互不相等就是一个大概率脱单的年份。例如1234年就是个脱单年


输入一个初始年份,然后计算多少年后可以遇到脱单年


要求


1、不能直接比较年份四个数字的异同


2、利用set的元素不重复特性来实现检查年份四个数字异同


输入


第一行输入n,表示有n个测试


接着输入n行,每行输入一个初始年份(如果年份不足4位,程序自动高位补0)


输出


计算每个初始年份后的第一个脱单年,并输出相应信息


每个年份输出一行


样例输入


3

2019

2020

2000


样例输出


From 2019, the offsingle year is 2019

From 2020, the offsingle year is 2031

From 2000, the offsingle year is 2013


题解

#include <bits/stdc++.h>
using namespace std;
int main() {
   string word;
   set<string> s;
   while(cin >> word){
      for(int i=0;i<word.size();i++) word[i] = tolower(word[i]);
    regex R("[a-z]{1,}");
      smatch Mat;
      if(regex_search(word, Mat, R))
        s.insert(Mat.str());
  }
  for(auto i:s){
    cout<<i<<endl;
  }
   return 0;
}


4. 图非0面积


题目描述


编程计算由"1"围成的下列图形的面积。面积计算方法是统计"1"所围成的闭合曲线中"0"点的数目。如图所示,在10*10的二维数组中,"1"围住了15个点,因此面积为15。


c0aa9be890364bd9a64cca25e7b582ff.png


输入


测试次数t


每组测试数据格式为:


数组大小m,n


一个由0和1组成的m*n的二维数组


输出


对每个二维数组,输出符号"1"围住的"0"的个数,即围成的面积。假设一定有1组成的闭合曲线,但不唯一。


样例输入


2

10 10

0 0 0 0 0 0 0 0 0 0

0 0 0 0 1 1 1 0 0 0

0 0 0 0 1 0 0 1 0 0

0 0 0 0 0 1 0 0 1 0

0 0 1 0 0 0 1 0 1 0

0 1 0 1 0 1 0 0 1 0

0 1 0 0 1 1 0 1 1 0

0 0 1 0 0 0 0 1 0 0

0 0 0 1 1 1 1 1 0 0

0 0 0 0 0 0 0 0 0 0

5 8

0 1 1 0 0 1 1 0

1 0 1 0 1 0 0 1

0 1 0 1 0 0 1 0

0 1 0 0 1 1 1 0

0 0 0 0 0 0 0 0


样例输出


15

5


题解

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 1010;
bool g[N][N], st[N][N];
int n, m, t;
int cnt;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {1, 0, -1, 0};
void bfs()
{
    memset(st, false, sizeof st);
    queue<PII> q;
    for(int i = 0; i < n; i ++ )
    {
        if(!g[i][0])
        {
            q.push({i, 0});
            st[i][0] = true;
        }
        if(!g[i][m - 1])
        {
            q.push({i, m - 1});
            st[i][0] = true;
        }
    }
    for(int i = 0; i < m; i ++ )
    {
        if(!g[0][i])
        {
            q.push({0, i});
            st[0][i] = true;
        }
        if(!g[n - 1][i])
        {
            q.push({n - 1, i});
            st[n - 1][i] = true;
        }
    }
    while(!q.empty())
    {
        auto t = q.front();
        q.pop();
        g[t.x][t.y] = 1;
        for(int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= m) continue;
            if(!st[a][b] && !g[a][b]) q.push({a, b});
        }
    }
}
void count()
{
    cnt = 0;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < m; j ++ )
            if(!g[i][j]) cnt ++ ;
}
int main()
{
    cin >> t;
    while(t -- )
    {
        cin >> n >> m;
        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < m; j ++ )
                cin >> g[i][j];
        bfs();
        count();
        cout << cnt << endl;
    }
    return 0;
}

5. 方程解析(string)


题目描述


以ax^2+bx+c的形式输入方程ax^2+bx+c=0。请用string或regex_match解析出方程的a、b、c。


例如:-10x^2+8x , 则a=-10, b = 8 , c = 0。


10x , 则a = 0, b=10, c = 0。


输入


测试数据有多组


每组测试数据一行,为ax^2+bx+c, 其中a,b,c均为整数,若为0,则该项可不出现。x前系数为+1,-1,1可不出现。


假设方程数据无非法情况。


输出


对每组测试数据,输出每个方程的系数a,b,c。格式见样例


样例输入


0

-x^2

10x^2-9x+7

10x

-10x^2+8x

-123


样例输出


0 0 0

-1 0 0

10 -9 7

0 10 0

-10 8 0

0 0 -123


题解

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<map>
#include<queue>
#include<set>
#include<regex>
using namespace std;
int main()
{
  string s0;
  while(cin>>s0)
  { 
    int a=0,b=0,c=0;
    auto it=s0.begin()+1;
    for(;;it++)
    {
      regex p1("[-+]*[0-9]*x\\^2");
      string s1(s0.begin(),it);
      if(regex_match(s1,p1))
      {
        string s(s0.begin(),it-3);
        if(s.empty())
        {
          a=1;
          s0.erase(s0.begin(),it);
          break;
        }
        else if(s=="-")
        {
          a=-1;
          s0.erase(s0.begin(),it);
          break;
        }
        a=atoi(s.c_str());
        s0.erase(s0.begin(),it);
        break;
      }
      if(it==s0.end())
        break;
    }
    if(s0.empty())
    {
      cout<<a<<" "<<b<<" "<<c<<endl;
      continue;
    }
      it=s0.begin()+1;
    for(;;it++)
    {
      regex p2("[-+]*[0-9]*x");
      string s1(s0.begin(),it);
      if(regex_match(s1,p2))
      {
        string s(s0.begin(),it-1);
        if(s.empty()||s=="+")
        {
          b=1;
          s0.erase(s0.begin(),it);
          break;
        }
        else if(s=="-")
        {
          b=-1;
          s0.erase(s0.begin(),it);
          break;
        }
        b=atoi(s.c_str());
        s0.erase(s0.begin(),it);
        break;
      }
      if(it==s0.end())
        break;
    }
    if(s0.empty())
    {
      cout<<a<<" "<<b<<" "<<c<<endl;
      continue;
    }
    c=atoi(s0.c_str());
    cout<<a<<" "<<b<<" "<<c<<endl;  
  }
  cout<<endl<<endl<<endl<<endl;
  return 0;
}
相关文章
|
算法 C++
面向对象程序设计(荣誉)实验六 set,bitset,multimap
面向对象程序设计(荣誉)实验六 set,bitset,multimap
142 0
|
2月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
219 1
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
163 2
|
3月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
87 0
|
3月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
157 0
|
3月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
40 0
|
3月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
172 0
|
7月前
|
编译器 容器
哈希表模拟封装unordered_map和unordered_set
哈希表模拟封装unordered_map和unordered_set
|
7月前
|
编译器 测试技术 计算机视觉
红黑树模拟封装map和set
红黑树模拟封装map和set