How to set configuration parameters using an array table? - c++

Following situation: I have an array with some constant values, which represent ranges.
A range is always between two values in the array, e.g.: 10 - 20 = range1
20-30 = range2 and so on...
const int arr[] = {10, 20, 30, 40, 50, 60};
With a Search function, I search for the number(val) between those ranges in arr[] and return the range index where val was found.
For example: if val = 15 → return value would be 1
if val = 33 → return value would be 3
int Search(const int arr[], int n, int val)
{
int i = 0;
while (i < n) {
if (val > arr[i])
++i;
else
return i;
}
return -1;
}
OK, this works out so far...
Now following problem:
I have some parameters let's call them x, y, z which are simple integers and they depend on the value of val.
The parameter values for x, y, z I know already before compilation, of course they are different for every range.
How can I now set x, y and z using the range index?
How can I make an array for example with the constant parameter values for x, y, z and set them depending on the returned range index? Or should it be a struct?
How would that look like...?
Thx

You could hold the parameters for each range in a struct:
struct range_parameters {
int x;
int y;
// etc
}
And keep all these structs in a std::vector:
std::vector<range_parameters> params;
Adding the data would be done like this:
range_parameters params_for_range_1;
params_for_range_1.x = 1;
params_for_range_1.y = 2;
params[0] = params_for_range_1;
So finally you can access the parameters for range n as params[n-1].

Related

Create a array of structs

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;
}

Cast from int to char

I'd like to know how this cast works :
int value = 100;
auto f = [&value] (int x, int y) -> char { return x + y + value; };
printf("%d\n", f(10, 20));
value = 200;
printf("%d\n", f(10, 20));
return 0;
It prints -126 and -30 but i don't understand how is it possible to print a negative integer.
The numerical range for char is -128..127. 10 + 20 + 100 is 130 and outside of that range, so it wraps around when expressed as char.
To fix you need to use a data type that can contain values large enough:
auto f = [&value] (int x, int y) -> int { return x + y + value; };
Or use values < 127.

Returning the actual value of maximum of absolutes of variables

I want to find the maximum of the absolute of two variables, and return the actual value of that variable, rather than the absolute value of that variable.
For example:
int x = 3;
int y = -5;
int z = max(abs(x), abs(y))
Will just set z to 5, whereas I want it to return -5. Is there a C++ function to perform this?
If you're using C++11, with the STL you could use a vector of int, max_element and a lambda Compare
std::vector<int> values = {3, -5};
int largest_abs = *std::max_element(values.begin(), values.end(), [](const int& a, const int& b)
{
return abs(a) < abs(b);
});
This returns the iterator between the start and end of values, whose absolute value is the largest. (this is found through the comparator) The * is then used to convert the iterator (returned by std::max_element) to an int
It's not a commonly used function, but writing your own function is trivial.
int max_abs(int x, int y)
{
if (x == INT_MIN || y == INT_MIN)
return INT_MIN;
return (abs(x) > abs(y)) ? x : y;
}
int z = (max(abs(x), abs(y)) == abs(x)) ? x : y;
This is like an if-condition. Its equivalent to
int z = x;
if(max(abs(x), abs(y)) != abs(z))
z = y;
But much shorter.
There is no function in the STL to fit into your needs directly, so you need to make your own and this one could be one version.
A more handy one can be int z = (abs(y) < abs(x)) ? x : y thought.

Returning multiple values and default parameters in C++

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.

Reverse map a functional relation(c++)

I am using a simple function (y(x)), and I want to generate an x value from a certain y value. While typically reverse mapping does not give a single x value, I am using the maximum from my y values. This means that there will be a unique x value for the y value I input(the maximum). I don't understand how to code this in c++
If you don't need interpolation, only exact reverse lookup, then it's relatively straighforward:
std::map<YType, XType> lookup;
// (code to read the file goes here)
// for each x {
YType y = f(x);
if ((lookup.count(y) == 0) || (lookup[y] < x)) {
lookup[y] = x;
}
// }
Then your reverse lookup is just lookup[y], which will return 0 (or a default-constructed value where applicable) if y in fact was missing from the data.
Be aware that my code is a bit inefficient, it looks up y several times in the map, up to 3. You can optimize using iterators, but I'm concerned that obscures what's going on if you're not already familiar with them:
typedef std::map<YType, XType> maptype;
typedef std::pair<maptype::iterator, bool> resulttype;
resulttype result = lookup.insert(std::make_pair(y, x));
if (!result.second) {
// key already existed, so value was not inserted. Check for max.
maptype::iterator pos = result.first;
if ((*pos).second < x) {
(*pos).second = x;
}
}
If I understand correctly, you are given a finite range of values x, say x[0], x[1], ..., x[N], and a function f, and you want to find the index k for which f(x[k]) is the largest possible. In that case, a simple search will do:
size_t k = 0;
T m = f(x[k]);
T tmp;
for (size_t i = 1; i <= N; ++i)
{
if ((tmp = f(x[i])) > m)
{
k = i;
m = tmp;
}
}
// Maximum is (x[k], m)
Here T is the type such that f is T f(T);