【问题标题】:Why can't we use square brackets in the code below?为什么我们不能在下面的代码中使用方括号?
【发布时间】:2021-10-01 09:27:44
【问题描述】:
vector<int> mergeKSortedArrays(vector<vector<int>*> input) {
      vector<int> ans;
      //min priority queue
      priority_queue<int, vector<int>, greater<int>> pq;
      for(int i = 0; i < input.size(); i++){
        for(int j = 0; j < input[i] -> size(); j++){
           pq.push(input[i][j]); //THIS LINE
         }
       }
       while(!pq.empty()){
          ans.push_back(pq.top());
          pq.pop();
       }
       return ans;
     }

调用这个函数mergeKSortedArrays的主函数

int main() {
        int k;
        cin >> k;
        vector<vector<int> *> input;
        for (int j = 1; j <= k; j++) {
          int size;
          cin >> size;
          vector<int> *current = new vector<int>;
          for (int i = 0; i < size; i++) {
             int a;
             cin >> a;
             current->push_back(a);
            }
           input.push_back(current);
          }

         vector<int> output = mergeKSortedArrays(input);

         for (int i = 0; i < output.size(); i++) {
            cout << output[i] << " ";
         }
        return 0;
    }

谁能说出为什么在第一个循环中使用 input[i][j] 会出错?我所知道的方括号如何工作的是它只是去地址和取消引用。所以我不明白为什么使用方括号会有问题。 Input[i] 将我带到向量指针,然后 Input[i][j] 将我带到该向量的地址并取消引用。就像 input[i][j] =*(vector 的地址 + j)。 伙计们,还有一件事,我可以输入 [i] -> at(j)。它编译没有问题。但不是不是不是 input[i][j] 与 input[i] -> at(j) 相同,除非我正在对内存进行非法访问。

【问题讨论】:

  • 可能是vector&lt;vector&lt;int&gt;*&gt; input -> vector&lt;vector&lt;int&gt;&gt; input? Edit 并显示调用 mergeKSortedArrays 的代码。阅读:minimal reproducible example

标签: c++ vector


【解决方案1】:

有了这个声明:

vector<vector<int>*> input;

input 不是 int 向量的向量,而是 pointers 指向 int 向量的向量。

因此你需要这个:(*input[i])[j]

  • input[i] 是指向 vector&lt;int&gt; 的指针
  • *input[i]vector&lt;int&gt;
  • (*input[i])[j]int

话虽如此,您首先不应该使用指针,而应该简单地使用vector&lt;vector&lt;int&gt;&gt;(整数向量的向量)。然后你可以使用input[i][j]

完整代码:

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

vector<int> mergeKSortedArrays(vector<vector<int>> input) {
  vector<int> ans;
  //min priority queue
  priority_queue<int, vector<int>, greater<int>> pq;
  for (int i = 0; i < input.size(); i++) {
    for (int j = 0; j < input[i].size(); j++) {
      pq.push(input[i][j]); //THIS LINE
    }
  }
  while (!pq.empty()) {
    ans.push_back(pq.top());
    pq.pop();
  }
  return ans;
}

int main() {
  int k;
  cin >> k;
  vector<vector<int>> input;
  for (int j = 1; j <= k; j++) {
    int size;
    cin >> size;
    vector<int> current;
    for (int i = 0; i < size; i++) {
      int a;
      cin >> a;
      current.push_back(a);
    }
    input.push_back(current);
  }

  vector<int> output = mergeKSortedArrays(input);

  for (int i = 0; i < output.size(); i++) {
    cout << output[i] << " ";
  }
  return 0;
}

注意:
这段代码可以编译,但我没有检查它是否真的按照您的预期工作。

奖励:
mergeKSortedArrays的签名应该是

vector<int> mergeKSortedArrays(const vector<vector<int>> & input)`

这将避免调用 mergeKSortedArrays 时不必要的向量副本。

【讨论】:

  • 我注意到的另一件事是,在我的代码中,我实际上能够执行 input[i] -> at(j)。不是和input[i][j]一样吗?
  • @Aman 不,它与input[i]-&gt;operator[](j)(又名(*input[i]).operator[](j)相似
  • @Caleth..所以在 input[i] 的位置有一个操作员正在帮助我访问索引。我不能只做输入[i][j]。但是,input[i] = *(input + i)...then for input[i][j] 不应该像 *((*input + i) + j) 那样做。它就像 *(&vector + j)。它不应该像数组一样工作吗?
  • 我假设 (&vector + j) 将通过向它添加 4 个字节将我带到这个整数向量的下一个索引。不过我觉得不是这样的。
【解决方案2】:

希望一个简单的例子能说明vector&lt;vector&lt;int&gt;&gt;vector&lt;vector&lt;int&gt;*&gt;之间的区别

#include <vector>
#include <iostream>

int main(){
    std::vector<int> v0 = {1, 2, 3};
    std::vector<int> v1 = {1, 2, 3};
    std::vector<std::vector<int>> vv = {v0, v1};
    std::vector<std::vector<int> *> vpv = {&v0, &v1};
    v0[0] = 4;
    v0[1] = 5;
    v0[2] = 6;

    std::cout
    << ' ' << v0[0] 
    << ' ' << v0[1]
    << ' ' << v0[2]
    << ' ' << v1[0] 
    << ' ' << v1[1]
    << ' ' << v1[2]
    << "\n" 
    << ' ' << vv[0][0] 
    << ' ' << vv[0][1]
    << ' ' << vv[0][2]
    << ' ' << vv[1][0] 
    << ' ' << vv[1][1] 
    << ' ' << vv[1][2] 
    << "\n"
    << ' ' << vpv[0][0][0] 
    << ' ' << vpv[0][0][1]
    << ' ' << vpv[0][0][2]
    << ' ' << vpv[1][0][0] 
    << ' ' << vpv[1][0][1]
    << ' ' << vpv[1][0][2]
    << "\n"; }

打印出来的结果是:

4 5 6 1 2 3
1 2 3 1 2 3
4 5 6 1 2 3

【讨论】:

  • 是的,我想我明白了。你能告诉我vpv[0]、vpv[0][0]和vpv[0][0][0]代表什么吗?
  • 是的:vpv[0] 是一个指向 int 向量的指针。我正在使用括号快捷方式来取消引用指针:pointer[0] 等效于 (*pointer) (快捷方式,因为它避免了括号)。在取消引用括号后,最后一级是访问指向的向量。如您所见,如果您使用的是指针,它在内存对象中仍然与初始向量相同,该对象没有被复制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多