I have a problem with my code. It is intended to save the values into a struct array. But 2 things happen at random - 1) Array may be empty or 2) Array may contain only one row of values.
struct MacroMas
{
int x;
int y;
int Delay;
int SemiAutoDelay;
int ammo;
MacroMas* Cords(int x, int y, int Delay)
{
MacroMas _ret;
_ret.x = x;
_ret.y = y;
_ret.Delay = Delay;
return _ret;
}
};
MacroMas* temp()
{
MacroMas _ret;
MacroMas* macroMasArray = new MacroMas[107];
for (int index = 0; index <107 ; ++index)
macroMasArray[index] = MacroMas();
macroMasArray[0].Cords(-3, 4, 16);
macroMasArray[1].Cords(-3, 4, 17);
// Some more code
return macroMasArray;
First in Cords function : function will return MacroMas* and you return an object of type MacroMas it's mistake in your Code.
in these two lines you make a mistake
macroMasArray[0].Cords(-3, 4, 16);
macroMasArray[1].Cords(-3, 4, 17);
Cords function has return value
When macroMasArray[0] or [1] calls Cords its not affect on them.
you need to store them like
macroMasArray[0] = macroMasArray[0].Cords(-3, 4, 16);
or use this pointer in the Cords Body.
void Cords(int x, int y, int Delay)
{
this->x = x
this->y = y;
this->Delay = Delay;
}
Related
I am attempting an online coding challenge wherein I am to implement a pathfinding algorithm that finds the shortest path between two points on a 2D grid. The code that is submitted is tested against a number of test cases that I, unfortunately, am unable to see, but it will however tell me if my answer for shortest distance is correct or not. My implementation of the A* algorithm returns a correct answer on 2/3 test cases and I cannot seem to figure out what scenario might create an incorrect answer on the third?
I have tried several of my own test cases and have gotten correct answers for all of those and at this point am feeling a little bit lost. There must be something small in my code that I am not seeing that is causing this third case to fail.
More details
The grid is w by h and contains only 1's (passable) and 0's (impassable) with every edge having a cost of 1 and the pathway cannot move diagonally
It all starts with the FindPath function which is to return the length of the shortest path, or -1 if no path is available
pOutBuffer is used to contain the path taken from beginning to end (excluding the starting point). If multiple paths are available then any will be accepted. So it isnt looking for one path in particular
I know the issue is not the result of time or memory inefficiency. I has to be either the distance returned is incorrect, or the values in pOutBuffer are incorrect.
Any help would be greatly appreciated as I am just about out of ideas as to what could possibly be wrong here. Thank you.
#include <set>
#include <vector>
#include <tuple>
#include <queue>
#include <unordered_map>
inline int PositionToIndex(const int x, const int y, const int w, const int h)
{
return x >= 0 && y >= 0 && x < w && y < h? x + y * w : -1;
}
inline std::pair<int, int> IndexToPosition(const int i, const int w)
{
return std::make_pair<int, int>(i % w, i / w);
}
inline int Heuristic(const int xa, const int ya, const int xb, const int yb)
{
return std::abs(xa - xb) + std::abs(ya - yb);
}
class Map
{
public:
const unsigned char* mapData;
int width, height;
const std::vector<std::pair<int, int>> directions = { {1,0}, {0,1}, {-1,0}, {0,-1} };
Map(const unsigned char* pMap, const int nMapWidth, const int nMapHeight)
{
mapData = pMap;
width = nMapWidth;
height = nMapHeight;
}
inline bool IsWithinBounds(const int x, const int y)
{
return x >= 0 && y >= 0 && x < width && y < height;
}
inline bool IsPassable(const int i)
{
return mapData[i] == char(1);
}
std::vector<int> GetNeighbours(const int i)
{
std::vector<int> ret;
int x, y, neighbourIndex;
std::tie(x, y) = IndexToPosition(i, width);
for (auto pair : directions)
{
neighbourIndex = PositionToIndex(x + pair.first, y + pair.second, width, height);
if (neighbourIndex >= 0 && IsWithinBounds(x + pair.first, y + pair.second) && IsPassable(neighbourIndex))
ret.push_back(neighbourIndex);
}
return ret;
}
};
int FindPath(const int nStartX, const int nStartY,
const int nTargetX, const int nTargetY,
const unsigned char* pMap, const int nMapWidth, const int nMapHeight,
int* pOutBuffer, const int nOutBufferSize)
{
int ret = -1;
// create the map
Map map(pMap, nMapWidth, nMapHeight);
// get start and end indecies
int targetIndex = PositionToIndex(nTargetX, nTargetY, nMapWidth, nMapHeight);
int startIndex = PositionToIndex(nStartX, nStartY, nMapWidth, nMapHeight);
// if start and end are same exit
if (targetIndex == startIndex) return 0;
std::unordered_map<int, int> pathway = { {startIndex, startIndex} };
std::unordered_map<int, int> distances = { {startIndex, 0} };
// queue for indecies to process
typedef std::pair<int, int> WeightedLocation;
std::priority_queue<WeightedLocation, std::vector<WeightedLocation>, std::greater<WeightedLocation>> queue;
queue.emplace(0, startIndex);
while (!queue.empty())
{
int currentWeight, currentIndex;
std::tie(currentWeight, currentIndex) = queue.top();
queue.pop();
if (currentIndex == targetIndex)
break;
int newDistance = distances[currentIndex] + 1;
for (int n : map.GetNeighbours(currentIndex))
{
if (distances.find(n) == distances.end() || newDistance < distances[n])
{
distances[n] = newDistance;
int weight = newDistance + Heuristic(n % nMapWidth, n / nMapWidth, nTargetX, nTargetY);
queue.emplace(weight, n);
pathway[n] = currentIndex;
}
}
}
if (pathway.find(targetIndex) != pathway.end())
{
int current = targetIndex;
while (current != startIndex)
{
int outIndex = distances[current] - 1;
pOutBuffer[distances[current] - 1] = current;
current = pathway[current];
}
ret = distances[targetIndex];
}
return ret;
}
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 2 years ago.
So, I am having some trouble rewriting a C++ class I made in C.
The C++ class has some private attributes:
int grid_width;
int grid_height;
const int group_width = 2;
const int group_height = 4;
std::vector<int> buffer;
It is initialized like so:
grid::grid(int width, int height) {
this->grid_width = width;
this->grid_height = height;
buffer.resize(this->grid_width / this->group_width * this->grid_height / this->group_height, 0);
}
It also comes with a clear function like so:
void grid::clear() {
// get_buffer_size returns elements in the buffer vector
for (int i = 0; i < get_buffer_size(); ++i) {
buffer[i] = 0x00;
}
}
Now, my attempt to rewrite this in C looks somewhat like this:
typedef struct
{
int width;
int height;
int *buffer;
} grid;
grid *grid_new(int grid_width, int grid_height)
{
if ((grid_width % 2 != 0) || (grid_height % 4 != 0))
return NULL;
int group_height = 4;
int group_width = 2;
grid *p_grid = calloc(grid_width / group_width * grid_height / group_height, sizeof(int));
p_grid->width = grid_width;
p_grid->height = grid_height;
return p_grid;
}
void grid_free(grid *p_grid)
{
free(p_grid->buffer);
free(p_grid);
}
void grid_clear(grid *g)
{
// ToDo: Iterate over all elements in the buffer
int elements = sizeof(g->buffer) / sizeof(int);
printf("Elements: %i", elements);
}
But for some reason, the amount of elements in my C code is always 2?
Does anyone know where I am messing up?
If the grid is initialized with 4 and 8, the expected buffer size should be 4, not 2. If it would be initialized with 10 and 24, the expected size would be 30, but it still remains 2 in my C example.
Your grid_new is allocating an array of grid structs and not a single grid with the correct number of elements.
You need to set buffer
Also, the number of elements in the grid is based on width/height and not sizeof(g->buffer) which is the size of the pointer and not the area to which it points
Here's the refactored code:
const int group_height = 4;
const int group_width = 2;
typedef struct {
int width;
int height;
int *buffer;
} grid;
grid *
grid_new(int grid_width, int grid_height)
{
if ((grid_width % 2 != 0) || (grid_height % 4 != 0))
return NULL;
grid *p_grid = calloc(1,sizeof(*p_grid));
// FIXME -- why???
grid_width /= group_width;
grid_height /= group_height;
p_grid->width = grid_width;
p_grid->height = grid_height;
p_grid->buffer = calloc(grid_width * grid_height,sizeof(int));
return p_grid;
}
void
grid_free(grid *p_grid)
{
free(p_grid->buffer);
free(p_grid);
}
void
grid_clear(grid *g)
{
// ToDo: Iterate over all elements in the buffer
int elements = g->width * g->height;
printf("Elements: %i", elements);
}
'sizeof' returns the number of bytes that specified type takes. in this case sizeof(g->buffer) is equal to sizeof(int*) and because you are using x64 processor sizeof all pointers is 8.
I'm looking for some help finding all clusters of chars in the string in C++. The exact task is:
Given the following “2D string” (in C++ expression):
string text =
"#################aa##a###c######\n" +
"####bbbbaaaabbbbbaaaaa###ccc##cc\n" +
"#o##bbbbaaaabbbbbaaaaa###c#c##cc\n" +
"#oo#bbbbaeeabbbbbbbbaa##cc#ccccc\n" +
"#o##bbbbaeeabbbbbaaaaaa#cc#####c\n" +
"#o##bbbbaaaabbbbbaaaaaa#cc#####c\n";
Write a program computing the area of each contiguous region of the same >symbols. Two equal symbols belong to the same area if they are neighbors either >in a row or in a column. Don’t count the newline (\n) symbols, they are just to >form the 2D string.
The main function should be recursive.
Hint: use an extra 2D array to mark each symbol in the 2D string if it is >already counted or not. Scan the array row-wise until a not counted yet symbol >is found. Then, run the recursive area-computing function starting from this >symbol. Continue until all symbols are marked as counted.
The program output should look (more or less) like:
Region of symbols #, area …
Region of symbols a, area …
Region of symbols #, area …
Region of symbols c, area …
My current code looks like this:
#include <iostream>
#include <string>
using namespace std;
int cords (string str, int x, int y) {
int length, i, position, lines = 0, x_max, y_max;
char symbol;
length = str.length();
for (i = 0; i < length; i++) {
symbol = str[i];
if (symbol == '\n')
lines++;
}
length -= lines;
x_max = length / lines;
y_max = length / x_max;
position = x - 1 + (y - 1) * x_max + y - 1;
if (x <= x_max && y <= y_max)
return position;
}
int clusterMiner (char symbol, string str, int x, int y, int counter, int last) {
if (x > 32 || y > 6) {
return counter;
} else {
if (str[cords(str, x++, y)] == symbol) {
counter++;
return clusterMiner(symbol, str, x++, y, counter, x);
} else if (str[cords(str, 1, y++)] == symbol) {
return clusterMiner(symbol, str, 1, y++, counter, x);
}
}
}
int main () {
int length, lines, i, j, k, l, counter;
string text = // 32 elements per line
"#################aa##a###c######\n" // 32
"####bbbbaaaabbbbbaaaaa###ccc##cc\n" // 64
"#o##bbbbaaaabbbbbaaaaa###c#c##cc\n" // 96
"#oo#bbbbaeeabbbbbbbbaa##cc#ccccc\n" // 128
"#o##bbbbaeeabbbbbaaaaaa#cc#####c\n" // 160
"#o##bbbbaaaabbbbbaaaaaa#cc#####c\n"; // 192
counter = clusterMiner('#', text, 1, 1, 0, 0);
cout << counter;
return 0;
}
Cords function is just for easier interaction with the two dimensions of the string.
I'm not sure what to do next. Right now the program counts only some of the symbols as it stops at the first different one ignoring these which are connected to further nodes.
Thanks!
First, do not calculate x_max and y_max all the time newly, just do it once and store it in a variable. Then, you will have to iterate over the whole field:
char get(int x, int y)
{
// + 1: the newline!!!
return field[x + y * (x_max + 1)];
}
void countAll()
{
calculateMaxima();
// created your visited array now
for(unsigned int y = 0; y <= y_max; ++y)
{
for(int x = 0; x <= x_max; ++x)
{
if(!visited[x, y])
{
count = 0;
search(get(x, y), x, y);
// output count here...
}
}
}
}
Each time we hit a character not yet visited, i. e. a new one, we start a new search. For each search, we have to consider four neighbours for each current position {x, y}:{x +/- 1, y} and {x, y +/- (x_max + 1} (apart from the positions at the edges, which have less). So your search might look like this:
void visit(char symbol, int x, int y)
{
if(!visited[x][y] && get(x, y) == symbol)
{
++count;
++visited[x][y] = true;
}
search(symbol, x, y);
}
void search(char symbol, int x, int y)
{
if(x > 0)
visit(x - 1, y);
if(x < max_x)
visit(x + 1, y);
if(y > 0)
visit(x, y - 1);
if(y < max_y)
visit(x, y + 1);
}
For now, I am assuming count, visited and x/y_max being some global variables. Cleaner, as we are C++, would be writing a separate class for this purpose:
class ClusterMiner
{
unsigned int count;
std::string field;
// ...
void visit(char symbol, int x, int y);
void search(char symbol, int x, int y);
// ...
public:
void countAll();
};
Code is untested and incomplete, it shall only give you the necessary hints to find your way...
Side note: If you have unconnected regions of the same character, these will be detected as such. If this is not desired, you might sum up the results e. g. in a std::map<char, unsigned int> and iterate over this one after you finished counting...
It is possible to store and wrap member functions with std::mem_fn.
In C you can use offsetof(...) on a member variable to crudely wrap a member variable (but only on a some types).
Is it possible to wrap a member variable in C++? What's the cleanest way?
ie
class X
{
...
M m;
...
};
mem_var<M> xm = &X::m;
int main()
{
X x = ...;
M i = ...;
xm(x) = i; // same as x.m = i
cout << xm(x); // same as cout << x.m
}
Yes, you can do it with... std::mem_fn.
struct B
{
int x;
int y;
};
int main()
{
auto m = std::mem_fn(&B::y);
B b {0, 0};
m(b) = 4;
printf("%d %d\n", b.x, b.y); // prints 0 4
printf("%d\n", m(b)); // prints 4
return 0;
}
Demo: http://ideone.com/40nI2
I'm trying to make a function that takes in either 1 or 3 parameters, and returns either 1 or 3 values (based on parameters passed).
If 1 parameter is passed then the function uses default values for the other 2 arguments.
If 3 parameters are passed then it uses those values.
bool foo( bool x, int &y = 0, int &z = 0) {
x = true; y = y + 1; z = z + 2;
return x;
}
Is this possible in C++ or am I confused with Java functions.
You can do it with two functions:
bool foo( bool x, int &y, int &z) {
x = true; // this isn't really what it does, is it?
y = y + 1; z = z + 2;
return x;
}
bool foo(bool x)
{
int a = 0, b = 0;
return foo(x,a,b);
}
Any function always returns only 1 value. Returning 2 or more values is not possible directly.
Indirectly, it happens when you pass parameters by reference. Since the two parameters &y and &z are passed by references, hence changes to them can be reflected back directly.
You can do this by passing by reference..
by doing so you are making a method that points to a memory location.
When that memory location is changed, then your value is changed.
Link
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr233.htm
You cannot do that this way. You can, however, overload that function with different number of parameters, and return, maybe, a std::vector or std::list with the results.
EDIT:
Being more sophisticated, you can use tuples for that:
typedef boost::tuple<bool,int,int> my_data_t;
my_data_t my_tuple(true, 1, 0);
then, you define your function like this:
bool foo( my_data_t & t)
{
t.get<0>() = true;
int& y = t.get<1>();
y = y+1;
int& z = t.get<2>();
z = z+2;
return t.get<0>();
}
and call it this way:
bool result = foo ( my_tuple );
then, out of the function, you'll see my_tuple.get<1>() (the corresponding to y) as 2 (1+1).
I am not sure what you are trying to do, but you can kind of return multiple values of different type using boost::tuple.
boost::tuple<bool, int, int> foo( bool x, int y = 0, int z = 0) {
x = true; y = y + 1; z = z + 2;
return boost::make_tuple(x, y, z);
}
int main() {
boost::tuple<bool, int, int> result = foo(x, 1, 2);
std::cout << boost::get<0>(result) << boost::get<1>(result) << boost::get<2>(result);
}
You could also use boost::optional, if you only want to return x, if only 1 parameter is passed.
Btw. tuple is available in C++11 too.