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] 的行和之后复制之前。所以,我的程序的输出是 [0111, 1111]
。我做错了什么?
您正在写信给 temp.end()
和 result.end()
。这些迭代器代表“最后一个”,因此写入这些迭代器是未定义的行为。
您似乎在寻找 std::back_inserter
。这将创建一个迭代器,它将在写入时将一个新元素插入到您的容器中。
std::copy(result.begin(), result.end(), std::back_inserter(temp));
虽然这回答了已发布的问题,但您的代码中仍然存在导致未定义行为的其他错误。
比使用 std::copy
更直接的方法是使用 .insert()
:
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
尝试使用 C++ 编译器编译您的程序是行不通的,因为您包含 #include <bits/stdc++.h>
这是一个不符合 tC++ 标准的 header。
你永远不应该包含这个文件。
您正在使用典型的竞争性编程材料,但是包括所有 C++ header 并且不使用它们会无缘无故地耗尽编译时间。
然后,您键入定义了典型的竞争性编程缩写。其中2个,你不用。那么就没有理由去定义它们了。
我建议不要再这样做了。在 C++ 中,请使用 using
语句。
然后,尽管您希望速度快,但还是将 arr
按值传递给打印函数。这将复制整个向量。
你 assign/compare 很多 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 << ']';
}
}
如果有问题,我很乐意回答。
要查找仅包含 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] 的行和之后复制之前。所以,我的程序的输出是 [0111, 1111]
。我做错了什么?
您正在写信给 temp.end()
和 result.end()
。这些迭代器代表“最后一个”,因此写入这些迭代器是未定义的行为。
您似乎在寻找 std::back_inserter
。这将创建一个迭代器,它将在写入时将一个新元素插入到您的容器中。
std::copy(result.begin(), result.end(), std::back_inserter(temp));
虽然这回答了已发布的问题,但您的代码中仍然存在导致未定义行为的其他错误。
比使用 std::copy
更直接的方法是使用 .insert()
:
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
尝试使用 C++ 编译器编译您的程序是行不通的,因为您包含 #include <bits/stdc++.h>
这是一个不符合 tC++ 标准的 header。
你永远不应该包含这个文件。
您正在使用典型的竞争性编程材料,但是包括所有 C++ header 并且不使用它们会无缘无故地耗尽编译时间。
然后,您键入定义了典型的竞争性编程缩写。其中2个,你不用。那么就没有理由去定义它们了。
我建议不要再这样做了。在 C++ 中,请使用 using
语句。
然后,尽管您希望速度快,但还是将 arr
按值传递给打印函数。这将复制整个向量。
你 assign/compare 很多 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 << ']';
}
}
如果有问题,我很乐意回答。