【问题标题】:Iterator for loop in map地图中的循环迭代器
【发布时间】:2023-03-15 15:40:01
【问题描述】:

我尝试了以下代码,但找不到错误。错误在循环部分,但我不知道如何正确使用迭代器以避免错误。 请帮助,并请澄清我的概念。 问题陈述是https://codeforces.com/contest/268/problem/A。我已经通过向量解决了

    int main()
    {
        std::ios::sync_with_stdio(false);
        int n,x,y,count=0; cin>>n;
        std::vector<pair<int,int>> v;
        for (int i = 0; i < n; ++i)
        {
            cin>>x>>y;
            v.push_back(make_pair(x,y));
        }

        for (int i = 0; i < n; ++i)
        {
            for (int j=i+1; j < n; ++j)
            {
                if(v[i].f==v[j].s){
                    count++;
                }
                if(v[i].s==v[j].f){
                    count++;
                }
            }
        }
        cout<<count;


        return 0;
    }

但通过地图遇到问题。 使用地图时会出现 SIGTSTP 错误。

#include <iostream>
#include <map>

using std::cin;
using std::cout;
using std::make_pair;

int main() {
  std::ios::sync_with_stdio(false);
  int n, x, y, count = 0;
  cin >> n;
  std::map<int, int> m;
  for (int i = 0; i < n; ++i) {
    cin >> x >> y;
    m.insert(make_pair(x, y));
  }

  for (auto i = m.begin(); i != m.end(); ++i) {
    for (auto j = ++i; j != m.end(); ++j) {
      if (i->first == j->second) {
        count++;
      }
      if (i->second == j->first) {
        count++;
      }
    }
  }
  cout << count;
  return 0;
}

【问题讨论】:

  • 错误是什么?请在您的问题中添加任何错误消息或意外输出(带有相应的输入)。点击edit 这样做。
  • 这个程序的目的是什么?
  • 你在双倍递增i。我的意思是,++i 将始终在每次 outer 循环迭代之后执行,and 在每个内部循环初始设置上执行。这意味着您最终可以将 i 放在 m.end()使用内循环初始化,然后尝试在下一次外循环迭代的增量步骤中进一步碰撞它(发生在比较测试之前),那个碰撞-过去端调用UB。我怀疑将内部循环初始化设置更改为auto j = std::next(i) 会满足您的要求,但没有解释代码的总体目的,这是一个完整的水晶球猜测。
  • 我已经添加了相关信息,请查看并帮助。

标签: c++ c++11 stl iterator c++14


【解决方案1】:

您不能使用 map 数据结构来解决这个问题,因为 map 以映射方式存储元素。每个元素都有一个键值和一个映射值。 没有两个映射值可以具有相同的键值。
但根据问题,键值可以相同,这就是为什么你不能在这里使用 map。
更多详情可以查看http://www.cplusplus.com/reference/map/map/

【讨论】:

  • 在循环中使用 multimap 和 std::next(i,1) 解决了这个问题。谁能告诉我们在解决这类问题时,我们应该使用 vector> 还是 map/multimap?
  • 如果保证map的key是唯一的,那么就用map,否则用vector。
【解决方案2】:

这是我的答案:

#include <iostream>
#include <map>

const int N = 50;

int h[N], a[N];

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", h + i, a + i);
  }

  int ans = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (i != j) {
        if (h[i] == a[j]) ans++;
      }
  printf("%d\n", ans);
  return 0;
}

问题的答案是sigma { h[i] = a[j] } (i != j)

你的代码犯了这些错误:

  1. std::map::insert 表示将某个键设置为某个值。另外,std::mapstd::multimap 不同。后者允许存在多个相同的键,而前者不允许。

  2. 你不应该只是将j 的起点设为i + 1,因为迭代范围应该是[0, i - 1] union [i + 1, n - 1](编辑:你的代码逻辑也是正确的)。

  3. 迭代器不能如此草率地自增,因为正如评论部分指出的那样,它有副作用。

【讨论】:

  • 在解决这类问题时,我们应该使用vector>还是map/multimap之类的?
  • 一个普通的数组在很多情况下就足够了。当您需要 push_back 等功能时,请使用 std::vector
  • 算法竞赛是关于快速和正确的答案。因此,不要使用不会提高答案并拖累编码速度的技术(就像 std::map/std::multimap 需要的额外日志 N 一样)。
猜你喜欢
  • 1970-01-01
  • 2016-01-02
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 2011-10-24
  • 2012-07-20
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多