为啥我们不能在下面的代码中使用方括号?

Posted

技术标签:

【中文标题】为啥我们不能在下面的代码中使用方括号?【英文标题】: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 【参考方案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) (快捷方式,因为它避免了括号)。在取消引用括号后,最后一级是访问指向的向量。如您所见,如果您使用的是指针,它在内存对象中仍然与初始向量相同,该对象没有被复制。

以上是关于为啥我们不能在下面的代码中使用方括号?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们不能在动态向量的情况下使用方括号?

为啥会出现这个错误?我们不能在函数括号内使用格式宏吗?

为啥我们在haskell中编写函数时需要使用括号?

为啥我们需要将 e.target.name 放在方括号 [] 中? [复制]

为啥我不能在没有括号的插值字符串中使用条件运算符? [复制]

xPath 用法总结整理