[英]std::copy doesn't copy vector in C++
To find all sequences of fixed length which contain only 0 and 1 I use this code:要查找仅包含 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;
}
But vector temp
is empty, before copying in line which I marked [1] and after.但是向量temp
是空的,在我标记为 [1] 的行中复制之前以及之后。 So, my program's output was [0111, 1111]
.所以,我的程序的 output 是[0111, 1111]
。 What I'm doing wrong?我做错了什么?
A more straightforward way than using std::copy
is the use of .insert()
:比使用std::copy
更直接的方法是使用.insert()
:
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
You are writing to temp.end()
and result.end()
.您正在写信给temp.end()
和result.end()
。 These iterators represent "one past the end", and therefore writing to these iterators is Undefined Behavior.这些迭代器代表“一个结束”,因此写入这些迭代器是未定义的行为。
You seem to be looking for std::back_inserter
.您似乎正在寻找std::back_inserter
。 This will create an iterator that will insert a new element to your container when it is written through.这将创建一个迭代器,该迭代器将在写入时将新元素插入到您的容器中。
std::copy(result.begin(), result.end(), std::back_inserter(temp));
While this answers the posted question, there remain other errors in your code leading to Undefined Behavior.虽然这回答了发布的问题,但您的代码中仍然存在其他导致未定义行为的错误。
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>
which is a non tC++ standard compliant header.尝试使用 C++ 编译器编译您的程序将不起作用,因为您包含了#include <bits/stdc++.h>
,它是不符合 tC++ 标准的 header。
You should never include this file.你永远不应该包含这个文件。
You are using typical competitive programming stuff, but including all C++ headers and not use them will eat up Compile time for no good reason.您正在使用典型的竞争性编程材料,但包括所有 C++ 头文件并且不使用它们会无缘无故地占用编译时间。
Then, you typedef the typical competitive programming abbreviations.然后,您键入定义典型的竞争性编程缩写。 2 of them, you do not use.其中2个,你不使用。 Then there is no reason to define them.那么就没有理由定义它们了。
I recommend to not do this any longer.我建议不要再这样做了。 And in C++, please use the using
statement.在 C++ 中,请使用using
语句。
Then, although you want to be fast, you pass arr
by value to your print function.然后,虽然你想快点,但你将arr
按值传递给你的 print function。 This will copy the whole vector.这将复制整个向量。
You assign/compare a lot of int with unsigned int values.您分配/比较了很多 int 与 unsigned int 值。 This you should not do.这是你不应该做的。
Additionally: Please use meaningful variable names and write comments.另外:请使用有意义的变量名并写注释。 The more the better.越多越好。
Regarding your specific bug.关于您的特定错误。 Both std::copy
statements use end
iterator as target.两个std::copy
语句都使用end
迭代器作为目标。 End is end.结束就是结束。 It is past the end of the vector.它超过了向量的末尾。 Please use std::back_inserter
instead.请改用std::back_inserter
。
Regarding the algorithm.关于算法。 I took a while for me to realize that you basically want to create binary numbers.我花了一段时间才意识到你基本上想要创建二进制数。 Nothing else.没有其他的。 Unfortunately you translated that in a very complicated way.不幸的是,您以非常复杂的方式翻译了它。
Normally, you just would count from 0 to 2^n-1 and then show the data.通常,您只需从 0 数到 2^n-1,然后显示数据。 Thats all.就这样。 Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper.因为数字可能是任意长度,我们将使用手动添加数字,就像在 scholl 中在一张纸上一样。 Very simple.很简单。
Everthing then biols down to some lines of code.然后一切都归结为几行代码。
Please see:请参见:
#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 << ']';
}
}
If there should be questions, then I am happy to answer.如果有问题,我很乐意回答。
reserve does't increse vector size.保留不会增加向量大小。
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>
which is a non tC++ standard compliant header.尝试使用 C++ 编译器编译您的程序将不起作用,因为您包含了#include <bits/stdc++.h>
,它是不符合 tC++ 标准的 header。
You should never include this file.你永远不应该包含这个文件。 Never.绝不。
So, you are using typical competitive programming stuff, but why include all C++ headers and not use them.因此,您使用的是典型的竞争性编程材料,但为什么要包含所有 C++ 标头而不使用它们。 This is a waste of time.这是浪费时间。
Then, you typedef the typical nonsens competitive programming abbreviations.然后,您键入定义典型的无意义的竞争性编程缩写。 2 of them, you do not use, so why define them?其中2个,你不使用,为什么要定义它们?
Do not do this any longer.不要再这样做了。 And in C++, please use the using
statement.在 C++ 中,请使用using
语句。
Then, although you want to be fast, you pass arr
by value to your print function.然后,虽然你想快点,但你将arr
按值传递给你的 print function。 This will copy the whole vector.这将复制整个向量。
You assign/compare a lot of int with unsigned int values.您分配/比较了很多 int 与 unsigned int 值。 This you should not do.这是你不应该做的。
Additionally: Use meaningful variable names and write comments.另外:使用有意义的变量名并写注释。 The more the better.越多越好。
Regarding the algorithm.关于算法。 I took a while for me to realize that you basically want to create binary numbers.我花了一段时间才意识到你基本上想要创建二进制数。 Nothing else.没有其他的。 Unfortunately you translated that in a very complicated way.不幸的是,您以非常复杂的方式翻译了它。
Normally, you just would count from 0 to n-1 and then show the data.通常,您只需从 0 数到 n-1,然后显示数据。 Thats all.就这样。 Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper.因为数字可能是任意长度,我们将使用手动添加数字,就像在 scholl 中在一张纸上一样。 Very simple.很简单。
Everthing then biols down to some lines of code.然后一切都归结为几行代码。
Please see:请参见:
#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.