I am confused about the following code and what it does:
first.assign (7,100); // 7 ints with a value of 100
std::vector<int>::iterator it;
it=first.begin()+1;
second.assign (it,first.end()-1); // the 5 central values of first
I don't understand the second.assign statement. I would assume it assigns 100 elements in second with a value of 100. Why is the size of second 5?
In the example code
it = vec.begin()+1 meaning 2nd element
And
second.assign (it,first.end()-1);
^^^^^^^^^^
One past the last element.
it has skipped the first and last elements and hence you have 7-2=5 elements in the last assignment.
There are 2 overloads of assign (3 in C++11).
First assign uses the new contents are n elements, each initialized to a copy of val.
2nd assign uses the new contents are elements constructed from each of the elements in the range between first and last, in the same order.
Therefore the 2nd assign copies first from the 2nd element to the penultimate element.
Related
i am learning data structure on c++ and i have come through one thing which is hard for me to understand or get concept.
I am just putting question to give better context.
https://leetcode.com/problems/frequency-of-the-most-frequent-element/
The frequency of an element is the number of times it occurs in an array.
You are given an integer array nums and an integer k. In one operation, you can choose an index of nums and increment the element at that index by 1.
Return the maximum possible frequency of an element after performing at most k operations.
Example 1:
Input: nums = [1,2,4], k = 5
Output: 3
Explanation: Increment the first element three times and the second element two times to
make nums = [4,4,4].
4 has a frequency of 3.
this is the code given to complete:
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
}
};
i want to solve this problem by recursive first but my problem here is that the function is getting reference of a vector as a parameter so if i change the value inside the function, it will change the original vector.
I am not able to think how can i make different recursion with different choices because it is not pass by value.
Any help please !!
It's a simple thing that I am doing but it doesn't work as I expected.
int main(){
vector<list<int>> adjList(3);
adjList[0].push_back(1);
adjList[0].push_back(2);
adjList[1].push_back(3);
adjList[1].push_back(0);
adjList[2].push_back(4);
cout << "Original graph...\n";
printGraph(adjList);
cout << "\nAfter deleting the zeroth index...\n";
adjList.erase(adjList.begin());
printGraph(adjList);
return 0;
}
Original graph...
0:1->2->NULL
1:3->0->NULL
2:4->NULL
After deleting the zeroth index...
0:3->0->NULL
1:4->NULL
I expected the zeroth index in my vector of list to be deleted. Instead, something weird happened where the second index got deleted and the elements in the list also got shuffled.
I am sure I am missing something basic here but just not able to figure out what that is.
Any help is much appreciated!
My bad. I realize now what's wrong. I was expecting to see the same indices after deletion but of course that is a wrong expectation. So the output is actually right just the indices moved around.
Original graph...
0:1->2->NULL
1:3->0->NULL
2:4->NULL
After deleting the zeroth index...
0:3->0->NULL (index 1 becomes 0)
1:4->NULL (index 2 becomes 1)
adjList.erase(adjList.begin()+1);
I expected the zeroth index in my vector of list to be deleted.
Your expectation is wrong.
adjList.begin()+1 is an iterator to the element at index 1. Therefore erasing that iterator will cause the element at index 1 to be erased (i.e. the second element).
adjList.begin() is an iterator to the element at the index 0, so if your intention is to erase that element, then that is the iterator that you would need to erase. Note however, that if you need to often erase the first element of the sequence, and need to keep the sequence in original order, then a vector is an inefficient choice. In such case, you might want to consider using a deque.
adjList.erase(adjList.begin());
I expected to get the below: 1:3->0->NULL 2:4->NULL
Your expectation is wrong.
A vector never skips any indices. If there are n elements in a vector, then those elements are in indices 0...n-1.
When you erase an element of a vector, the elements at greater indices are shifted to the left (this is why erasing from anywhere except at the end of the vector is slow).
I am working on a magic square problem that uses a dynamic matrix of size n*n. It fills the matrix with numbers 1-n^2, and the sum of each row, column, and diagonal must be the same. One of the conditions of the algorithm is to check if an element in the matrix already had a number input in it during one of the loops. I am having problems checking if one of the elements in the matrix already had a number inputed in it, so I am wondering how to check if an element is empty.
Here is my code for that portion of the algorithm:
else if(matrix[row][col] != 0)
{
row = row + 2;
col--;
}
For some reason it triggers this if statement on the 5th iteration of the encompasing loop. I have worked it out on paper using the algorithm for a magic square, and the 5th iteration of the loop brings it to an empty element in the matrix. I thought that if an element is empty it holds the value 0? I appreciate any help as I am very confused. Thank you.
Array's in C and C++ are not empty by default. You need to explicitly set the elements to 0 or create the array in such a way that they are initialized to 0.
What you are facing is Undefined Behavior. The uninitialized array has some random(read garbage) values and accessing those results in a Undefined behavior.
Array's created at global scope or with a static qualifier will be initialized to 0 or you can use initialization provided built in by the language or you can explicitly set each element to 0.
There are multiple ways of doing so, the best one depends on what behavior you want to extract from the array.
I was reading Josuttis "The C++ Standard Library, 2nd ed.". In section 6.7.1 author explains that the code given below will give unexpected results. I still don't how std::remove() functions, and why I am getting this strange result. (Though I understood that you need to use std::erase() in order to actually remove elements, and it is actually better to use list::erase() rather than combination of std::remove() & `std::remove()).
list<int> coll;
// insert elements from 6 to 1 and 1 to 6
for (int i=1; i<=6; ++i) {
coll.push_front(i);
coll.push_back(i);
}
// print
copy (coll.cbegin(), coll.cend(), // source
ostream_iterator<int>(cout," ")); // destination
cout << endl;
// remove all elements with value 3
remove (coll.begin(), coll.end(), // range
3); // value
// print (same as above)
and the results are
pre: 6 5 4 3 2 1 1 2 3 4 5 6
post: 6 5 4 2 1 1 2 4 5 6 5 6 (???)
This explanation should help:
Removing is done by shifting the elements in the range in such a way
that elements to be erased are overwritten. Relative order of the
elements that remain is preserved and the physical size of the
container is unchanged. Iterators pointing to an element between the
new logical end and the physical end of the range are still
dereferenceable, but the elements themselves have unspecified values.
A call to remove is typically followed by a call to a container's
erase method, which erases the unspecified values and reduces the
physical size of the container to match its new logical size.
Note that the return value from std::remove() is the iterator that represents the new end. Therefore, calling std::erase() on this new end and the old end will free your excess space.
std::remove doesn't actually shorten the list. It can't - as it only gets iterators and not the container itself.
What it does is copies the remaining values so that you get them in the beginning of the container. But the final elements of the container (in your case - the last two: '5' and '6') are actually still there..
After using std::remove you have to shorten to container yourself to remove the remaining "junk" copies.
You asked the algorithm to remove "3" element. So, while enumerating the container the algo shifts the content if something is removed from the middle. Such shift occurs 2 times in your case, this is why you see "5 6" elements at the end (because actual end was moved to 2 items forward). Then, "std::erase" will fix the issue with tail zombies.
To quote from everyone's favorite c++ website:
The function cannot alter the properties of the object containing the
range of elements (i.e., it cannot alter the size of an array or a
container): The removal is done by replacing the elements that compare
equal to val by the next element that does not, and signaling the new
size of the shortened range by returning an iterator to the element
that should be considered its new past-the-end element.
So std::remove doesn't change the size of the list. It removes the matching elements and returns you an iterator that represents the new end of the list. To actually erase the extraneous elements, you then need to do:
auto it = remove(coll.begin(), coll.end(), 3);
coll.erase(it, coll.end());
I need to shuffle an array so that all array elements should change their location.
Given an array [0,1,2,3] it would be ok to get [1,0,3,2] or [3,2,0,1] but not [3,1,2,0] (because 2 left unchanged).
I suppose algorithm would not be language-specific, but just in case, I need it in C++ program (and I cannot use std::random_shuffle due to the additional requirement).
What about this?
Allocate an array which contains numbers from 0 to arrayLength-1
Shuffle the array
If there is no element in array whose index equals its value, continue to step 4; otherwise repeat from step 2.
Use shuffled array values as indexes for your array.
For each element e
If there is an element to the left of e
Select a random element r to the left of e
swap r and e
This guarantees that each value isn't in the position that it started, but doesn't guarantee that each value changes if there's duplicates.
BeeOnRope notes that though simple, this is flawed. Given the list [0,1,2,3], this algorithm cannot produce the output [1,0,3,2].
It's not going to be very random, but you can rotate all the elements at least one position:
std::rotate(v.begin(), v.begin() + (rand() % v.size() - 1) + 1, v.end());
If v was {1,2,3,4,5,6,7,8,9} at the beginning, then after rotation it will be, for example: {2,3,4,5,6,7,8,9,1}, or {3,4,5,6,7,8,9,1,2}, etc.
All elements of the array will change position.
I kind of have a idea in my mind hope it fits your application. Have one more container and this container will be
a "map(int,vector(int))" . The key element will show index and the second element the vector will hold the already used values.
For example for the first element you will use rand function to find which element of the array you should use.Than you will check the map structure if this element of the array has been used for this index.