萌新求助

P1001 A+B Problem

Zhangikun @ 2023-04-16 10:59:42

当然我这题已经AC了,但是我有个问题:

#include<bits/stdc++.h>
using namespace std;
template<class T1,class T2>struct ikundered_map
{
  vector<pair<T1,T2> >hash[114514];//T1为下标的类型,T2为存储的类型
  int put_id(T1 x)
  {
    int id;
    if(typeid(T1)==typeid(1)||typeid(T1)==typeid(10000000000LL)||typeid(T1)==typeid('A')||typeid(T1)==typeid(false)||typeid(T1)==typeid(float(0.1))||typeid(T1)==typeid(0.1))
    id=((int)x%114514+114514)%114514;
    else
    id=put_id(x[0]);
    return id;
  }
  T2& operator[](T1 x)
  {
    int id;
    id=put_id(x);
    for(int i=0;i<hash[id].size();i++)
    {
      if(hash[id][i].first==x)
      {
        return hash[id][i].second;
      }
    }
    T2 num;
    hash[id].push_back({x,num});
    return hash[id][hash[id].size()-1].second;
  }
};
int main()
{
  string s;
  vector<string>v;
  int n;
  cin>>n;
  ikundered_map<string,bool>kun;
  for(int i=1;i<=n;i++)
  {
    cin>>s;
    if(kun[s]==0)
    {
      v.push_back(s);
      kun[s]=1;
    }
  }
  for(int i=0;i<v.size();i++)
  {
    cout<<v[i]<<" ";
  }
  return 0;
}

这个手写哈希为什么不能通过编译


by Zhangikun @ 2023-04-17 19:31:00

@徐崇瑜 请问怎么用呢,里面有什么格式要求吗


by 徐崇瑜 @ 2023-04-17 20:26:07

@Zhangikun 就是模板 template 关键字必须存在,然后只要不是正常格式(指定义的参数个数、类型等相同)的,就要在原类名后添加对应特定格式 </* 你的格式... */>

一个示例(代替 typeid 进行类型相等判断的类):

template<typename _Tpf, typename _Tps> class isSameType {
    public:
        static constexpr bool res = false;
};

template<typename _Tp> class isSameType<_Tp, _Tp> { //  同类型情况,编译器优先选择特化类型
    public:
        static constexpr bool res = true;
};

如上,特化的以及不特化的东西的区别就在于声明后的 </* ... */>


by 徐崇瑜 @ 2023-04-17 20:29:32

然后如果你想让 intlong long 被判定为同个类,那么可以这么写(往后面加):

template class isSameType<int, long long> {
    public:
        static constexpr bool res = true;
};
template class isSameType<long long, int> { //  注意顺序,正着反着都要写
    public:
        static constexpr bool res = true;
};

template 不可省略,但是后面的 <> 可以省略。


by Zhangikun @ 2023-04-17 20:32:16

#include<bits/stdc++.h>
#define LL long long
using namespace std;
template<class T3>int makeid(T3 x)
{
  return makeid(x[0]);
}
template<>int makeid(int x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(char x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(bool x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(double x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(float x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(LL x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(unsigned x)
{
  return (int(x)%114514+114514)%114514;
}
template<>int makeid(unsigned LL x)
{
  return (int(x)%114514+114514)%114514;
}
template<class T1,class T2>struct ikundered_map
{
  vector<pair<T1,T2> >hash[114514];//T1为下标的类型,T2为存储的类型
  T2& operator[](T1 x)
  {
    int id=makeid(x);
    for(int i=0;i<hash[id].size();i++)
    {
      if(hash[id][i].first==x)
      {
        return hash[id][i].second;
      }
    }
    T2 num;
    hash[id].push_back({x,num});
    return hash[id][hash[id].size()-1].second;
  }
};

int main()
{
  ikundered_map<vector<int>,int>a;
  int n;
  cin>>n;
  for(int i=1;i<=n;i++)
  {
    vector<int>v;
    int k;
    cin>>k;
    while(k--)
    {
      unsigned int num;
      cin>>num;
      v.push_back(num);
    }
    cout<<++a[v]<<"\n";
  }
  return 0;
}

@徐崇瑜 这样也可以


by 徐崇瑜 @ 2023-04-17 20:34:12

你的

typeid(T1)==typeid(1)||typeid(T1)==typeid(10000000000LL)||typeid(T1)==typeid('A')||typeid(T1)==typeid(false)||typeid(T1)==typeid(float(0.1))||typeid(T1)==typeid(0.1)

就可以改成

isSameType<T1, int>::res || isSameType<T1, long long>::res || isSameType<T1, char>::res || isSameType<T1, bool>::res || isSameType<T1, float>::res || isSameType<T1, double>::res

看上去可能还是很繁琐,但是比 typeid 快很多。(编译时已经知道答案了)


by Zhangikun @ 2023-04-17 20:36:38

@徐崇瑜 嗯嗯嗯


by 徐崇瑜 @ 2023-04-17 20:38:40

@Zhangikun 是的。。。

虽然我也会写出这种程序。。。

推荐写一个 ifType<bool, typename, typename> 以及 isInteger<typename>isFloat<typename>,在定义时选择一下哪些是整数,哪些是浮点。

然后推荐使用封装的带有 operator() 的类代替函数,因为支持的功能更全面。


by Zhangikun @ 2023-04-17 20:39:49

@徐崇瑜 太奆了,谢谢大奆佬


by 徐崇瑜 @ 2023-04-17 20:44:58

比如

//  定义了 ifType, isInteger 和 isFloat 后。。。

template<typename _Tp> class intIdMakerType {
    /*  整数实现。。。  */
};

template<typename _Tp> class floatIdMakerType {
    /*  浮点数数实现。。。  */
};

template<typename _Tp> class idMaker : ifType<isInteger<_Tp>, intIdMakerType<_Tp>, ifType<isFloat<_Tp>, floatIdMakerType<_Tp>, otherIdMakerType<_Tp> > > {
    /*  `otherIdMakerType` 表示其他不支持的类的 `idMaker` 的封装类,然后定义 `makeid`  */
};

template<typename _Tp> using makeid = idMaker<_Tp>();

现场写的,不知道编译是不是过不了。。。


by xueruo @ 2023-04-18 21:16:56

小黑子,露出鸡脚了吧


上一页 | 下一页