繁体   English   中英

std::copy 不会在 C++ 中复制向量

[英]std::copy doesn't copy vector in C++

要查找仅包含 0 和 1 的所有固定长度序列,我使用以下代码:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

void print_array(vector<string> arr) {
  cout << '[';
  int n = arr.size();
  for (size_t i = 0; i < n; i++) {
    cout << arr[i];
    if (i < (n - 1)) {
      cout << ", ";
    }
  }
  cout << ']' << endl;
}

vector<string> get_variants(int n) {
  vector<string> result = {"0", "1"};
  vector<string> temp;
  temp.reserve(2);
  result.reserve(2);
  for (int i=0; i < (n - 1); ++i) {
    copy(result.begin(), result.end(), temp.end()); // [1]
    for (int j=0; j < result.size(); ++j) {
      temp[j] += "0";
      result[j] += "1";
    }
    copy(temp.begin(),temp.end(), result.end());
    temp.clear();
  }
  return result;
}

int main(int argc, char const *argv[]) {
  int n;
  cin >> n;
  vector<string> maybe = get_variants(n);
  print_array(maybe);
  return 0;
}

但是向量temp是空的,在我标记为 [1] 的行中复制之前以及之后。 所以,我的程序的 output 是[0111, 1111] 我做错了什么?

比使用std::copy更直接的方法是使用.insert()

temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy

您正在写信给temp.end()result.end() 这些迭代器代表“一个结束”,因此写入这些迭代器是未定义的行为。

您似乎正在寻找std::back_inserter 这将创建一个迭代器,该迭代器将在写入时将新元素插入到您的容器中。

std::copy(result.begin(), result.end(), std::back_inserter(temp));

虽然这回答了发布的问题,但您的代码中仍然存在其他导致未定义行为的错误。

尝试使用 C++ 编译器编译您的程序将不起作用,因为您包含了#include <bits/stdc++.h> ,它是不符合 tC++ 标准的 header。

你永远不应该包含这个文件。

您正在使用典型的竞争性编程材料,但包括所有 C++ 头文件并且不使用它们会无缘无故地占用编译时间。

然后,您键入定义典型的竞争性编程缩写。 其中2个,你不使用。 那么就没有理由定义它们了。

我建议不要再这样做了。 在 C++ 中,请使用using语句。

然后,虽然你想快点,但你将arr按值传递给你的 print function。 这将复制整个向量。

您分配/比较了很多 int 与 unsigned int 值。 这是你不应该做的。

另外:请使用有意义的变量名并写注释。 越多越好。


关于您的特定错误。 两个std::copy语句都使用end迭代器作为目标。 结束就是结束。 它超过了向量的末尾。 请改用std::back_inserter


关于算法。 我花了一段时间才意识到你基本上想要创建二进制数。 没有其他的。 不幸的是,您以非常复杂的方式翻译了它。

通常,您只需从 0 数到 2^n-1,然后显示数据。 就这样。 因为数字可能是任意长度,我们将使用手动添加数字,就像在 scholl 中在一张纸上一样。 很简单。

然后一切都归结为几行代码。

请参见:

#include <iostream>
#include <vector>

int main() {
    // Read length of binary number to create and validate input
    if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {

        // Here we will store the binary digits, so 0s or 1s
        std::vector<int> digits(numberOfDigits,0);

        // Som printing helper
        std::cout << '[';
        bool printComma{};

        // We need to print 2^n possible combinations
        for (int i = 0; i < (1 << numberOfDigits); ++i) {

            // Print comma, if need
            if (printComma) std::cout << ','; printComma = true;

            // Print all digits of the binary number
            for (const int d : digits) std::cout << d;
           
            // Calculate next binary number
           int carry = 0;
           for (int index=numberOfDigits -1; index >=0; --index)  {
                
                const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
                carry = sum / 2;
                digits[index] = sum % 2;
            } 
        }
        std::cout << ']';
    }
}

如果有问题,我很乐意回答。

保留不会增加向量大小。

尝试使用 C++ 编译器编译您的程序将不起作用,因为您包含了#include <bits/stdc++.h> ,它是不符合 tC++ 标准的 header。

你永远不应该包含这个文件。 绝不。

因此,您使用的是典型的竞争性编程材料,但为什么要包含所有 C++ 标头而不使用它们。 这是浪费时间。

然后,您键入定义典型的无意义的竞争性编程缩写。 其中2个,你不使用,为什么要定义它们?

不要再这样做了。 在 C++ 中,请使用using语句。

然后,虽然你想快点,但你将arr按值传递给你的 print function。 这将复制整个向量。

您分配/比较了很多 int 与 unsigned int 值。 这是你不应该做的。

另外:使用有意义的变量名并写注释。 越多越好。


关于算法。 我花了一段时间才意识到你基本上想要创建二进制数。 没有其他的。 不幸的是,您以非常复杂的方式翻译了它。

通常,您只需从 0 数到 n-1,然后显示数据。 就这样。 因为数字可能是任意长度,我们将使用手动添加数字,就像在 scholl 中在一张纸上一样。 很简单。

然后一切都归结为几行代码。

请参见:

#include <iostream>
#include <vector>

int main() {
    // Read length of binary number to create and validate input
    if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {

        // Here we will store the binary digits, so 0s or 1s
        std::vector<int> digits(numberOfDigits,0);

        // Som printing helper
        std::cout << '[';
        bool printComma{};

        // We need to print 2^n possible combinations
        for (int i = 0; i < (1 << numberOfDigits); ++i) {

            // Print comma, if need
            if (printComma) std::cout << ','; printComma = true;

            // Print all digits of the binary number
            for (const int d : digits) std::cout << d;
           
            // Calculate next binary number
           int carry = 0;
           for (int index=numberOfDigits -1; index >=0; --index)  {
                
                const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
                carry = sum / 2;
                digits[index] = sum % 2;
            } 
        }
        std::cout << ']';
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM