I am currently trying to fill up a 2D array with 16 values from 1-16. I want to fill up the array with non-repeating random values.
For example, if I have an array int array[4][4] how would I go through a loop filling the array while checking to make sure that another identical random value isn't placed into another location in the array?
int array[4][4];
int* p = &array[0][0];
std::iota(p, p+16, 1);
std::random_device r;
std::default_random_engine g(r());
std::shuffle(p, p+16, g);
Use int randomValue = rand() % 16 + 1; and store it in another helper 2D array for check purpose. you should be done.
Create a 1-d array, say arr of size 16, populate it with values from 1 to 16. Use shuffle on arr. Traverse through the array to fill the 2-D array, say arr2.
for(int i = 0; i < 16; i++){
arr2[i/4][i%4] = arr[i];
}
Something wired i see here with std vector
I have
variable that its value is dynamically changes but always under 20
dynamicSizeToInsert in the example.
why the vector size keeps growing ?
std::vector<int> v;
//sometimes its 5 sometimes it is 10 sometimes it is N < 20
int dynamicSizeToInsert = 5
int c = 0;
for(std::vector<int>::size_type i = 0; i != 100; i++) {
if(c == dynamicSizeToInsert )
{
c = 0;
}
v.insert(v.begin() + c, c);
c++;
printf("%d",v.size()) //THIS THINK KEEP growing although i only using vector indexes 0 to 4 allways
}
i want to keep my vector side 5 elements big
and that new value will run over other value in the same index .
std::vector::insert, as the name suggests, inserts elements at the specified position.
When c == dynamicSizeToInsert, c is set to 0. So now, v.size() == 5. Now this lines executes:
v.insert(v.begin() + c, c);
This will insert 0 at posistion v.begin() + 0, which is position 0 and it will offset every other element (it will not replace the element at position 0), and so the vector keeps growing.
Instead of using insert, use operator[]:
//So that 'v' is the right size
v.resize(dynamicSizeToInsert);
for(std::vector<int>::size_type i = 0; i != 100; i++) {
if(c == dynamicSizeToInsert )
{
c = 0;
}
v[i] = c; //Sets current index to 'c'
c++;
}
insert doesn't replace element, rather it inserts element at given location and shifts all the right elements to one position right. That's why your vector size is growing.
If you want to replace an existing index then you can use operator[]. However, keep in mind that the index must be between 0 - size() - 1 in order to use operator[].
std::vector::insert inserts a new member into the array at the index you specify, and moving the other elements forward or even reallocating the array once it reaches capacity(a relatively expensive operation)
The vector is extended by inserting new elements before the element at
the specified position, effectively increasing the container size by
the number of elements inserted.
This causes an automatic reallocation of the allocated storage space
if -and only if- the new vector size surpasses the current vector
capacity.
(http://www.cplusplus.com/reference/vector/vector/insert/)
As quoted above, the vector is extended with every insert operation.
to get the behaviour you want you need to use the [] operator like so:
v[i] = some_new_value;
this way a new element is never added, its only the value of the ith element that is changed.
const int dynamicSizeToInsert = 5;
std::vector<int> v(dynamicSizeToInsert);
int c = 0;
for(std::vector<int>::size_type i = 0; i !=100; i++)
{
v.at(i%dynamicSizeToInsert) = (dynamicSizeToInsert == c?c = 0,c ++: c ++);
printf("%d",v.size());
}
I have the following Task: I am doing an implementation of the Cheapest Insertion method and I am storing my subtours into a vector. After building the vector, I Need to find the total length of the distances between the nodes, that are included in the vector (for example I have 0-32-41-3-45-0 stored in the vector). How can I calculate the total distance? I have the following function:
double tLength = 0;
for (vector<int>::iterator i=resultingRoute.begin(); i!=resultingRoute.end();i++)
{
tLength+= distanceMatrix[*i][*i+1];
}
return tLength;
but it is calculating from 0 to 1, then from 32 to 33, 41 to 42, and so on. What I Need is 0 to 32, 32 to 41, 41 to 3. I tried to create a second iterator j to start at.begin()+1, but it is repeating the second part of the function too much.
double tLength = 0;
for (vector<int>::iterator i=resultingRoute.begin(); i!=resultingRoute.end()-1;i++)
{
for(vector<int>::iterator j=resultingRoute.begin()+1;j!=resultingRoute.end();j++)
{
tLength+= distanceMatrix[*i][*j];
}
}
return tLength;
What is the best way to calculate the length of the tour? Thanks.
but it is calculating from 0 to 1, then from 32 to 33, 41 to 42, and
so on
It indeed does it as the *i+1 takes value of *i and adds a 1 to it. You probably wanted to write *(i+1). In that case the condition i!=resultingRoute.end() is incorrect, it should be i!=resultingRoute.end()-1, otherwise the *(i+1) would be out of range for last element. You should also check whether the vector has at least 2 elements before entering the loop.
You can avoid the iterators and work with the vector as if it were an array, without the need to check the vector's size:
for (size_t i = 0; i + 1 < resultingRoute.size(); ++i)
tLength += distanceMatrix[resultingRoute[i]][resultingRoute[i+1]];
Is there a way to get the array index of a 1D array from a 2D array?
For Eg: I have a 2D array, the array size is unknown and changes (I've used std::vector) to push_back as and when required. This works fine as long as its a 2D array but I need to get the 1D array index of this 2D array.
2D array:
Group 1 - 1, 2, 3
Group 2 - 4, 5, 6
Group 3 - 7, 8, 9, 10, 11, 12
and so on.
So, basically is there a quick way to know that when 6 is selected from Group 2 i.e. Array[1][2] = 6 => I need the array index as: 1D array=> Array[5] = 6 => i.e. I need 5 as my answer. I have tried several things but no luck so far. Any suggestions?
If your data is static, you can make another array in which you will store the offset for each 1D array. For your example, you will have the following array offset = {0, 3, 6}. Then you can find the index by offset[row] + col.
If you can change the row sizes, then you can store the size of each row in a Binary indexed tree and find the offset in O(log n) with a single query, where n is the amount of rows (1D vectors). However, each time you change the row size, you would have to update the structure again in O(log n).
If you are creating a vector of vectors (or a list of vectors), the memory locations are not guaranteed to be related. So to make it behave like a 1-dimensional array, you would need to wrap the container in your own class and overload operator[]. That operator would then need to check the index to determine the proper vector element to return. A simplified version might look like:
T& operator[](std::size_t index)
{
std::size_t temp = index;
if (index < myVectors[0].size())
{
return myVectors[0][index];
}
temp = index - myVectors[0].size()
if (temp < myVectors[1].size())
{
return myVectors[1][temp];
}
// etc ...
}
You can simplify it to a loop:
T& operator[](std::size_t index)
{
std::size_t temp = index;
for (std::size_t i = 0; i < myVectors.size(); ++i)
{
if (temp < myVectors[i].size())
{
return myVectors[i][temp];
}
temp -= myVectors[i].size();
}
throw std::out_of_range("Array access out of bounds!");
}
I got this question at an interview and at the end was told there was a more efficient way to do this but have still not been able to figure it out. You are passing into a function an array of integers and an integer for size of array. In the array you have a lot of numbers, some that repeat for example 1,7,4,8,2,6,8,3,7,9,10. You want to take that array and return an array where all the repeated numbers are put at the end of the array so the above array would turn into 1,7,4,8,2,6,3,9,10,8,7. The numbers I used are not important and I could not use a buffer array. I was going to use a BST, but the order of the numbers must be maintained(except for the duplicate numbers). I could not figure out how to use a hash table so I ended up using a double for loop(n^2 horrible I know). How would I do this more efficiently using c++. Not looking for code, just an idea of how to do it better.
In what follows:
arr is the input array;
seen is a hash set of numbers already encountered;
l is the index where the next unique element will be placed;
r is the index of the next element to be considered.
Since you're not looking for code, here is a pseudo-code solution (which happens to be valid Python):
arr = [1,7,4,8,2,6,8,3,7,9,10]
seen = set()
l = 0
r = 0
while True:
# advance `r` to the next not-yet-seen number
while r < len(arr) and arr[r] in seen:
r += 1
if r == len(arr): break
# add the number to the set
seen.add(arr[r])
# swap arr[l] with arr[r]
arr[l], arr[r] = arr[r], arr[l]
# advance `l`
l += 1
print arr
On your test case, this produces
[1, 7, 4, 8, 2, 6, 3, 9, 10, 8, 7]
I would use an additional map, where the key is the integer value from the array and the value is an integer set to 0 in the beginning. Now I would go through the array and increase the values in the map if the key is already in the map.
In the end I would go again through the array. When the integer from the array has a value of one in the map, I would not change anything. When it has a value of 2 or more in the map I would swap the integer from the array with the last one.
This should result in a runtime of O(n*log(n))
The way I would do this would be to create an array twice the size of the original and create a set of integers.
Then Loop through the original array, add each element to the set, if it already exists add it to the 2nd half of the new array, else add it to the first half of the new array.
In the end you would get an array that looks like: (using your example)
1,7,4,8,2,6,3,9,10,-,-,8,7,-,-,-,-,-,-,-,-,-
Then I would loop through the original array again and make each spot equal to the next non-null position (or 0'd or whatever you decided)
That would make the original array turn into your solution...
This ends up being O(n) which is about as efficient as I can think of
Edit: since you can not use another array, when you find a value that is already in the
set you can move every value after it forward one and set the last value equal to the
number you just checked, this would in effect do the same thing but with a lot more operations.
I have been out of touch for a while, but I'd probably start out with something like this and see how it scales with larger input. I know you didn't ask for code but in some cases it's easier to understand than an explanation.
Edit: Sorry I missed the requirement that you cannot use a buffer array.
// returns new vector with dupes a the end
std::vector<int> move_dupes_to_end(std::vector<int> input)
{
std::set<int> counter;
std::vector<int> result;
std::vector<int> repeats;
for (std::vector<int>::iterator i = input.begin(); i < input.end(); i++)
{
if (counter.find(*i) == counter.end())
result.push_back(*i);
else
repeats.push_back(*i);
counter.insert(*i);
}
result.insert(result.end(), repeats.begin(), repeats.end());
return result;
}
#include <algorithm>
T * array = [your array];
size_t size = [array size];
// Complexity:
sort( array, array + size ); // n * log(n) and could be threaded
// (if merge sort)
T * last = unique( array, array + size ); // n, but the elements after the last
// unique element are not defined
Check sort and unique.
void remove_dup(int* data, int count) {
int* L=data; //place to put next unique number
int* R=data+count; //place to place next repeat number
std::unordered_set<int> found(count); //keep track of what's been seen
for(int* cur=data; cur<R; ++cur) { //until we reach repeats
if(found.insert(*cur).second == false) { //if we've seen it
std::swap(*cur,*--R); //put at the beginning of the repeats
} else //or else
std::swap(*cur,*L++); //put it next in the unique list
}
std::reverse(R, data+count); //reverse the repeats to be in origional order
}
http://ideone.com/3choA
Not that I would turn in code this poorly commented. Also note that unordered_set probably uses it's own array internally, bigger than data. (This has been rewritten based on aix's answer, to be much faster)
If you know the bounds on what the integer values are, B, and the size of the integer array, SZ, then you can do something like the following:
Create an array of booleans seen_before with B elements, initialized to 0.
Create a result array result of integers with SZ elements.
Create two integers, one for front_pos = 0, one for back_pos = SZ - 1.
Iterate across the original list:
Set an integer variable val to the value of the current element
If seen_before[val] is set to 1, put the number at result[back_pos] then decrement back_pos
If seen_before[val] is not set to 1, put the number at result[front_pos] then increment front_pos and set seen_before[val] to 1.
Once you finish iterating across the main list, all the unique numbers will be at the front of the list while the duplicate numbers will be at the back. Fun part is that the entire process is done in one pass. Note that this only works if you know the bounds of the values appearing in the original array.
Edit: It was pointed out that there's no bounds on the integers used, so instead of initializing seen_before as an array with B elements, initialize it as a map<int, bool>, then continue as usual. That should get you n*log(n) performance.
This can be done by iterating the array & marking index of the first change.
later on swaping that mark index value with next unique value
& then incrementing that mark index for next swap
Java Implementation:
public static void solve() {
Integer[] arr = new Integer[] { 1, 7, 4, 8, 2, 6, 8, 3, 7, 9, 10 };
final HashSet<Integer> seen = new HashSet<Integer>();
int l = -1;
for (int i = 0; i < arr.length; i++) {
if (seen.contains(arr[i])) {
if (l == -1) {
l = i;
}
continue;
}
if (l > -1) {
final int temp = arr[i];
arr[i] = arr[l];
arr[l] = temp;
l++;
}
seen.add(arr[i]);
}
}
output is 1 7 4 8 2 6 3 9 10 8 7
It's ugly, but it meets the requirements of moving the duplicates to the end in place (no buffer array)
// warning, some light C++11
void dup2end(int* arr, size_t cnt)
{
std::set<int> k;
auto end = arr + cnt-1;
auto max = arr + cnt;
auto curr = arr;
while(curr < max)
{
auto res = k.insert(*curr);
// first time encountered
if(res.second)
{
++curr;
}
else
{
// duplicate:
std::swap(*curr, *end);
--end;
--max;
}
}
}
void move_duplicates_to_end(vector<int> &A) {
if(A.empty()) return;
int i = 0, tail = A.size()-1;
while(i <= tail) {
bool is_first = true; // check of current number is first-shown
for(int k=0; k<i; k++) { // always compare with numbers before A[i]
if(A[k] == A[i]) {
is_first = false;
break;
}
}
if(is_first == true) i++;
else {
int tmp = A[i]; // swap with tail
A[i] = A[tail];
A[tail] = tmp;
tail--;
}
}
If the input array is {1,7,4,8,2,6,8,3,7,9,10}, then the output is {1,7,4,8,2,6,10,3,9,7,8}. Comparing with your answer {1,7,4,8,2,6,3,9,10,8,7}, the first half is the same, while the right half is different, because I swap all duplicates with the tail of the array. As you mentioned, the order of the duplicates can be arbitrary.