Sender Cyclic Redundancy Check Code - Why isn't my code working? - c++

Given a frame and generator, no. of bits in generator is n
you have to put n-1 number of zeroes behind frame
then the first n bits of frame are XORed with the generator
this is continued until the remainder has n-1 digits
then last n-1 digits of frame(which were the zeroes we added in step 1) are replaced by n-1 digits of
remainder
this is to be displayed
It executes, takes input but the cursor just blinks instead of giving output
#include<iostream>
#include<string>
using namespace std;
class CRC
{
int frame[32], generator[10],f,g;
public:
void input();
void check();
}obj;
void CRC::input()
{
int i;
cout<<"Enter length of frame:";
cin>>obj.f;
cout<<"Enter frame:";
for(i=0;i<obj.f;i++)
{
cin>>obj.frame[i];
}
cout<<"Enter length of generator:";
cin>>obj.g;
cout<<"Enter generator:";
for(i=0;i<obj.g;i++)
{
cin>>obj.generator[i];
}
obj.f=obj.f+obj.g-1;
obj.check();
}
void CRC::check()
{
int p[32],k=0,i;
for(i=0;i<obj.f;i++)
{
p[i]=obj.frame[i];
}
while((obj.f-k)>=g)
{
for(i=k;i<obj.g+k;i++)
{
p[i]=p[i]^generator[i];
}
for(i=obj.g+k;i<obj.f;i++)
{
p[i]=frame[i];
}
for(i=0;i<obj.f;i++)
{
if(p[i]==1)
{
k=i;
break;
}
}
}
for(i=obj.f-obj.g;i<obj.f;i++)
{
obj.frame[i]=p[i];
}
cout<<"Original message:";
for(i=0;i<obj.f;i++)
{
cout<<obj.frame[i];
}
}
int main()
{
obj.input();
return 0;
}

Related

Getting wrong answer in a DP problem although implementation looks correct

I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}

SIGABRT error in cpp

I'm getting a SIGABRT error when I compile the following code(PALIN problem on SPOJ).The objective of the code is to find smallest palindromic number which should be greater than the given number, where given number can have upto 1000000 digits.
Link to the problem is: http://www.spoj.com/problems/PALIN/ It runs well on codeblocks but SPOJ returns SIGABRT error. Can someone explain the reason?
#include<iostream>
#include<string>
using namespace std;
string palinodd(string num)//to find next nearest palindrome for an odd digit number
{
string palin=num;
int flag=0;
for(int i=num.size()/2-1;i>-1;i--)
{
if(flag==0)//checks if the middle most digit should be incremented
{
if(num[i]<palin[num.size()-i-1])
flag=1;
else if(num[i]>palin[num.size()-i-1])
flag=-1;
}
palin[num.size()-1-i]=num[i];
}
if(flag!=-1)
palin[num.size()/2]++;
if(palin[num.size()/2]==':')//if the middle digit goes greater than 9
{
palin[num.size()/2]='0';
palin[num.size()/2-1]++;
palin[num.size()/2+1]++;
}
return palin;
}
string palineve(string num)//to find next nearest palindrome for an even digit number
{
string palin=num;
int flag=0;
for(int i=num.size()/2-1;i>-1;i--)
{
if(flag==0)//checks if middle digit should be incremented
{
if(num[i]<palin[num.size()-i-1])
flag=1;
else if(num[i]>palin[num.size()-i-1])
flag=-1;
}
palin[num.size()-1-i]=num[i];
}
if(flag!=-1)
palin[num.size()/2-1]++;
if(palin[num.size()/2-1]==':')//if the middle digit goes greater than 9
{
palin[num.size()/2-2]++;
palin[num.size()/2+1]++;
palin[num.size()/2-1]='0';
}
palin[num.size()/2]=palin[num.size()/2-1];//updates the middle number
return palin;
}
int main()
{
int t;
cin>>t;
while(t--)
{
string num="912496394";
string ans;
if(num.size()%2!=0)
ans=palinodd(num);
else
ans=palineve(num);
cout<<ans<<endl;
}
return 0;
}
Appreciate your effort, try to match c++ compiler, version in SPOJ and codeblocks. I tried your code with clang++-5.0 after changing num (912496394) to string but i didn't get expected results. I think you might have posted older version of your code, if possible you can post the updated code.
The process will be aborted with SIGABRT if there are any overflows in your code, as you are using more string operations you can refer below link which has some info on SIGABRT,
SIGABRT called when calling find() on a string element in an array
One suggestion on your approach to the problem, you can try to increment the input by one in a while loop until you find a palindrome or you reach largest number and print the results
The solution I found out for above problem is:
#include<iostream>
#include<string>
using namespace std;
string palinodd(string num)
{
string palin=num;
int flag=0;
for(int i=num.size()/2-1;i>-1;i--)
{
if(flag==0)
{
if(num[i]<palin[num.size()-i-1])
flag=1;
else if(num[i]>palin[num.size()-i-1])
flag=-1;
}
palin[num.size()-1-i]=num[i];
}
if(flag!=-1)
palin[num.size()/2]++;
if(palin[num.size()/2]==':')
{
palin[num.size()/2]='0';
palin[num.size()/2-1]++;
palin[num.size()/2+1]++;
}
for(int i=num.size()/2-1;i>0;i--)
{
if(palin[i]==':')
{
palin[i]='0';
palin[i-1]++;
}
}
for(int i=num.size()/2+1;i<num.size()-1;i++)
{
if(palin[i]==':')
{
palin[i]='0';
palin[i+1]++;
}
}
return palin;
}
string palineve(string num)
{
string palin=num;
int flag=0;
for(int i=num.size()/2-1;i>-1;i--)
{
if(flag==0)
{
if(num[i]<palin[num.size()-i-1])
flag=1;
else if(num[i]>palin[num.size()-i-1])
flag=-1;
}
palin[num.size()-1-i]=num[i];
}
if(flag!=-1)
palin[num.size()/2-1]++;
if(palin[num.size()/2-1]==':')
{
palin[num.size()/2-2]++;
palin[num.size()/2+1]++;
palin[num.size()/2-1]='0';
}
palin[num.size()/2]=palin[num.size()/2-1];
/*if any incremented digit becomes greater than 9,it shows a ':' so we make it 0 and increase previous(if ':' comes in the first half of the string)/next(if ':' comes in the last half of the sting) digit by 1.*/
for(int i=num.size()/2-2;i>0;i--)
{
if(palin[i]==':')
{
palin[i]='0';
palin[i-1]++;
}
}
for(int i=num.size()/2+1;i<num.size()-1;i++)
{
if(palin[i]==':')
{
palin[i]='0';
palin[i+1]++;
}
}
return palin;
}
int main()
{
int t;
cin>>t;
while(t--)
{
string num,ans;
cin>>num;
int cnt=0;
/*if all the digits in the string are 9, then the next palindromic number will have one more digit than the original number of digits. Thus, increasing the string length*/
for(int i=0;i<num.size();i++)
{
if(num[i]=='9')
cnt++;
}
if(cnt==num.size())
{
num[0]='1';
for(int i=1;i<num.size();i++)
num[i]='0';
num+='0';
}
if(num.size()%2!=0)
ans=palinodd(num);
else
ans=palineve(num);
cout<<ans<<endl;
}
return 0;
}

I was making a Program, of selection sorting using array int Turbo C++

The Output will be having four column for serial number, the user input, ascending order and descending order. I am doing it in Turbo C++ but after compiling it is giving 12 errors.
- Declaration terminated incorrectly
- Declaration syntax error
- Variable 'i' and 'j' is initialized more than once
- Declaration terminated incorrectly
The Program is:
#include<iostream.h>
#include<conio.h>
int main()
{
clrscr();
int a[10][3];
cout<<"Enter Number of elements: \n";
for(int i=0;i<10;i++)
{
cin>>a[i][0];
a[i][1]=a[i][0];
a[i][2]=a[i][0];
}
for(int j=9;j>0;j--)
{
for(i=0;i<j;i++)
{
int t;
t=a[i+1][1];
a[i+1][1]=a[i][1];
a[i][1]=t;
}
}
return 0;
};
for(i=0;i<9;i++)
{
a[i][1];
}
for( j=9;j>0;j--)
{
for(i=0;i<j;i++)
{
if(a[i][2]<a[i+1][2])
{
int t;
t=a[i+1][2];
a[i+1][2]=a[i][2];
a[i][2]=a[i][2];
a[i][2]=t;
}
}
}
cout<<"|\tSr.No\t|\tUser Input\t|\tA.O\t|\tD.O\t|";
for(i=0;i<=9;i++)
{
cout<<" "<<i+1<<"\t\t|\t\t"<<b[i][0]<<"\t\t|\t\t"b[i][2]<<"\t\t|\t\t"<<b[i][1]<<endl;
}
getch();

Roman numbers to decimal numbers, getting garbage value

I have to create a program for converting Roman numerals to decimal numbers for which I'm getting garbage value as an output.
The fact is I have double checked my logic and it seems to be correct.
How can I correct it?
Here's my code:
#include<iostream>
#include<cstring>
using namespace std;
class RomanType
{
char str[10];
int d;
public:
void accept()
{
cout<<"Enter Roman No. in capitals:"<<endl;
cin>>str;
convert(str);
}
void convert(char str1[10])
{
int j=0;
for(j=0;j<strlen(str1);j++)
{
if( str1[j]=='I')
{
if(str1[j+1]=='V' || str1[j+1]=='X')
{
d=d-1;
cout<<j<<endl;
}
else
{
d=d+1;
cout<<d<<endl;
}
}
if ( str1[j]=='V')
d=d+5;
if(str1[j]=='X')
{
if(str1[j+1]=='L' || str1[j+1]=='C')
d=d-10;
else
d=d+10;
}
if(str1[j]=='L')
d=d+50;
if( str1[j]=='C')
{
if(str1[j+1]=='D' || str1[j+1]=='M')
d=d-100;
else
d=d+100;
}
if(str1[j]=='D')
d=d+500;
if(str1[j]=='M')
d=d+1000;
}
}
void display()
{
cout<<"It's decimal equivalent is="<<d<<endl;
}
};
main()
{
RomanType obj;
obj.accept();
obj.display();
}
Few points:
Don't directly jump to parsing high value romans. Start with I, V, and X only (i.e. target 1 to 10 first, then 11 to 20, then 21 to 39, 40 to 99, 100 to 499 etc.)
Don't assume that if I is given, it is given before or after V or X. It may be given for itself (eg. II - you else part assumes something).
Assign value of d with zero
Do step debugging, watch value of d and other variables. If debugger isn't good or available, do output the values on each step/iteration.
[Add] You need not to pass str to function convert, since they belong to same class, and convert can/would read the same content.
You didn't initialize d to 0
in convert put d=0 at the start
You didn't initialize d to 0. Please add this at the top of your convert function:
void convert(char str1[10])
{
int j=0;
d = 0;
. . .
OK guys thanks for the help. It's solved now. I had done a blunder and that was initialised d again in convert(), so that had made it as a local variable. See the comments:
#include<iostream>
#include<cstring>
using namespace std;
class RomanType
{
char str[10];
int d;
public:
void accept() // UNNECESSARILY NOT PASSING ANY STRING
{
cout<<"Enter Roman No. in capitals:"<<endl;
cin>>str;
convert();
}
void convert()
{
d=0;// PREVIOUSLY WRIITEN int d=0; so that was the mistake. Yay! it's solved :D
for(int j=0;j<10;j++)
{
if( str[j]=='I')
{
if(str[j+1]=='V' || str[j+1]=='X')
{
d=d-1;
// cout<<d<<endl;
}
else
{
d=d+1;
//cout<<d<<endl;
}
}
else if ( str[j]=='V')
d=d+5;
else if(str[j]=='X')
{
if(str[j+1]=='L' || str[j+1]=='C')
d=d-10;
else
d=d+10;
}
else if(str[j]=='L')
d=d+50;
else if( str[j]=='C')
{
if(str[j+1]=='D' || str[j+1]=='M')
d=d-100;
else
d=d+100;
}
else if(str[j]=='D')
d=d+500;
else if(str[j]=='M')
d=d+1000;
}
}
void display()
{
cout<<"It's decimal equivalent is="<<d<<endl;
}
};
main()
{
RomanType obj;
obj.accept();
obj.display();
}

Peculiar behavior while recursively calling function in C++ and getting two different outputs for the same code with only an extra line with "cout"

#include <iostream>
#include <vector>
#define MAXX 1000
using namespace std;
int number[MAXX], digits=0;
int adjust(int i)
{
if(number[i]<9)
{
cout<<"i = "<<i<<" "; //PROBLEM
(number[i])++;
return i;
}
number[i]=0;
adjust(i-1);
}
void makePalindrome(int head,int tail)
{
int revert;
if(head>tail)
return;
if(number[head]==number[tail])
{
makePalindrome(head+1,tail-1);
}
if(number[tail]<number[head])
{
number[tail]=number[head];
makePalindrome(head+1,tail-1);
}
if (number[tail]>number[head])
{
number[tail]=number[head];
revert=adjust(tail-1);
if(revert<=head)
{
makePalindrome(revert,digits-revert-1);
}
else
{
makePalindrome(head+1,tail-1);
}
}
}
int main(int argc, char const *argv[])
{
long long int num,num_copy;
int head,tail;
int number_reverse[MAXX];
cout<<"Enter the number whose next greater palindrome you want to find" <<endl;
cin>>num;
num_copy=num;
while(num_copy>0)
{
number_reverse[digits]=num_copy%10;
digits++;
num_copy=num_copy/10;
}
//cout<<"Digits = "<<digits<<"\n";
for (int i = digits-1; i >=0; --i)
{
number[digits-i-1]=number_reverse[i];
//cout<<number[digits-i-1]<<" ";
}
head=0; tail=digits-1;
makePalindrome(head,tail);
cout<<"Answer : ";
for (int i = 0; i < digits; ++i)
{
cout<<number[i];
}
cout<<"\n";
return 0;
}
When I am running with an input : 94187978322, it is giving two different answers with and without a "cout" line (line with comment "PROBLEM").
Here's the output:
ishivendra:code shivendraagrawal$ g++ next_palindrome.cpp
ishivendra:code shivendraagrawal$ ./a.out
Enter the number whose next greater palindrome you want to find
94187978322
Answer : 94188078149
ishivendra:code shivendraagrawal$ g++ next_palindrome.cpp
ishivendra:code shivendraagrawal$ ./a.out
Enter the number whose next greater palindrome you want to find
94187978322
i = 7 i = 6 i = 4 Answer : 94188088149
The second output is the desired output. Can you point out the cause of this difference and incorrectness for the first one ?
I figured half of it out, it was a logical error.
I should have written return adjust(i-1).
I still don't know the cause for the peculiarity (There was no compilation or runtime error) but at least my code is running as desired now.