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.
Related
I am relatively new to C++, and currently writing a function that involves inputting a number of new value(s) into a sorted array. When the new value is put into the array, it needs to maintain it's sort in ascending order. This has to be done using two arrays (the original array, and a "destination" array that will contain the new, sorted value). I'm completely at a loss on how to go about this.
Everything that I have to do must be within the iostream and iomanip libraries.
This is all I have so far:
int insert_into_sorted (int source[], int source_len, int destination[], int new_elem){
int offset = 0;
for (int i = 0; i <= source_len; i++)
{
if (new_elem < source[i])
{
source[i] = destination[i + offset];
}
else
{
return 1;
}
}
}
I don't entirely know what I'm doing, at all. I have made a for loop, and an if statement within that for-loop.
When I execute the program, I input a test value. Based on what test value I enter, a certain new value is inputted.
EX: If I do test 1, it inputs a value of 15 within an array of 10,20. The 15 needs to go into the array of 10,20 while also being in ascending order.
However, my output contains:
Original array (10,20)
New array (-1,-1, 4255009);
I have tried rearranging statements, different return values, with slightly different outputs--but again, I'm so lost that I'm not sure what this is even doing in terms of how my program is running. Because it's a function and I cannot edit main, it's a bit difficult to test what is happening step-by-step.
I'll assume that destination is large enough to contain the additional element.
You will probably want to first compare new_elem to each element of source before copying. If source[i] > new_elem, then you'll want to copy new_elem to destination instead of source[i] - this is to ensure that new_elem gets copied before an element larger than it and after an element smaller than it (which is how sorting works), and set a flag to tell the function to copy the rest of the elements regularly - that way, you don't keep recopying new_elem over and over again.
The code would probably look something like this (I'm only giving the pseudocode, not the actual code itself):
set `new_element_copied` to False
for each element in `source`:
if the current element > `new_elem` and `new_element_copied` is not True:
copy `new_elem` to `destination`
copy current element to `destination` //so as not to skip an element
set `has_new_element_been_copied` to True
else
copy current element to `destination`
(the ` characters indicate variable names)
Also, make sure that when you're iterating over an array in C++, you use < not <=. Arrays are 0-indexed, so arr[10] would get the 11th element in arr.
Edit
If you don't end up copying new_elem in your for loop, make sure to copy it at the end by checking if new_element_copied is still False:
set `new_element_copied` to False
for each element in `source`:
...
if `new_element_copied` is False: //indicates element was not copied
copy `new_elem` to `destination`
Edit 2: Make sure to keep a seperate variable for the index of destination, as using the same index for both source and destination will screw you up
I'm new to C++, and what I have to do is to write a method that checks if a 2D array contains any duplicate items.
So for example, I have a matrix[3][4], I've been able to compare the first element [0][0] with the rest, till the last one [2][3].
The problem is that I don't know how to proceed, what I should do is that the method then compares the element [0][1] with the rest (except with the previous one and itself of course) and etc..
First of, the fact that it's a 2D array is irrelevant in this context; you want to find duplicates across the entire array, so you'd be better of with 1-dimensional indexing anyway. Coincidentally, that's a suggested way of handlings two-dimensional arrays in C++.
So assuming you can put the indices in some order, the general idea is to check every element with all subsequent elements. This will give you O(n2). A pseudocode is, unsurprisingly, two loops, and is a common pattern used e.g. for collision detection:
for (iterA = 0; iterA < num - 1; iterA++) {
for (iterB = iterA + 1; iterB < num; iterB++) { // note how iterB starts one further
if (*iterA == *iterB)
return true; // found a duplicate
}
}
In case of a 2D array, the *iterA dereference can be replaced with a function that breaks up the composite 1-dimensional index into two components, e.g. with i % width, i / width. This is, again, a very common pattern.
That being said, why bother? Make an std::set, start putting elements one-by-one and call find before every insert. If find returns something, break.
I'm trying to learn Nim by converting different pieces of code, and I've stumbled upon something which I've never seen before.
#include<bits/stdc++.h>
...
for(int t=q&1?u+x:u+x>>1;t>1;)t/=p[++cnt]=sieve[t];
...
sort(p+1,p+cnt+1);
I understand what the ternary operator is and how it works, what I don't quite get is what's going on with the variables "t" and "cnt" (both integers) and the array "p" (an array of integers). How does using an increment as the index of "p" work?
Then there's the sort function, in which I completely gave up because I couldn't find any documentation on what it does (the fact that it's taking an integer added to an array obviously doesn't help).
Lets first start of by making the code a little more readable. A little bit of whitespace never hurt anybody.
for(int t = (q & 1? u + x: u + x >> 1); t > 1;)
{
t /= p[++cnt] = sieve[t];
}
what's going on with the variables "t" and "cnt" (both integers) and the array "p" (an array of integers)
So t is being set to either u + x or u + x >> 1 depending on what q & 1 is. Then inside the loop we are dividing t by whatever the value of sieve at the index of t is. We are also assign that value to the p array at the position of ++cnt. ++cnt is using the pre increment operator to increase the value of cnt by 1 and then using that value for the index of p.
Then there's the sort function, in which I completely gave up because I couldn't find any documentation on what it does
For this I am assuming they are using the std::sort() function. When dealing with arrays the name of the array is treated as a pointer to the first element of the array. So when we see sort(p+1,p+cnt+1); you can translate it to sort(one from the begining of the array, cnt + 1 elements from the begining of the array);. So this is going to sort all of the elements in the array from one from the begining of the array to one less than cnt + 1 elements from the begining of the array.
Are you trying to learn Nim as you said, or trying to learn C? Both things you asked about are pretty basic c:
++cnt has the side effect (cnt=cnt+1) combined with the value that cnt ends up with. That value is used as the index. The side effect is a side effect.
p+1 and p+cnt are each pointers. The name of an array is treated as a constant pointer to the first element of that array in most uses within C. A pointer plus an integer is another pointer, pointing that number of elements past the original.
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.
I have to implement my own sort on a dynamic string array, e.g. of such array is:
string * sortArray;
I then read in the size of the array from a text file and make the array as long as needed and fill it. So, I have...
sortArray = new string[_numberOfNames];
for(int i = 0; i < _numberOfNames; ++i){
sin >> _data[i];
}
Now I need to create my own sorting method and I thought I'd go with quicksort. My problem is, I'm not sure how to go about it.
When I choose a pivot, how can I then go about setting up two more dynamic string arrays to put the lower values and highers values in to, then recurse on? There is no way of knowing before hand how big each array needs to be before I start putting values into them.
I thought I could do something like define the size of each array as being the same as the array being sorted, and then some how remove any unwanted empty spaces from the end, but I'm not sure this is possible?
Any help would be much appreciated.
P.S. I know about the std::sort, I already have this in the program, I'm just trying to implement a sort myself.
Two options as from the comments above:
1.) Use std::vector. There you can have variable size arrays.
2.) Use an "in place" version of quicksort that does the sorting in your original array. See http://en.wikipedia.org/wiki/Quicksort#In-place_version
Lets say you have array size N
and you pivot value is x
what you should do is like that, have two pointers one to the beginning(0) and one to the end (N-1). they should both move to the middle. when ever the beginning pointer value is greater than x and the end pointer value is lower than x switch their values. after you finished and placed x in his new location (where the two pointers met) continue recursionally for the part left to x and right to x.