Infix to Postfix Conversion - c++-cli

I'm trying to code that converts infix expressions to postfix expressions. Currently, the program works correctly if I enter for e.g "5+6" it will output the correct answer which is "5 6 +". The problem occurs when I enter more than one operator for e.g "5+6-3", it outputs and incorrect answer "+3-". Can someone please point out where I'm making the error ? Thanks, in advance !
void main(){
Stack *s = new Stack;
string input;
cout <<"Enter Expression"<<endl;
cin>>input;
InfixToPostfix(input);
system("PAUSE");
}
string InfixToPostfix(string input){
Stack *S = new Stack();
string postfix = "";
for (int i=0; i < input.length();i++){
if (input[i]== ' '||input[i]==',') continue;
else if (IsOperator(input[i]))
{
while(!S->IsStackEmpty() && S->StackTop() != '(' && HasHigherPrecedence(S->StackTop(),input[i]))
{
postfix=S->StackTop();
S->Pop();
}
S->Push(input[i]);
}
else if(IsOperand(input[i]))
{
postfix +=input[i];
}
else if (input[i] == '(')
{
S->Push(input[i]);
}
else if (input[i]==')')
{
while(!S->IsStackEmpty() && S->StackTop() != '('){
postfix += S->StackTop();
S->Pop();
}
S->Pop();
}
}
while(!S->IsStackEmpty()){
postfix +=S->StackTop();
S->Pop();
}
cout <<""<<postfix;
return postfix;
}
bool IsOperand(char C)
{
if(C>= '0' && C<= '9') return true;
if(C>= 'a' && C<= 'z') return true;
if(C>= 'A' && C<= 'Z') return true;
return false;
}
bool IsOperator(char C)
{
if(C=='+' || C== '-' || C =='*' || C == '/' ||C == '$')
{
return true;
}else{
return false;
}
}
int IsRightAssociative(char op)
{
if(op=='$'){
return true;
}else{
return false;
}
}
int GetOperatorWeight(char op){
int weight = -1;
switch(op)
{
case'+':
case '-':
weight=1;
break;
case '*':
case '/':
weight=2;
break;
case '$':
weight=3;
break;
}
return weight;
}
int HasHigherPrecedence ( char op1, char op2)
{
int op1Weight= GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
if(op1Weight == op2Weight)
{
if(IsRightAssociative(op1))
{
return false;
}else{
return true;
}
return op1Weight > op2Weight ? true:false;
}
}

One suggestion: use a tree, rather than a stack, as an intermediate data structure. Let the operator with lowest precedence be the root of the tree and build it recursively from there. Then walk through the tree from left to right, again recursively, to generate the postfix version. That way, you can also keep track of the maximum stack depth for the postfix version, which can be important as many hand-held RPN calculators, for example, have very limited stack depths.

Related

Finding whether the binary tree is valid bst

I get Following error on running the code below for tree(2,2,2) on leetcode:
AddressSanitizer:DEADLYSIGNAL
==31==ERROR: AddressSanitizer: stack-overflow on address 0x7ffe3ba89ff8 (pc 0x000000372df9 bp 0x7ffe3ba8a010 sp 0x7ffe3ba8a000 T0)
==31==ABORTING
My code is given below:
class Solution {
public:
bool isValidBST(TreeNode* root) {
TreeNode* cur=root;
while(cur){
cout<<cur->val<<endl;
if(!cur->left) {
if(!cur->right) return 1;
int a=cur->val,b=cur->right->val;
if(a>=b )
return false;
cur=cur->right;
}
else{
TreeNode* prev=cur->left;
while(prev->right && prev->right!=cur)
prev=prev->right;
if(prev->right==NULL){
prev->right=cur;
cur=cur->left;
}
else{
prev->right=0;
if(cur->val>=cur->right->val) return 0;
cur=cur->right;
}
}
}
return 1;
}
};

How to remake the program so that words are passed in function arguments in the KOTLIN programming language?

Need to create a function that implements the attached algorithm, to which all words are passed in the function arguments.
For example:
f ("dfd" dd "ddd");
My code:
fun main() {
var s = readLine();
var w = Array(128){0} //To mark characters from a word 1
var g = Array(128){0}//When we encounter a space, we add units from the first array to the corresponding elements of the second, zeroing them in the first.
if(s!=null)
{
for(c in s)
{
if(c.toInt() > 127 || c.toInt()<0) {
println("Input error, try again");
return;
}
//Checking for space.
if(c.toInt() != 32) w[c.toInt()] = 1;
else
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//For the last word, if there was no space after it.
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//Displaying matched characters to the screen
for(k in 0..127)
{
if(g[k]>1)
{
println(k.toChar());
}
}
}
This program searches for characters that match at least two words in a string
Example
input: hello world
output: lo
There's already utilities for these in Kotlin, I highly recommend you to read the docs before asking these type of questions.
The groupingBy should do what you want:
readLine()?.let { input ->
input.groupingBy { it }.eachCount()
.forEach { if (it.value > 1 && it.key != ' ') println(it.key) }
}

Calculating size of Google Firestore documents

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}
In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

how to find the first and follow values of grammar

i have the following grammar and i would like to create the First & follow table. if i have a case that the first of non terminal is epsilon should i take also all the terminals that came after this non terminal from is rule?
S-> ABC
A->Aa/aB
B->Bb/epsilon
C->Cc/epsilon
and my question is:
in the first of C i need to get First(C) = {epsilon,c) and First(B) = {epsilon,b)?
i got the following results but still i think i have problems:
|first|follow
S |a |$
A |a |a
B |eps,b|b,a,$
C |eps,c|$
Finding the FIRST and Follow of a Grammar written in txt FILE:
#include<stdio.h>
#include<string.h>
#define size 10
int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[size],temp,temp2[size],temp3[20],*ptr;
struct prod
{
char left_of_non_term[size],right_of_nonTerm[size][size],first[size],fol[size];
int n;
}pro[size];
int main()
{
FILE *f;
for(i=0;i<size;i++)
pro[i].n=0;
f=fopen("lab6.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].left_of_non_term);
if(n>0)
{
if( strcmp(pro[n].left_of_non_term,pro[n-1].left_of_non_term) == 0 )
{
pro[n].left_of_non_term[0]='\0';
fscanf(f,"%s",pro[n-1].right_of_nonTerm[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].right_of_nonTerm[pro[n].n]);
pro[n].n++;
n++;
}
printf("\nGiven Grammar");
printf("\n-------------\n");
for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s = %s\n",pro[i].left_of_non_term,pro[i].right_of_nonTerm[j]);
pro[0].first[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].right_of_nonTerm[j][0]<65 || pro[i].right_of_nonTerm[j][0]>90 )
{
pro[i].first[strlen(pro[i].first)]=pro[i].right_of_nonTerm[j][0];
}
else if( pro[i].right_of_nonTerm[j][0]>=65 && pro[i].right_of_nonTerm[j][0]<=90 )
{
temp=pro[i].right_of_nonTerm[j][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
}
printf("-------------");
printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].first);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].first[l]==pro[i].first[j])
break;
if(l==-1)
printf("%c ",pro[i].first[j]);
}
printf("}");
}
for(i=0;i<n;i++)
temp2[i]=pro[i].left_of_non_term[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].right_of_nonTerm[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].right_of_nonTerm[j];
if(pro[l].right_of_nonTerm[j][p+1]>=65 && pro[l].right_of_nonTerm[j][p+1]<=90)
{
for(o=0;o<n;o++)
if(pro[o].left_of_non_term[0]==pro[l].right_of_nonTerm[j][p+1])
strcat(pro[i].fol,pro[o].first);
}
else if(pro[l].right_of_nonTerm[j][p+1]=='\0')
{
temp=pro[l].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].right_of_nonTerm[j][p+1];
}
}
}
}
printf("\n\n\n");
for(i=0;i<n;i++)
{
printf("\nFOLLOW (%s) -> { ",pro[i].left_of_non_term);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
printf(" }");
}
printf("\n");
//getch();
}
void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].left_of_non_term[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].right_of_nonTerm[t][0]<65 || pro[k].right_of_nonTerm[t][0]>90 )
pro[i].first[strlen(pro[i].first)]=pro[k].right_of_nonTerm[t][0];
else if( pro[k].right_of_nonTerm[t][0]>=65 && pro[k].right_of_nonTerm[t][0]<=90 )
{
temp=pro[k].right_of_nonTerm[t][0];
if(temp=='S')
pro[i].first[strlen(pro[i].first)]='#';
findter();
}
}
break;
}
}
}
void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].right_of_nonTerm[t],temp);
if( ptr1 )
{
p1=ptr1-pro[k].right_of_nonTerm[t];
if(pro[k].right_of_nonTerm[t][p1+1]>=65 && pro[k].right_of_nonTerm[t][p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].left_of_non_term[0]==pro[k].right_of_nonTerm[t][p1+1])
{
strcat(pro[i].fol,pro[o1].first);
chk++;
}
}
else if(pro[k].right_of_nonTerm[t][p1+1]=='\0')
{
temp=pro[k].left_of_non_term[0];
if(pro[l].right_of_nonTerm[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].right_of_nonTerm[t]
[p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}
Also Make a text File named it lab6.txt . and put grammers like below
S ABCDE
A a|0
B b|0
C c
D d|0
E e|0
Here space after NonTerminal Indicates the -> this sign and 0 indicates epsilon.

number changed automatically to the string

I am trying to read Excel file through apache poi. In a column I am having the data `"9780547692289". After iterating all the columns, in the output, the number is displaying like this "9.780547692289E12". I mean number changed automatically to the string(because it has'E'). I have to keep this as number only(as it is). What should I do..?
It is probably just a display setting. The "E" is just for scientific notation for displaying the number.
//while getting values from excel u can use this method
private String getCellValue(Cell cell) {
if (cell == null) {
return null;
}
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
return cell.getStringCellValue();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
return cell.getNumericCellValue() + "";
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return cell.getBooleanCellValue() + "";
}else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
return cell.getStringCellValue();
}else if(cell.getCellType() == Cell.CELL_TYPE_ERROR){
return cell.getErrorCellValue() + "";
}
else {
return null;
}
}
This worked for me
if (cell.getCellType()==Cell.CELL_TYPE_NUMERIC || cell.getCellType()==Cell.CELL_TYPE_FORMULA )
{
int i = (int)cell.getNumericCellValue();
String cellText = String.valueOf(i);
}