Inserting elements to vector in c++ - c++

I need to insert for every element of vector it's opposite.
#include <iostream>
#include <vector>
int main() {
std::vector < int > vek {1,2,3};
std::cout << vek[0] << " " << vek[1] << " " << vek[2] << std::endl;
for (int i = 0; i < 3; i++) {
std::cout << i << " " << vek[i] << std::endl;
vek.insert(vek.begin() + i + 1, -vek[i]);
}
std::cout << std::endl;
for (int i: vek) std::cout << i << " ";
return 0;
}
OUTPUT:
1 2 3
0 1 // it should be 0 1 (because vek[0]=1)
1 -1 // it should be 1 2 (because vek[1]=2)
2 1 // it should be 2 3 (because vek[2]=3)
1 -1 1 -1 2 3 // it should be 1 -1 2 -2 3 -3
Could you explain me why function insert doesn't insert the correct value of vector? What is happening here?
Note: Auxiliary vectors (and other data types) are not allowed

During the for loop, you are modifying the vector:
After the first iteration which inserts -1, the vector becomes [1, -1, 2, 3]. Therefore, vec[1] becomes -1 rather than 2. The index of 2 becomes 2. And after inserting -2 into the vector, the index of the original value 3 becomes 4.
In the for loop condition, you need to add index i by 2, instead of 1:
#include <iostream>
#include <vector>
int main() {
std::vector < int > vek {1,2,3};
std::cout << vek[0] << " " << vek[1] << " " << vek[2] << std::endl;
for (int i = 0; i < 3 * 2; i+=2) {
std::cout << i << " " << vek[i] << std::endl;
vek.insert(vek.begin() + i + 1, -vek[i]);
}
std::cout << std::endl;
for (int i: vek) std::cout << i << " ";
return 0;
}

Related

splitting one vector into almost-equal sub vectors then storing into another vector

I am trying to split one large user given vector into x sub vectors. Everything "seems" to work as it should but the outcome is not right.
std::vector<std::vector<std::string>> split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string>> perm_vector;
for (int x = 0; x < thread_amount; x++) {
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++) {
hm++;
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
}
perm_vector.push_back(temp_vector);
}
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
std::cout << perm_vector[0][0];
return perm_vector;
Running this code will give you this:
initial size: 7
split amount: 3
2 need to be in each sub-vector
There will be: 1 element remaining
1
2
3
4
5
6
Size of vector holding the sub vectors after splitting: 3
2
the vector i pass in is called test holds strings and is like so:
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
Everything up until the last print statement seems to work. So perm_vector should hold 3 sub vectors containing every element in the main user given vector. When you print perm_vector[0][0] you would expect the output to be "1", but it is 2, also 7 should not be in the vector and 6 should be the last one but since it starts at 2, 7 is in it. the counter is defined outside of the function and it starts at 0. My question is why is it starting at 2?
I see two problems in your code:
hm is incremented before use. Furthermore, there is no point in making it global.
size_for_splitting is the result of an integer division, so the remainder is missing
I modified your code so the issues with hm are solved. I get the intended output <<1, 2>, <3, 4>, <5, 6>>, the 7 is missing as mentioned above.
#include <iostream>
#include<vector>
#include<string>
std::vector<std::vector<std::string> > split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string> > perm_vector;
int hm = 0;
for (int x = 0; x < thread_amount; x++) {
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++) {
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
hm++;
}
perm_vector.push_back(temp_vector);
}
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
return perm_vector;
}
int main()
{
std::vector<std::string> test;
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
std::vector<std::vector<std::string> > out = split_to_sub_vectors(test, 3);
}
Even if hm starts at 0, you increment it before you use it. Probably if you increment at the end of the internal for loop, you might get the output you expect. It's hard to tell the problem because I don't know what's in 'initial_vector', I assume initial_vector[0] = 1?
If you use the range-v3 library, implementing this logic becomes much easier, and less error prone:
#include <range/v3/all.hpp>
namespace rs = ranges;
namespace rv = ranges::views;
auto split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount) {
auto res = initial_vector
| rv::chunk(thread_amount)
| rs::to<std::vector<std::vector<std::string>>>;
if (res.back().size() != thread_amount)
res.pop_back();
return res;
}
Here's a demo.

What's wrong in my if statements logic?

In this little program I try to order 3 numbers in a descending order. But seems like the line in which has "// 3 2 1 - doesn't work" as a comment isn't working as expected. It seems like my logic is correct.
My input:
4,
554 and
454545
Output: (which is not what I wanted)
554, 454545 and 4
If the value hold on the integer numbThree is bigger than numbOne and if numbOne is NOT bigger than numbTwo (NOT == else) it should ouput numbThree, numbTwo and numbOne in this order, why doesn't it work?
#include <iostream>
int main() {
int numbOne = 0, numbTwo = 0, numbThree = 0;
std::cin >> numbOne >> numbTwo >> numbThree;
if (numbOne > numbTwo) {
if (numbTwo > numbThree) {
std::cout << numbOne << " " << numbTwo << " " << numbThree << std::endl; // 1 2 3
}
else {
std::cout << numbOne << " " << numbThree << " " << numbTwo<< std::endl; // 1 3 2
}
}
else if (numbTwo > numbOne) {
if (numbOne > numbThree) {
std::cout << numbTwo << " " << numbOne << " " << numbThree << std::endl; // 2 1 3 - works
}
else {
std::cout << numbTwo << " " << numbThree << " " << numbOne << std::endl; // 2 3 1
}
}
else if (numbThree > numbOne) {
if (numbOne > numbTwo) {
std::cout << numbThree << " " << numbOne << " " << numbTwo << std::endl; // 3 1 2
}
else {
std::cout << numbThree << " " << numbTwo << " " << numbOne << std::endl; // 3 2 1 - doesn't work
}
}
std::cin.get();
std::cin.ignore();
return 0;
}
Thanks in advance for helping me out.
You cannot, in general, sort 3 numbers with 2 comparisons (see YSC's comment for a hard reason in terms of information content). Already your case 1 3 2 is flawed: what if numbThree > numbOne?
In general you have to allow for up to 3 comparisons. Of course, you can simply use the sort functionality provided by the standard library (i.e. by the language). If you don't want to (for some reason), then the correct logic (for ascending order) is
if(a<b)
if (b<c) // a,b,c // 2 comparisons
else if(a<c) // a,c,b // 3 comparisons
else // c,a,b // 3 comparisons
else
if( (a<c) // b,a,c // 2 comparisons
else if(b<c) // b,c,a // 3 comparisons
else // c,b,a // 3 comparisons
Thus, in 4 out of 6 possible cases we need 3 rather than 2 comparisons.
Not intended as an answer, but as an illustration of the comment by Sam Varshavchik:
What's wrong is that the code should use a small array, and std::sort,
instead of this kind of spaghetti code.
While Sam is right about production code, as an exercise of how to implement the logic, the question is okay and there is already a solution.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v(3);
if (! (std::cin >> v[0] >> v[1] >> v[2])) { exit(-1); }
std::sort(v.begin(), v.end(), std::greater<int>());
for (auto c: v) { std::cout << c << " "; }
std::cout << "\n";
}

C++ how to print out array values next to each other rather than underneath

I have made this section of code and would like it to print out like so:
Element Value
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
Instead of being underneath of each other. Could any one point me in the correct direction?
#include <iostream>
int main(){
int n[10] = {1,2,3,4,5,6,7,8,9,10};
int x[10] = {0,0,0,0,0,0,0,0,0,0};
std::cout << "Element" <<std::endl;
for(int i = 0; i < 10; i++)
{
std::cout <<n[i] << std::endl;
}
std::cout << "Value" <<std::endl;
for(int y = 0; y <10; y++)
{
std::cout << x[y] << std::endl;
}
std::cout << "size of array: " << sizeof(n) << std::endl;
}
Print the values next to each other in one loop instead of using two loops (I changed the contents of x to make sure we see what's going on):
#include <iostream>
int main(){
int x[10] = {5,8,1,2,4,6,7,1,0,9};
std::cout << "Element Value" << std::endl;
for(int i = 0; i < 10; i++) {
std::cout << " " << i << " " << x[i] << std::endl;
}
std::cout << "size of array: " << sizeof(x) << std::endl;
return 0;
}
https://ideone.com/vAaLyl
Output:
Element Value
0 5
1 8
2 1
3 2
4 4
5 6
6 7
7 1
8 0
9 9
size of array: 40
Other than that, there's no need for the array n; use your index as the index.

garbage values for vector push_back

I'm trying to assign an array's values to a vector. It seems to be working fine for one vector, but when I do it for a second, I'm getting back garbage values. I cout the number and I know it's correct, but it's not assigning correctly. I don't understand because it's working fine for the first vector.
int sorted[] = {0,1,2,3,4,5,6,7,8,9,10};
// make two smaller arrays, do this untill they are a base case size;
void split(int *dataIN, int dataSize){
// new data will be broken up into two vectors with each half of the
// original array. These will be size firstHalfSize and secondHalfSize.
int firstHalfSize;
int secondHalfSize;
vector<int> firstHalf;
vector<int> secondHalf;
// test to see if array in is odd or even
bool isOdd;
if (dataSize%2 == 1){
isOdd = true;
}else if (dataSize%2 == 0){
isOdd = false;
}
// determine length of new vectors
// second half is firstHalf + 1 if odd.
firstHalfSize = dataSize/2;
if (isOdd){
secondHalfSize = firstHalfSize + 1;
}else if (!isOdd){
secondHalfSize = firstHalfSize;
}
// assign first half of dataIn[] to firstHalf vector
cout << "firs: " << firstHalfSize << endl;
for (int i = 0; i < firstHalfSize; i++){
cout << "a: " << dataIN[i] << endl;// make sure i have the right number
firstHalf.push_back(dataIN[i]);// assign
cout << "v: " << firstHalf[i] << endl;// make sure assigned correctly
}
// do the same for second half
cout << "second: " << secondHalfSize << endl;
for (int i = firstHalfSize; i < (firstHalfSize+secondHalfSize); i++){
cout << "a: " << dataIN[i] << endl;
secondHalf.push_back(dataIN[i]);
cout << "v: " << secondHalf[i] << endl;
}
}
int main(void){
split(sorted, sizeof(sorted)/sizeof(int));
return 0;
}
This is my result. As you can see the first vector push_back went fine and the array values (after "a: ") are also correct.
firs: 5
a: 0
v: 0
a: 1
v: 1
a: 2
v: 2
a: 3
v: 3
a: 4
v: 4
second: 6
a: 5
v: -805306368
a: 6
v: 2
a: 7
v: -805306368
a: 8
v: 0
a: 9
v: 0
a: 10
v: 0
In the second case, you are indexing from firstHalfSize.
You need to cout the values starting from index 0. For example:
cout << "v: " << secondHalf[i-firstHalfSize] << endl;
You are iterating firstHalf from 0 to firstHalfSize with the variable i, so i will be within the range of firstHalf, when you use operator[] - in the second vector's case, i does not mean the same thing.
The filling of the vector is working. It is just your debug output that is incorrect. When outputting values from secondHalf you need to use indexes from 0, not from firstHalfSize.
You can write your code more simply if you take advantage of the std::vector range constructor that takes a pair of iterators. Array pointers can be treated as iterators:
void print(const std::vector<int>& data){
for(int value : data)
std::cout << value << " ";
std::cout << "\n";
}
void split(int *dataIN, int dataSize){
auto firstHalfSize = (dataSize + 1) / 2;
std::vector<int> firstHalf(dataIN, dataIN + firstHalfSize);
std::vector<int> secondHalf(dataIN + firstHalfSize, dataIN + dataSize);
std::cout << "firstHalf: ";
print(firstHalf);
std::cout << "seconHalf: ";
print(secondHalf);
}
Live demo

printing two adjacent values returned from adjacent_find

I want to print the first 2 values where the next is doubled from the current value.
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
bool doubled (int x, int y) { return x*2 == y; }
int main()
{
deque<int> di;
deque<int>::iterator diiter;
for (int i=0; i<=10; i+=2) di.insert(di.end(), i);
for (diiter = di.begin(); diiter != di.end(); ++diiter)
cout << *diiter << " ";
cout << endl;
diiter = adjacent_find(di.begin(), di.end(), doubled);
if (diiter != di.end()) {
cout << "found " << *diiter << " at " << distance(di.begin(), diiter)+1
<< " and " << *(++diiter) << " at " << distance(di.begin(), diiter)+1
<< endl;
}
}
the output is
0 2 4 6 8 10
found 4 at 3 and 4 at 2
not what I expected, which should be:
0 2 4 6 8 10
found 2 at 2 and 4 at 3
What's wrong with my code? I don't understand how the second position is decremented from the first one when I actually incremented it.
Thanks for all help.
Your program is giving strange results because it does not take in to account the fact, that order of evaluation of arguments to a function(In this case operator <<) is Unspecified.
My Answer here, explains the problem in detail & should be a good read.
You need to cout them on separate statements.
cout << "found " << *diiter;
cout << " at " << distance(di.begin(), diiter)+1;
cout << " and " << *(++diiter);
cout << " at " << distance(di.begin(), diiter)+1;
cout << endl;
This works well & outputs the correct/desired output.