How to write multiple if conditions - c++

I have two variables A and B and I want to write a code where if one of the two variables is equal to
151 or 156 or 720
and the other is not equal to one of these numbers then a third variable C = 0 is equal to one.
So for example
1) if A = 151 and B = 700 then C = 1
2) if A = 151 and B = 720 then C = 0
3) if A = 140 and B = 700 then C = 0
This is the code
int A = 0
cin >> A;
int B = 0
cin >> B;
int C=0;
int DECKlist[3] = {151,156,720}
for(int d=0; d<3;d++){
if(A== DECKlist[d]){
for(int w=0; w<3;w++){
if(B==DECKlist[w]) C=0;
else C=1;
}
}
if(B== DECKlist[d]){
for(int w=0; w<3;w++){
if(A==DECKlist[w]) C=0;
else C=1;
}
}
}
Is this OK? There are other better ways of doing it?

This is an exclusive OR, XOR. There is no logical XOR in C++, but you can use the bit-wise XOR for your case and exploit the fact that the result of a logical operator is a bool which will map to 0 or 1:
#include <iostream>
int main()
{
int A, B, C;
std::cin >> A;
std::cin >> B;
A = (A == 151 || A == 156 || A == 720);
B = (B == 151 || B == 156 || B == 720);
C = A ^ B;
std::cout << C << std::endl;
}
I've used a simple expression here to check whether a number is one of three supplied numbers. For larger sets of numbers to check against, you could use a, well, std::set.

You can use standard algorithms. For example you could use standard algoritnm std::binary_search along with bitwise XOR operator because array DECKlist is sorted
#include <algorithm>
#include <iterator>
//...
int DECKlist[] = { 151, 156, 720 };
//...
if ( std::binary_search( std::begin( DECKlist ), std::end( DECKlist ), A ) ^
std::binary_search( std::begin( DECKlist ), std::end( DECKlist ), B ) )
{
C = 1;
}
In this case you may add new values in the array and the approach will work as usual correctly. It does not depend on "magic numbers" and their quntity.:)

How about
int c=0;
for(int i=0; i<3; i++){
if(A == DECKlist[i]) c++;
if(B == DECKlist[i]) c++;
}
c = c%2;
Basically, count the number of matches, then make it zero if it was 2.

The first thing I'd do is hide the searching code. Here is a bit of C++ that will search an array (or any other container) linearly for if a given value is there. It uses a two C++11 features: std::begin and std::end, and auto typed variables:
#include <algorithm>
#include <utility>
#include <iterator>
template<class Array, class T>
bool find_in( Array const& arr, T const& t ) {
using std::begin; using std::end;
const auto b = begin(arr);
const auto e = end(arr);
const auto it = std::find( b, e, t ); // search the range for t
return !(e != it);
}
find_in is passed an array and a value, and returns true if that value is in the array.
We then use the same preamble. I avoid using namespace std; because it is a bad habit -- just name things with std:: or import individual symbols within a function scope.
#include <iostream>
int main() {
int A = 0
std::cin >> A;
int B = 0
std::cin >> B;
int C=0;
int DECKlist[3] = {151,156,720};
bool A_in_list = find_in(DECKlist, A);
bool B_in_list = find_in(DECKlist, B);
if (A_in_list != B_in_list)
C = 1;
std::cout << C << "\n";
}
The searching code, because I put it in a helper function, is really clean in the "core" logic of the program.
As we want to know when one is in the list, but not the other, we just compare the results using !=.

Related

I encountered the 10^9+7 problem but I can't understand the relation between the distributive properties of mod and my problem

Given 3 numbers a b c get a^b , b^a , c^x where x is abs diff between b and a cout each one but mod 10^9+7 in ascending order.
well I searched web for how to use the distributive property but didn't understand it since I am beginner,
I use very simple for loops so understanding this problem is a bit hard for me so how can I relate these mod rules with powers too in loops? If anyone can help me I would be so happy.
note time limit is 1 second which makes it harder
I tried to mod the result every time in the loop then times it by the original number.
for example if 2^3 then 1st loop given variables cin>>a,a would be 2, num =a would be like this
a = (a % 10^9 + 7) * num this works for very small inputs but large ones it exceed time
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
long long a,b,c,one,two,thr;
long long x;
long long mod = 1e9+7;
cin>>a>>b>>c;
one = a;
two = b;
thr = c;
if (a>=b)
x = a - b;
else
x = b - a;
for(int i = 0; i < b-1;i++)
{
a = ((a % mod) * (one%mod))%mod;
}
for(int j = 0; j < a-1;j++)
{
b = ((b % mod) * (two%mod))%mod;
}
for(int k = 0; k < x-1;k++)
{
c = ((c % mod) * (thr%mod))%mod;
}
}
I use very simple for loops [...] this works for very small inputs, but large ones it exceeds time.
There is an algorithm called "exponentiation by squaring" that has a logarithmic time complexity, rather then a linear one.
It works breaking down the power exponent while increasing the base.
Consider, e.g. x355. Instead of multiplying x 354 times, we can observe that
x355 = x·x354 = x·(x2)177 = x·x2·(x2)176 = x·x2·(x4)88 = x·x2·(x8)44 = x·x2·(x16)22 = x·x2·(x32)11 = x·x2·x32·(x32)10 = x·x2·x32·(x64)5 = x·x2·x32·x64·(x64)4 = x·x2·x32·x64·(x128)2 = x1·x2·x32·x64·x256
That took "only" 12 steps.
To implement it, we only need to be able to perform modular multiplications safely, without overflowing. Given the value of the modulus, a type like std::int64_t is wide enough.
#include <iostream>
#include <cstdint>
#include <limits>
#include <cassert>
namespace modular
{
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t;
}
int main()
{
std::int64_t a, b, c;
std::cin >> a >> b >> c;
auto const x{ b < a ? a - b : b - a };
std::cout << modular::exponentiation(a, b) << '\n'
<< modular::exponentiation(b, a) << '\n'
<< modular::exponentiation(c, x) << '\n';
return 0;
}
namespace modular
{
constexpr std::int64_t M{ 1'000'000'007 };
// We need the mathematical modulo
auto from(std::int64_t x)
{
static_assert(M > 0);
x %= M;
return x < 0 ? x + M : x;
}
// It assumes that both a and b are already mod M
auto multiplication_(std::int64_t a, std::int64_t b)
{
assert( 0 <= a and a < M and 0 <= b and b < M );
assert( b == 0 or a <= std::numeric_limits<int64_t>::max() / b );
return (a * b) % M;
}
// Implements exponentiation by squaring
auto exponentiation(std::int64_t base, std::int64_t exponent) -> std::int64_t
{
assert( exponent >= 0 );
auto b{ from(base) };
std::int64_t x{ 1 };
while ( exponent > 1 )
{
if ( exponent % 2 != 0 )
{
x = multiplication_(x, b);
--exponent;
}
b = multiplication_(b, b);
exponent /= 2;
}
return multiplication_(b, x);
}
}

Can I make enumerations of variables in if statemants?

I am trying to learn C++ (Beginner). But I wonder how I can make an enumeration of variables in statements like if.
Do I just put a comma between variables?
What is the right syntax for this.. or is this all good?
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d, e;
cin >> a >> b >> c >> d >> e;
if (a, b, c > e && a, b, c > d)
{
cout << a + b + c;
}
}
No, there is nothing in C++ like that. You'll need to split each of those into their own statement, like:
if (a > e && b > e && c > e && a > d && b > d && c > d){
However, the logic here can be simplified.
If you want a > e AND a > d, then you only need to show that a is greater than the larger of e and d. The reverse is true for a, b and c. In other words, you only need to check that the smallest of a/b/c is greater than the largest of e/d.
So this can become:
if (min({a, b, c}) > max(e, d)){
You can not do what you have tried there in the code.
The obvious way (beginner)way has been shown in the #scohe001's answer. However, when you learn at some point the templates and fold expressions, the following solution would be much compact and similar to what you have tried to do.
#include <iostream>
#include <utility>
template<typename... Args>
constexpr bool all_of_greater(const int lhs, Args&&... rhsArgs)
{
return ((lhs < std::forward<Args>(rhsArgs)) && ...);
}
Now you could do similar to what you have done in the code:
if (all_of_greater(e, a, b, c) && all_of_greater(d, a, b, c))
{
std::cout << a + b + c;
}
(See Online Demo)
Here's a reworked approach where the "values" and the "targets" are split into two separate vector structures to ease comparison:
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
// Helper function to read an arbitrary number of entries into a vector
void read_n(std::vector<int>& list, const size_t n) {
for (size_t i = 0; i < n; ++i) {
int v;
std::cin >> v;
list.push_back(v);
}
}
int main() {
// Container to hold the values
std::vector<int> values;
read_n(values, 3);
// Container to hold the targets
std::vector<int> targets;
read_n(targets, 2);
// Ensure that for each target...
for (auto target : targets) {
// ...all of the values exceed that target...
if (!std::all_of(values.cbegin(), values.cend(), [target](int i) { return i > target; })) {
// ...or else it's a fail.
return -1;
}
}
// Use accumulate to compute the sum and display it.
std::cout << std::accumulate(values.cbegin(), values.cend(), 0) << std::endl;
return 0;
}
When writing code try and think in terms of structure and loops rather than just copy-pasting code to add more variables.

Recursively counting a number of values that satisfies a condition and return that number

I need to count how many cubes of values between a and b (2 and 9 in this example) end with numbers between 2 and 5. Everything has to be done with recursion.
The output of this code is
part c = recc = 4
32767
0
It does not make sense to me. It calculates the value of n correctly, but then once asked to return it, returns either 0 or 32767, as if it was not defined.
Can anyone pinpoint the issue?
#include <iostream>
#include <string>
using namespace std;
void partb(int a, int b){
if(a<=b){
int p = (a*a*a)%10;
else if(p>=2 && p<=5){
cout<<a*a*a<<" ";
}
partb(a+1, b);
}
}
int recc(int n, int a, int b){
int p = (a*a*a)%10;
if(a>b){
cout<<"recc = " << n << endl;
return n;
}
else if(a<=b){
if(p>=2 && p<=5){
n++;
}
recc(n, a+1, b);
}
}
int partc(int a, int b){
int n = recc(0, a, b);
cout<<endl<< "part c = " << recc(0, a, b) << endl;
return n;
}
int main(){
int n=partc(2,9);
cout << n << endl;
return 0;
}
Not all control paths in your function return a value, so you were getting undefined behaviour when using the return value.
Now, this wasn't helped by the fact that the function itself is needlessly complicated. Let's rewrite it to use common practice for recursion:
int recc(int a, int b)
{
if (a > b) return 0;
int p = (a*a*a)%10;
int n = (p>=2 && p<=5) ? 1 : 0;
return n + recc(a+1, b);
}
Now your function is simpler. The recursion termination condition is right at the top. The function then decides whether a will contribute 1 or 0 to the count. And finally you return that value plus the count for a smaller range.
Notice how return n + recc(a+1, b); has broken the problem into a simple local solution combined with the recursive result of a reduced scope.
The invocation becomes simpler too, because you no longer have to pass in a redundant argument:
int partc(int a, int b)
{
int n = recc(a, b);
cout << endl << "part c = " << n << endl;
return n;
}

for loop doesn't execute

I've written a naive (only accepts integer exponents) power function for complex numbers (a home made class) using a simple for loop that multiplies the result for the original number n times:
C pow(C c, int e) {
C res = 1;
for (int i = 0; i==abs(e); ++i) res=res*c;
return e > 0 ? res : static_cast<C>(1/res);
}
When I try to execute this, e.g.
C c(1,2);
cout << pow(c,3) << endl;
I always get 1, because the for loop doesn't execute (I checked).
Here's the full code:
#include <cmath>
#include <stdexcept>
#include <iostream>
using namespace std;
struct C {
// a + bi in C forall a, b in R
double a;
double b;
C() = default;
C(double f, double i=0): a(f), b(i) {}
C operator+(C c) {return C(a+c.a,b+c.b);}
C operator-(C c) {return C(a-c.a,b-c.b);}
C operator*(C c) {return C(a*c.a-b*c.b,a*c.b+c.a*b);}
C operator/(C c) {return C((a*c.a+b*c.b)/(pow(c.a,2)+pow(c.b,2)),(b*c.a - a*c.b)/(pow(c.a,2)+pow(c.b,2)));}
operator double(){ if(b == 0)
return double(a);
else
throw invalid_argument(
"can't convert a complex number with an imaginary part to a double");}
};
C pow(C c, int e) {
C res = 1;
for (int i = 0; i==abs(e); ++i) {
res=res*c;
// check wether the loop executes
cout << res << endl;}
return e > 0 ? res : static_cast<C>(1/res);
}
ostream &operator<<(ostream &o, C c) { return c.b ? cout << c.a << " + " << c.b << "i " : cout << c.a;}
int main() {
C c(1,2), d(-1,3), a;
cout << c << "^3 = " << pow(c,3) << endl;}
What you wrote will read as follows:
for (int i = 0; i == abs(e); ++i)
initialize i with 0 and while i is equal to the absolute value of e (i.e. 3 at the beginning of the function call), do something
It should rather be
for (int i = 0; i < abs(e); ++i)
Tip: the code will throw at the first iteration due to the double conversion operator (and caused by a*c.b + c.a*b), but this is another issue: fix your complex (i.e. with imaginary part) printing function or implement a pretty printing method or such.
you should be using i != abs(e) or i < abs(e) as for loop condition. Currently you are using i == abs(e) which will fail in first try because:
i = 0
abs(e) = 3
so 0 == 3 is false and hence for loop will not execute.

Is there an example for accumarray() in C/C++

We are trying to understand accumarray function of MATLAB, wanted to write C/C++ code for the same for our understanding. Can someone help us with a sample/pseudo code?
According to the documentation,
The function processes the input as follows:
Find out how many unique indices there are in subs. Each unique index defines a bin in the output array. The maximum index value in
subs determines the size of the output array.
Find out how many times each index is repeated.
This determines how many elements of vals are going to be accumulated at each bin in the output array.
Create an output array. The output array is of size max(subs) or of size sz.
Accumulate the entries in vals into bins using the values of the indices in subs and apply fun to the entries in each bin.
Fill the values in the output for positions not referred to by subs. Default fill value is zero; use fillval to set a different
value.
So, translating to C++ (this is untested code),
template< typename sub_it, typename val_it, typename out_it,
typename fun = std::plus< typename std::iterator_traits< val_it >::value_type >,
typename T = typename fun::result_type >
out_it accumarray( sub_it first_index, sub_it last_index,
val_it first_value, // val_it last_value, -- 1 value per index
out_it first_out,
fun f = fun(), T fillval = T() ) {
std::size_t sz = std::max_element( first_index, last_index ); // 1. Get size.
std::vector< bool > used_indexes; // 2-3. remember which indexes are used
std::fill_n( first_out, sz, T() ); // 4. initialize output
while ( first_index != last_index ) {
std::size_t index = * first_index;
used_indexes[ index ] = true; // 2-3. remember that this index was used
first_out[ index ] = f( first_out[ index ], * first_value ); // 5. accumulate
++ first_value;
++ first_index;
}
// If fill is different from zero, reinitialize untouched values
if ( fillval != T() ) {
out_it fill_it = first_out;
for ( std::vector< bool >::iterator used_it = used_indexes.begin();
used_it != used_indexes.end(); ++ used_it ) {
if ( * used_it ) * fill_it = fillval;
}
}
return first_out + sz;
}
This has a few shortcomings, for example the accumulation function is called repeatedly instead of once with the entire column vector. The output is placed in pre-allocated storage referenced by first_out. The index vector must be the same size as the value vector. But most of the features should be captured pretty well.
Many thanks for your response. We were able to fully understand and implement the same in C++ (we used armadillo). Here is the code:
colvec TestProcessing::accumarray(icolvec cf, colvec T, double nf, int p)
{
/* ******* Description *******
here cf is the matrix of indices
T is the values whose data is to be
accumulted in the output array S.
if T is not given (or is scaler)then accumarray simply converts
to calculation of histogram of the input data
nf is the the size of output Array
nf >= max(cf)
so pass the argument accordingly
p is not used in the function
********************************/
colvec S; // output Array
S.set_size(int(nf)); // preallocate the output array
for(int i = 0 ; i < (int)nf ; i++)
{
// find the indices in cf corresponding to 1 to nf
// and store in unsigned integer array q1
uvec q1 = find(cf == (i+1));
vec q ;
double sum1 = 0 ;
if(!q1.is_empty())
{
q = T.elem(q1) ; // find the elements in T having indices in q1
// make sure q1 is not empty
sum1 = arma::sum(q); // calculate the sum and store in output array
S(i) = sum1;
}
// if q1 is empty array just put 0 at that particular location
else
{
S(i) = 0 ;
}
}
return S;
}
Hope this will help others too!
Thanks again to everybody who contributed :)
Here's what I came up with. Note: I went for readability (since you wanted to understand best), rather than being optimized. Oh, and I've never used MATLAB, I was just going off of this sample I saw just now:
val = 101:105;
subs = [1; 2; 4; 2; 4]
subs =
1
2
4
2
4
A = accumarray(subs, val)
A =
101 % A(1) = val(1) = 101
206 % A(2) = val(2)+val(4) = 102+104 = 206
0 % A(3) = 0
208 % A(4) = val(3)+val(5) = 103+105 = 208
Anyway, here's the code sample:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
class RangeValues
{
public:
RangeValues(int startValue, int endValue)
{
int range = endValue - startValue;
// Reserve all needed space up front
values.resize(abs(range) + 1);
unsigned int index = 0;
for ( int i = startValue; i != endValue; iterateByDirection(range, i), ++index )
{
values[index] = i;
}
}
std::vector<int> GetValues() const { return values; }
private:
void iterateByDirection(int range, int& value)
{
( range < 0 ) ? --value : ++value;
}
private:
std::vector<int> values;
};
typedef std::map<unsigned int, int> accumMap;
accumMap accumarray( const RangeValues& rangeVals )
{
accumMap aMap;
std::vector<int> values = rangeVals.GetValues();
unsigned int index = 0;
std::vector<int>::const_iterator itr = values.begin();
for ( itr; itr != values.end(); ++itr, ++index )
{
aMap[index] = (*itr);
}
return aMap;
}
int main()
{
// Our value range will be from -10 to 10
RangeValues values(-10, 10);
accumMap aMap = accumarray(values);
// Now iterate through and check out what values map to which indices.
accumMap::const_iterator itr = aMap.begin();
for ( itr; itr != aMap.end(); ++itr )
{
std::cout << "Index: " << itr->first << ", Value: " << itr->second << '\n';
}
//Or much like the MATLAB Example:
cout << aMap[5]; // -5, since out range was from -10 to 10
}
In addition to Vicky Budhiraja "armadillo" example, this one is a 2D version of accumarray using similar semantic than matlab function:
arma::mat accumarray (arma::mat& subs, arma::vec& val, arma::rowvec& sz)
{
arma::u32 ar = sz.col(0)(0);
arma::u32 ac = sz.col(1)(0);
arma::mat A; A.set_size(ar, ac);
for (arma::u32 r = 0; r < ar; ++r)
{
for (arma::u32 c = 0; c < ac; ++c)
{
arma::uvec idx = arma::find(subs.col(0) == r &&
subs.col(1) == c);
if (!idx.is_empty())
A(r, c) = arma::sum(val.elem(idx));
else
A(r, c) = 0;
}
}
return A;
}
The sz input is a two columns vector that contain : num rows / num cols for the output matrix A. The subs matrix is a 2 columns with same num rows of val. Num rows of val is basically sz.rows by sz.cols.
The sz (size) input is not really mandatory and can be deduced easily by searching the max in subs columns.
arma::u32 sz_rows = arma::max(subs.col(0)) + 1;
arma::u32 sz_cols = arma::max(subs.col(1)) + 1;
or
arma::u32 sz_rows = arma::max(subs.col(0)) + 1;
arma::u32 sz_cols = val.n_elem / sz_rows;
the output matrix is now :
arma::mat A (sz_rows, sz_cols);
the accumarray function become :
arma::mat accumarray (arma::mat& subs, arma::vec& val)
{
arma::u32 sz_rows = arma::max(subs.col(0)) + 1;
arma::u32 sz_cols = arma::max(subs.col(1)) + 1;
arma::mat A (sz_rows, sz_cols);
for (arma::u32 r = 0; r < sz_rows; ++r)
{
for (arma::u32 c = 0; c < sz_cols; ++c)
{
arma::uvec idx = arma::find(subs.col(0) == r &&
subs.col(1) == c);
if (!idx.is_empty())
A(r, c) = arma::sum(val.elem(idx));
else
A(r, c) = 0;
}
}
return A;
}
For example :
arma::vec val = arma::regspace(101, 106);
arma::mat subs;
subs << 0 << 0 << arma::endr
<< 1 << 1 << arma::endr
<< 2 << 1 << arma::endr
<< 0 << 0 << arma::endr
<< 1 << 1 << arma::endr
<< 3 << 0 << arma::endr;
arma::mat A = accumarray (subs, val);
A.raw_print("A =");
Produce this result :
A =
205 0
0 207
0 103
106 0
This example is found here : http://fr.mathworks.com/help/matlab/ref/accumarray.html?requestedDomain=www.mathworks.com
except for the indices of subs, armadillo is 0-based indice where matlab is 1-based.
Unfortunaly, the previous code is not suitable for big matrix. Two for-loop with a find in vector in between is really bad thing. The code is good to understand the concept but can be optimized as a single loop like this one :
arma::mat accumarray(arma::mat& subs, arma::vec& val)
{
arma::u32 ar = arma::max(subs.col(0)) + 1;
arma::u32 ac = arma::max(subs.col(1)) + 1;
arma::mat A(ar, ac);
A.zeros();
for (arma::u32 r = 0; r < subs.n_rows; ++r)
A(subs(r, 0), subs(r, 1)) += val(r);
return A;
}
The only change are :
init the output matrix with zero's.
loop over subs rows to get the output indice(s)
accumulate val to output (subs & val are row synchronized)
A 1-D version (vector) of the function can be something like :
arma::vec accumarray (arma::ivec& subs, arma::vec& val)
{
arma::u32 num_elems = arma::max(subs) + 1;
arma::vec A (num_elems);
A.zeros();
for (arma::u32 r = 0; r < subs.n_rows; ++r)
A(subs(r)) += val(r);
return A;
}
For testing 1D version :
arma::vec val = arma::regspace(101, 105);
arma::ivec subs;
subs << 0 << 2 << 3 << 2 << 3;
arma::vec A = accumarray(subs, val);
A.raw_print("A =");
The result is conform with matlab examples (see previous link)
A =
101
0
206
208
This is not a strict copy of matlab accumarray function. For example, the matlab function allow to output vec/mat with size defined by sz that is larger than the intrinsec size of the subs/val duo.
Maybe that can be a idea for addition to the armadillo api. Allowing a single interface for differents dimensions & types.