Symmetric Matrix in C++ - c++

Checking whether a 2D Matrix is symmetric or not
Task is to output YES if the matrix is symmetric else output NO.
I am not getting the expected result. Can someone please help me out and please let me know what's wrong with this code
#include<iostream>
#include<vector>
using namespace std;
bool rev(int n)
{
int n1,d,rn=0;
n1=n;
while(n>0)
{
d=n%10;
rn=(rn*10)+d;
n/=10;
}
if(n1==rn)
{return true;}
else
return false;
}
bool XAxisSymCheck(vector<int> vect)
{
// Declaring iterator to a vector
vector<int>::iterator ptr;
for (ptr = vect.begin(); ptr < vect.end(); ptr++)
{ if(!rev(*ptr)) // reversing the elements in each element of vector to check whether its symmetric or not .. similar to palindrome
{
return false;
}
}
}
int main()
{int testcase;
cin>>testcase;
for(int k=0;k<testcase;++k)
{vector<int> rows;
bool IsSymmetric=true;
int row;
cin >> row;
// read each row and append to the "rows" vector
for (int r = 0; r < row; r++)
{
int line;
cin >> line;
rows.push_back(line);
}
if(XAxisSymCheck(rows))
{int i,j;
i=0;
j=row-1;
while(i<j) // looping through the elements of vector and checking the first element with last element , second element with the second last element and so on.
{
if(rows[i]!=rows[j])
{
IsSymmetric=false;
break;
}
i++;
j--;
}
}
else
{
IsSymmetric=false;
}
cout << (IsSymmetric ? "Yes" : "No") << endl;
}
return 0;
}
Input:
First line contains T - number of test cases.
T test cases follow.
First line of each test case contains the N - size of matrix.
Next N lines contains binary strings of length N.
Output:
Print YES or NO in a new line for each test case
SAMPLE INPUT
5
2
11
11
4
0101
0110
0110
0101
4
1001
0000
0000
1001
5
01110
01010
10001
01010
01110
5
00100
01010
10001
01010
01110
SAMPLE OUTPUT
YES
NO
YES
YES
NO
Test Case #1: Symmetric about both axes, so YES.
Test Case #2: Symmetric about X-axis but not symmetric about Y-axis, so NO.
Test Case #3: Symmetric about both axes, so YES.
Test Case #4 and #5 are explained in statement.

There are three problems with your code
1) You are never returning true from XAxisSymCheck (this can easily discovered by inspecting the compiler warnings, eg g++ -Wall matrix.cpp)
bool XAxisSymCheck(vector<int> vect) {
vector<int>::iterator ptr;
for (ptr = vect.begin(); ptr < vect.end(); ptr++) {
if(!rev(*ptr, vect.size()))
return false;
}
return true;
}
2) When your XAxisSymCheck fails, you are not setting IsSymmetric to false (at least in the original post before the edit)
for(int k=0;k<testcase;++k) {
vector<int> rows;
bool IsSymmetric = true;
// ....
if (XAsxisSymCheck(rows)) {
// ...
} else {
IsSymmetric = false;
}
cout << (IsSymmetric ? "Yes" : "No") << endl;
}
3) Your reverse check fails, if a line has leading zeros, because the reverse is not multiplicated by 10 often enough.
bool rev(int n,int len) {
int n1,d,rn=0;
n1=n;
for (int i = 0; i < len; i++)
{
d=n%10;
rn=(rn*10)+d;
n/=10;
}
return n1==rn;
}

Related

Check Number sequence

You are given S a sequence of n integers i.e. S = s1, s2, ..., sn. Compute if it is possible to split S into two parts : s1, s2, ..., si and si+1, si+2, ….., sn (0 <= i <= n) in such a way that the first part is strictly decreasing while the second is strictly increasing one.
Note : We say that x is strictly larger than y when x > y.
So, a strictly increasing sequence can be 1 4 8. However, 1 4 4 is NOT a strictly increasing sequence.
That is, in the sequence if numbers are decreasing, they can start increase at one point. And once number starts increasing, they cannot decrease at any point further.
Sequence made up of only increasing numbers or only decreasing numbers is a valid sequence. So in both the cases, print true.
You just need to print true/false. No need to split the sequence.
Input format :
Line 1 : Integer 'n'
Line 2 and Onwards : 'n' integers on 'n' lines(single integer on each line)
Output Format :
"true" or "false" (without quotes)
Constraints :
1 <= n <= 10^7
Sample Input 1 :
5
9
8
4
5
6
Sample Output 1 :
true
Sample Input 2 :
3
1
2
3
Sample Output 2 :
true
Sample Input 3 :
3
8
7
7
Sample Output 3 :
false
Explanation for Sample Format 3 :
8 7 7 is not strictly decreasing, so output is false.
Sample Input 4 :
6
8
7
6
5
8
2
Sample Output 4 :
false
Explanation for Sample Input 4 :
The series is :
8 7 6 5 8 2
It is strictly decreasing first (8 7 6 5). Then it's strictly increasing (5 8). But then it starts strictly decreasing again (8 2). Therefore, the output for this test case is 'false'
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
int p;
cin >> p;
bool isDec = true;
int i = 1,c;
while(i <= n - 1){
cin >> c;
if(c > p){
if(isDec == true){
isDec = false;
}
isDec = true;
p = c;
} else if(c < p){
if(isDec == false){
isDec = false;
}
isDec = true;
p = c;
} else {
isDec = false;
break;
}
i++;
}
if(isDec){
cout << "true" << endl;
} else{
cout << "false" << endl;
}
}
What is wrong with this code? It failed for last test case.
#include<iostream>
using namespace std;
int main() {
int n;
cin>>n;
int current_term;
cin>>current_term;
bool isDecreasing = true,is_valid_sequence_yet=true;
int i=2;// first term of sequence has already been taken
while(i<=n){
int next_term;
cin>>next_term;
if(is_valid_sequence_yet && isDecreasing && current_term>next_term){
current_term=next_term;
isDecreasing=true;
}else if(is_valid_sequence_yet && current_term < next_term){
current_term=next_term;
isDecreasing = false;
}else{
is_valid_sequence_yet=false;
}
i++;
}
if(is_valid_sequence_yet){
cout << "true" << endl;
}else{
cout << "false" <<endl;
}
}
import java.util.*;
public class test{
public static void main(String args[]){
Scanner s=new Scanner(System.in);
int n=s.nextInt();
int arr[]=new int[n];
for(int i=0;i<n;i++){
arr[i]=s.nextInt();
}
boolean flag=true;
for(int i=0;i<n-2;i++){
if((arr[i]<arr[i+1])&& arr[i+1]>arr[i+2])){
flag=false;
break;
}
}
System.out.print(flag);
}
}
int num , temp = 1 , i =1 ;
cin>>num;
bool Isdec = true;
int Previes_num , current_num;
cin>>Previes_num;
while(i <= num-1){
cin>>current_num;
if(Previes_num > current_num){
if(Isdec){
Isdec = true ;
temp++;
}
else{
cout<<"false";
return 0;
}
}
else if(current_num > Previes_num){
if(Isdec){
Isdec = false ;
}
}
else{
cout<<"false";
return 0 ;
}
++i;
Previes_num=current_num;
}
if(temp==num){
cout<<"true";
}
else if(Isdec == 0){
cout<<"true" ;
}
return 0;
}
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << endl;
int t1,t2; // two consecutive terms
cin >> t1;
cout << endl;
bool changed=false; // this will turn true once the series has switched to increasing mode
bool result=true; // we will change it to flase if any condition is voilated
for(int i=2;i<=n;i++) { // i=2 since we already took one input
cin >> t2;
cout << endl;
if (t1>t2) {
if (changed == true) {//we are in the increasing part
result = false; //since now the terms are decreasing but we are in incresaing part the series is no longer valid
}
}
else if (t1<t2) {
if ( changed == false) {
changed = true; // the series has now changed to increasing series if it wasn't before
}
}
else {
result = false; // if tow terms are equal the result is automatically false
}
t1=t2; // replacing the terms to get new input
}
if (result) cout << "true"; // if we dont do this we get 0,1 as output
else cout << "false";
}
We need to set two bools as shown. Once our series changes from decreasing to increasing we will set change to true.
If we already have change set to true but our series changes again from decreasing to increasing we will set result bool to false.
In the end we can output result to get our required answer.
In case we get two consecutive terms equal we straightaway set result to false as it directly violates our condition of strictly increasing or strictly decreasing.
We will not use break anywhere because user is expected to give all the inputs and then result is displayed.
As for debugging your code, you need to change your approach. Also, what did you even intend to accomplish by this :
if(isDec == false){
isDec = false;
}

Find a triplet that sum a given value

I've been struggling with a problem where based on a given number i have to find all the triplets that sum gives the given number.
For example if the given number is 5 conditions are : (x+y+z=5 and x<=y<=z) :
Input :
5
Output :
0 0 5
0 1 4
0 2 3
1 1 3
1 2 2
I've tried to find all the solutions starting with 0 but i can't figure out how to find solutions that start with 1, 2, 3, etc
What i have so far :
int x,y,z;
void showSolutions(int c) {
z=c;
while((x<=y) && (y<=z)) {
if((x<=y&&y<=z)&&(x+y+z)==c) {
cout<<x<<" "<<y<<" "<<z;
cout<<"\n";
}
y++;
z--;
}
}
Thanks for help!
Well you can think of this recursively, let me try to point a generic method which would work for two numbers or triplets or more.
class sum
{
public:
vector<vector<int>> triplets(int k, int target)
{
vector<vector<int>> result;
vector<int> holder;
getTriplets(k, target, holder, result);
return result;
}
void getTriplets(int k, int target, vector<int>& holder, vector<vector<int>>& result)
{
if(target < 0) return;
if(k < 0) return;
if(k == 0 && target == 0)
{
result.push_back(holder);
return;
}
for(int i = 0; i <= target; ++i)
{
holder.push_back(i);
getTriplets(k-1, target - i, holder, result);
holder.pop_back();
}
}
};
You can invoke this as:
sum s;
auto res = s.triplets(3,5);
for(auto row : res)
{
for(auto col : row) cout << col << " ";
cout << endl;
}
where the first argument to triplets is the what the size of set required and the latter is the garget value. The problem here is, it will produce duplicates, 0 0 5 and 5 0 0 I will leave that for you to figure out how.
Simply add results to a temporary holder and recursively try all combinations. until you reach the target value which is 0 in our case since we are subtracting, or hit a error condition. Backtrack and pop the value and exhausting all combinations. Store the result if we hit the target.
Live Demo
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int x,y,z;
for(z=n;z>=0;z--)
{
for(y=0;y<=z && z+y<=n;y++)
{
x=n-(y+z);
if(x<=y)
cout<<x<<y<<z<<endl;
}
}
}
for n=5,you get
005
014
113
023
122

C++ program Booths Algorithm 2s Complement using array

I have included the program in which I am having a logical problem. The program is based on booth's algorithm and I have put a snippet of it. In this 'working' snippet decimal number is accepted from the user converted to decimal form with the help of array (a[0]=1 LSB) and lastly the 2s complement is calculated of array b[].
Now, when I run the program:
#include<iostream>
using namespace std;
class booth
{
public:
int n;
int b[3];
int comb[3], q[3]; //b=multiplicand q=multiplier
int bb, qq; //bb and qq store actual decimal no.s
booth()
{
for(int i=0; i<4; i++)
{
b[i]=0; //b array stores multiplicand in binary
q[i]=0; //q array stores multiplier in binary
comb[i]=0; //will store calculated 2s complement in
binary
}
n=4;
bb=0;
qq=0;
}
void acceptMm();
void display();
};
void booth :: acceptMm() //function to accept value from user and
//converting it into binary in the form of
//array and then calculating its 2s complement
{
cout<<"Enter Multiplicand: ";
cin>>bb;
cout<<"Enter Multiplier: ";
cin>>qq;
//decimal to binary
int rem1, rem2, i=0, j=0; //rem1 and rem2 are remainders
while(qq!=0)
{
rem2=qq%2;
qq/=2;
q[i]=rem2;
i++;
}
cout<<q[3]<<q[2]<<q[1]<<q[0]<<endl; // to display binary no.
//again decimal to binary
while(bb!=0)
{
rem1=bb%2;
bb/=2;
b[j]=rem1;
j++;
}
cout<<b[3]<<b[2]<<b[1]<<b[0]<<endl; //to display binary no.
// 2s complement:
int ii=0;
int jj=4; //4 bit binary number
while(b[ii]==0 && jj!=0)
{
comb[ii]=b[ii];
ii++;
jj--;
}
comb[ii]=b[ii];
cout<<b[3]<<b[2]<<b[1]<<b[0]<<endl; //displayed value (problem)
ii++;
jj--;
if(jj==0)
{
return;
}
while(jj!=0)
{
if(b[ii]==0)
{
comb[ii]=1;
ii++;
jj--; }
else
{
comb[ii]=0;
ii++;
jj--;
}
}
}
void booth :: display()
{
cout<<"multiplicand\n";
for(int x=3; x>=0; x--)
{
cout<<b[x]<<" ";
}
cout<<endl;
cout<<"multiplier\n";
for(int j=3; j>(-1); j--)
{
cout<<q[j]<<" ";
}
cout<<endl;
cout<<"compliment of multiplicand\n";
for(int y=3; y>(-1); y--)
{
cout<<comb[y]<<" ";
}
}
int main()
{
booth obj;
cout<<"Booths Algorithm\n";
obj.acceptMm();
obj.display();
return 0;
}
Output
Booths Algorithm
Enter Multiplicand: 5
Enter Multiplier: 4
0100
0101
1101
multiplicand
1 1 0 1
multiplier
0 1 0 0
compliment of multiplicand
0 0 1 1
Here in the output I expect the 6th line as 0101 but get 1101. Why are the values of array b[] changing? The value of array b[] at line 5 is correct so why does it change? According to the code the value shouldnt be changing right?
I am stuck.. Please help!! Any suggestion will be appreciated!!
b, q and comb are array of 3 elements so b[3] is an array overflow (whose value is unknown). In fact comb being allocated right after b it is likely that b[3] equals comb[0].
You are doing an overflow . Do it like this. Simple .
class booth {
public:
int n;
int b[4];
int comb[4], q[4]; //b=multiplicand q=multiplier
int bb, qq; //bb and qq store actual decimal no.s
booth() {
for (int i = 0; i < 4; i++) {
b[i] = 0; //b array stores multiplicand in binary
q[i] = 0; //q array stores multiplier in binary
comb[i] = 0; //will store calculated 2s complement in }
n = 4;
bb = 0;
qq = 0;
}
}

C++ odd-even array, infinite answer

This program supposed to read the number of elements and a list, and split the array for even and odd numbers, and display the number of zeros in original array.
I posted a question before for the first problem I had with this program and the answers were really helpful since this is an assignment. But now I have another problem which is every time I run the program it gave me 0 'z. and it does not stop until I close the window. I think the problem is with the count function but I was not able to diagnose the problem by myself. I added:
cout<< odd_num<< " " << even_num;
after I called count function to find out what is the problem and it gave me a really big number so whatever the error is, it is coming from this function.
So please help me! I'm sure for most of you this is very basic but I just started to learn this and really appreciate it if you can help me.
Edit: I edited this code and the only problem is an extra zero as output; look at the example output at the end.
Here is the code:
int count(const int list[], int size, int & odd , int & even)
{
int zero(0);
for (int i(0); i<size ; i++)
{
if (list[i] == 0)
{
zero++;
}
if (list[i]% 2 ==0 & list[i]!=0)
{
even++;
}
else if (list[i]% 2 ==1 & list[i]!=0)
{
odd++;
}
}
return zero;
}
void split(const int list[], int size, int list_even[], int even_num, int list_odd[], int odd_num )
{
int j(0);
int k(0);
for (int i(0); i<size; i++)
{
if(list[i]%2 == 0)
{
list_even[j]= list[i];
j++;
}
else if(list[i]%2 != 0)
{
list_odd[k]= list[i];
k++;
}
}
if (j != even_num || k != odd_num)
{
cerr << "Error.";
}
}
// function to print an array
void print_list(int array[], int length)
{
for (int a=0; a<length; a++)
{
cout <<array[a]<<" ";
}
}
And here is the sample answer:
Enter number of elements: 3
Enter list:
2
30
0
Error.Even elements:
2 30 0 0
Odd elements:
There were 1 zeros in the list
Another sample is:
Enter number of elements: 3
Enter list:
2
1
5
Error.Even elements:
2 2752708
Odd elements:
1 5 2762032 2752708
There were 0 zeros in the list
You did not initialize your variables try:
int zero_num(0); // number of zeros
int even_num(0);
int odd_num(0);
Try printing them out before you start using them (before this fix) and see what they are set too. :)
Fix to your count function:
// function to copy odd and even number to seperate arrays
void split(const int list[], int size, int list_even[], int even_num, int list_odd[], int odd_num )
{
int j(0);
int k(0);
for (int i(0); i<size; i++)
{
if (list[i] == 0)
{ // zeros are not considered even in the count function
// so they should not be added here.
continue;
}
else if(list[i]%2 == 0)
{
list_even[j]= list[i];
j++;
}
else if(list[i]%2 != 0)
{
list_odd[k]= list[i];
k++;
}
}
// test that we have found the right number of even and odd numbers.
if (j != even_num || k != odd_num)
{
cerr << "Error.";
}
}
And to make sure that multiple calls to the count function does not mess up your numbers make this change:
//function to count the odd and even numbers and th enumber od zeros
int count(const int list[], int size, int & odd , int & even)
{
// reset the even and odd counts before we start.
odd=0;
even=0;
int zero(0); // variable to count zeros
for (int i(0); i<size ; i++)
{
if (list[i] == 0)
{
zero++;
}
else if (list[i]% 2 == 0 )
{
even++;
}
else if (list[i]% 2 == 1 )
{
odd++;
}
}
return zero;
}
Sample output:
Enter number of elements: 5
Enter list:
1
2
5
0
0
Even elements: 2
Odd elements: 1
5
There were 2 zeros in the list
Another sample output with zeros in begining and middle:
Enter number of elements: 5
Enter list:
0
2
0
1
7
Even elements: 2
Odd elements: 1
7
There were 2 zeros in the list
In if condition you are using & which is bit-wise operator instead of && which is Logical AND.
See:
if (list[i]% 2 ==0 & list[i]!=0)
{
even++;
}
use && instead and see if it works, else drop me a message.
[Improvement] How about to write your count function like this,
int count(const int list[], int size, int & odd , int & even)
{
int zero(0);
for (int i(0); i<size; ++i)
{
if (list[i]==0)
{
++zero;
}
else
{
if (list[i]%2==0) ++even;
else ++odd;
}
}
return zero;
}

Recursion in c++ (generate binary codes)

I am trying to write a program that generates all the binary codes given an input number (for the number of bits). For example, if the user inputs 3, it should generate all the numbers below:
000
001
010
011
100
101
110
111
The function is called generateBinaryCode(), and it has to be recursive (that's the challenge of the question).
The following is my attempt but it doesn't work. Can anyone please offer me some insights?
Thanks in advance.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> generateBinaryCode(int nBits);
int main()
{
int input;
while (true)
{
cout << "Enter an integer (any negative numbers are sentinel): ";
cin >> input;
if (input < 0) break;
for (unsigned i = 0; i < generateBinaryCode(input).size(); i++)
cout << generateBinaryCode(input).at(i) << endl;
}
return 0;
}
vector<string> generateBinaryCode(int nBits)
{
vector<string> result;
int size = result.size();
std::vector<string>::iterator it;
if (nBits == 1) {
result.push_back("0");
result.push_back("1");
} else {
result = generateBinaryCode(nBits - 1);
for (unsigned int i = 0; i < result.size(); i++)
{
result.push_back("0" + result.at(i));
result.at(i) = "1" + result.at(i);
}
}
return result;
}
Your code is very close to correct, but the self-modifying result is going to be problematic. insertion into a vector does many things, among them invalidating iterators currently open on the sequence. But it will also change the result of size() (for obvious reasons, I hope).
The simplest answer is to use a sub list vector, then enumerate that, appending all entries within with '0' and '1', and inserting those results into your return vector. An example of this is below:
std::vector<std::string> getBitStrings(unsigned int n)
{
std::vector<std::string> result;
if (n <= 1)
{
result.push_back("0");
result.push_back("1");
}
else
{ // recurse, then add extra bit chars
std::vector<std::string> sub = getBitStrings(n-1);
for (std::vector<std::string>::const_iterator it = sub.cbegin();
it != sub.cend(); ++it)
{
result.push_back(*it+'0');
result.push_back(*it+'1');
}
}
return result;
}
This is somewhat different than your implementation, in that it expects values between 1 and n for the bit count. Running with n=5, the following is produced:
int main()
{
std::vector<std::string> bs = getBitStrings(5);
std::copy(bs.begin(), bs.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
Output
00000
00001
00010
00011
00100
00101
00110
00111
01000
01001
01010
01011
01100
01101
01110
01111
10000
10001
10010
10011
10100
10101
10110
10111
11000
11001
11010
11011
11100
11101
11110
11111
To be honest there are a plethora of ways this can be done, this is just one. I purposely modeled it after your original implementation so as to limit algorithm change. I hope it helps you understand the problem and one way around it.
The main flaw is in the following loop:
for (unsigned int i = 0; i < result.size(); i++)
{
result.push_back("0" + result.at(i));
result.at(i) = "1" + result.at(i);
}
In a nutshell, you don't want to be adding elements to result while iterating over it. What you have right now is an infinite loop (that'll eventually run out of memory).
Also, you don't want to be calling generateBinaryCode() at every iteration of your main loop. Call it once and store the result in a variable.
And finally (and least importantly), entering 0 at the prompt will result in infinite recursion.
simpler and concise solution
void printBin(std::string prefix, int n)
{
if(prefix.size() == n)
{
std::cout <<prefix <<std::endl;
return;
}
printBin(prefix + '0', n);
printBin(prefix + '1', n);
return;
}
int main()
{
int n;
std::cin >> n;
printBin("", n);
return 0;
}
What you are trying to do at this line
result.push_back("0" + result.at(i));
is basically this, and that may be dodgy, and cause of your problem.
Here's a simple one:
(written in C, not C++, but the outline should be the same)
void generateBinaryCode(char* txt, int i, int len)
{
if (len != 0)
{ txt[i] = '0';
makeBinary(txt, i+1, len-1);
txt[i] = '1';
makeBinary(txt, i+1, len-1);
} else
{
puts(txt);
}
}
int main()
{
char str[4] = {0};
generateBinaryCode(str, 0, sizeof(str)-1);
getchar();
return 0;
}