hello we have to convert an expression like "43 + machula0 = 163"
as 43 + 120 = 163.means we have to scan the expression and then find the missing part.my program runs good without putting the while loop but it shows the error when i run it with the loop.
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdlib>
using namespace std;
void convert(char *a,int size)
{
int i=0;
char c =a[i];
int f1,f2,f3,n1,n2,s=0; //f1,f2,f3 are flags to check machula
f1=0;f2=0;f3=0;n1=0;n2=0;
while(c!='+')//to store no. before plus in n1
{
c=a[i];
if(isalpha(c))//to check whether the character is alphabet or not
{
f1=1;
}
else if(isdigit(c))//to check whether the character is digit
{
int a = c-'0';
n1=n1*10 + a;
}
i++;
}
while(c!='=')//to store no. before plus in n2
{
c=a[i];
if(isalpha(c))
{
f2=1;
}
else if(isdigit(c))
{
int k = c-'0';
n2=n2*10 + k;
}
i++;
}
while(i!=size)//to store no. before plus in s
{
c=a[i];
if(isalpha(c))
{
f3=1;
}
else if(isdigit(c))
{
int h = c-'0';
s=s*10 + h;
}
i++;
}
if(f3==1)
{
s=n1+n2;
cout<<n1<<" + "<<n2<<" = "<<s<<endl;
}
else
{
if(f1==1)
{
n1=s-n2;
cout<<n1<<" + "<<n2<<" = "<<s<<endl;
}
else if(f2==1)
{
n2=s-n1;
cout<<n1<<" + "<<n2<<" = "<<s<<endl;
}
else
{
cout<<n1<<" + "<<n2<<" = "<<s<<endl;
}
}}
int main()
{
int t;
cin>>t;
while(t--)
{
char *a;
a= new char[10000];
cin.getline(a,10000);
int size = strlen(a);
convert(a,size);
delete []a;
}
return 0;
}
On second thought I do have some useful input. If you are typing this in by hand, there is a attendance to type in the input like this:
1
43 + machula0 = 163" as 43 + 120 = 163
and that leads to problems
int main()
{
int t;
cin>>t; // gets up to the end of the number typed.
// It does not get the carriage return from hitting enter to trigger the input.
while(t--)
{
char *a; // Not relevant to the problem, but this is an awesomely bad idea.
// Use a string
a= new char[10000];
cin.getline(a,10000); // returns instantly with an empty string because of the
// left-over enter used above to get the number.
int size = strlen(a);
convert(a,size); // most of convert does not check size, so instantly out of
// array bounds and crash
delete []a;
}
return 0;
}
It will be valid for input like this:
1 43 + machula0 = 163" as 43 + 120 = 163
Better solution:
void convert(string &a)
{
for (char c: a)
{
//parse logic goes here
}
// output logic goes here
}
int main()
{
int t;
cin >> t;
cin.get();
while (t--)
{
string line;
if (getline(cin, line))
{
convert(line);
}
}
return 0;
}
Unfortunately the convert function needs a lot more work. Most obviously the nearly complete lack of testing for the end of the string.
Related
#include <iostream>
#include <string>
using namespace std;
#define Max 100000
class Stack {
private:
int top =-1;
char letters[Max];
public:
void setTop(int t) {
top = t;
}
int getTop() {
return top;
}
bool isEmptyStack() {
if (top == -1) {
return true;
}
else{ return false;
}
}
char push(char x,int s) {
if (top != s - 1){
top++;
x = letters[top];
return x;
}
}
char pop() {
if ((isEmptyStack())==false){
cout << "the deleted value is: " << l[top]<<endl;
top--;
return l[top];
}
}
};
void reverse(char letters[], char temp[], int size, Stack stack) {
int i=0;
for (i = 0; i < size; i++) {
stack.push(letters[i],size);
}
i = 0;
cout << temp<<endl;
while (stack.isEmptyStack() == false)
{
letters[-1] = stack.getTop();
stack.pop();
stack.push(letters[i],size);
i++;
}
/* for (int i = 0; i < size; i++) {
cout << temp[i];
}*/
}
int myStringLength(const char* letter)
{
for (int i = 0, c = 0; letter[i] != '\0'; i++, c++) {
if (letter[i] != '\0')
for (; letter[i] != '\0'; i++, c++)
if (letter[i] == '\0') break;
return c;
}
}
int main()
//initializes the main function
{
Stack stack;
string w;
std::cout << "Enter a Word: ";
getline(cin,w);
char* letters = &w[0];
// sets the character text array to set the number of characters equal to the size of the string
//calls the processData function
std::cout << letters<<endl;
int size = myStringLength(letters);
reverse(letters, letters, size, stack);
return 0;//returns the function at 0.
}
I set out to create a program that will check if a word is a palindrome(meaning it is spelled the same normally and if the word is reversed.) I am not yet at that point that is just the final objective. In my code, I have created a stack class because I wanted to feel the satisfaction of getting the same result using my own code. My problem is the stack is not reversing it is returning some weird characters that I don't have the keys on my keyboard to replicate.
The desired outcome should be word's reversed characters.
if the word is food the function should be returning doof. I have already compared the reversed stack to the original and printed the final statement. I fixed the char letters[];
If you're open to using a simple function instead of a Stack then you could use the following program since it is much more simple than your Stack version and hence less-error prone.
#include <iostream>
#include <string>
bool checkIfPalindroom(const std::string &str)
{
for(int i=0;i<(str.size()/2);i++)
{
if (str[i] != str[str.size() - i - 1])
{
return false;//if this if is satisfied even once, return false
}
}
return true;//if the control flow reaches here this will mean that no if was satisfied and hence return true
}
int main()
{
std::string myString = "Somearbitrarystring";
if(checkIfPalindroom(myString))//call the function
{
std::cout<<"The given string: "<<myString <<" is a palindrome"<<std::endl;
}
else
{
std::cout<<"The given string: "<<myString<<" is not a palindrome"<<std::endl;
}
return 0;
}
I want to make a lexical analyzer using c++ that can -
remove single/multiline comments and produce the fresh text
identify keywords
identfy variables
identify special symbols
from a text file as input of the program and finally output all of them in a separate text file as output from the program.
I have already coded the program. But It is unable to identfy the identifiers as variable and removing any commentline from the given text. My code is given below:
#include<bits/stdc++.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
using namespace std;
int isKeyword(char buffer[])
{
char keywords[32][10] =
{
"auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if","int","long","register","return","short","signed",
"sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while"
};
int i, flag = 0;
for(i = 0; i < 32; ++i)
{
if(strcmp(keywords[i], buffer) == 0)
{
flag = 1;
break;
}
}
return flag;
}
int main()
{
char ch, buffer[15], special[]=",;\(){}[]'':";
ifstream My_input_file("D:\\input1.txt");
ofstream My_output_file("D:\\output1.txt");
int mark[1000]= {0};
int i,j=0,kc=0,ic=0,sc=0;
vector < string > k;
vector<char >id;
vector<char>sp;
string line;
int flag=1;
if(My_input_file.is_open())
{
while(getline(My_input_file,line))
{
int lenth=line.length(),i;
char* newline = new char[lenth+1];
strcpy(newline,line.c_str());
for(i=0; i<lenth; i++)
{
if(newline[i]=='/'&& newline[i+1]=='/')
break;
if (newline[i]=='/'&& newline[i+1]=='*')
flag=2;
if (newline[i]=='*'&& newline[i+1]=='/')
{flag=1;
i++;}
else if(flag==1)
My_output_file<<newline[i];
}
My_output_file<<"\n";
while(!My_input_file.eof())
{
ch = My_input_file.get();
for(i = 0; i < 12; ++i)
{
if(ch == special[i])
{
int aa=ch;
if(mark[aa]!=1)
{
sp.push_back(ch);
mark[aa]=1;
++sc;
}
}
}
if(isalnum(ch))
{
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0))
{
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
{
k.push_back(buffer);
++kc;
}
else
{
if(buffer[0]>=97 && buffer[0]<=122)
{
if(mark[buffer[0]-'a']!=1)
{
id.push_back(buffer[0]);
++ic;
mark[buffer[0]-'a']=1;
}
}
}
}
}
}
}
My_input_file.close();
My_output_file<<"Keyword List: "<<endl;
for(int f=0; f<kc; ++f)
{
if(f==kc-1)
{
My_output_file<<k[f]<<"\n";
}
else
{
My_output_file<<k[f]<<endl;
}
}
My_output_file<<endl;
My_output_file<<"Variable List: "<<endl;
for(int f=0; f<ic; ++f)
{
if(f==ic-1)
{
My_output_file<<id[f]<<"\n";
}
else
{
My_output_file<<id[f]<<endl;
}
}
My_output_file<<endl;
My_output_file<<"Special Symbol List: "<<endl;
for(int f=0; f<sc; ++f)
{
if(f==sc-1)
{
My_output_file<<sp[f]<<"\n";
}
else
{
My_output_file<<sp[f]<<endl;
}
}
return 0;
}
I am using this text file as input. Input Text File Image
After running this code into codeblock it produce the following output. Output Text File Image
But, i want the output like this: Output Required From the Program
Where i am going wrong? Please help me to sort out.
I am using a trie implementation from topcoder.com and trying to store words in a trie structure. I used the code from the net. I can't seem to find out why my input is failing.
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
#define M 10000
#define tr(c,i) for(typeof(c.begin()) i=c.begin(); i!=c.end(); ++i)
class Trie {
public:
int words;
int prefixes;
Trie* edges[26];
Trie();
void addWord(string word);
int countWords(string word);
int countPrefixes(string prefix);
};
Trie::Trie() {
words = 0;
prefixes = 0;
for(int i=0;i<26;++i)
edges[i] = NULL;
}
void Trie::addWord(string word) {
if (word.size()==0)
words = words+1;
else {
prefixes = prefixes+1;
char k = word[0];
if (edges[k-'A']==NULL) {
edges[k-'A'] = new Trie;
}
edges[k-'A']->addWord(word.substr(1));
}
}
int Trie::countWords(string word) {
if (word.size()==0)
return words;
else {
char k = word[0];
if (edges[k-'A']==NULL)
return 0;
else {
return edges[k-'A']->countWords(word.substr(1));
}
}
}
int Trie::countPrefixes(string prefix) {
if (prefix.size()==0)
return prefixes;
else {
char k = prefix[0];
if (edges[k-'A']==NULL)
return 0;
else {
return edges[k-'A']->countPrefixes(prefix.substr(1));
}
}
}
int main()
{
int tests;
cin>>tests;
for(int t=1;t<=tests;t++)
{
Trie root;
int n;
cin>>n;
string str[n];
int ans=0;
for(int i=0;i<n;i++)
{
cin>>str[i];
root.addWord(str[i]);
}
for(int i=0;i<n;i++)
{
ans+=root.countPrefixes(str[i]);
}
cout<<ans;
}
return 0;
}
Any suggestions on what could be wrong? Thank you!
I will be given string. I can remove only 1 element from it. After removing it if the new string becomes palindrome I have to print "Yes" otherwise "No".
For example, I am given a string "abdbca". Here I can remove 5th index 'c' and make it palindrome and i have to print "Yes". On the other hand if the string is something like "abcd" I can not make it palindrome by removing only one character. Hence I have to print "No".
I tried to do it but my code is not efficient enough. Can anybody please suggest me a efficient way to do it? I have to check strings of 10^5 length in less than 2.5 seconds.
the way I tried to do it is shown bellow :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define REP(i,n) for(int i=0;i<n;i++)
#define MAX 100010
using namespace std;
bool isPalindrome(char abc[]){
int len = strlen(abc), lem = len/2;
for(int i=0,n=len-1;i<=lem;i++,n--) if(abc[i]!=abc[n]) return false;
return true;
}
int main()
{
int tc;
char str[MAX];
scanf("%d",&tc);
while(tc--){
scanf("%s", str);
int length = strlen(str), len = length - 1, z = length % 2, res = 0, ans = 0, b=0,lem = length / 2;
for(int i = 0;i<length;i++){
int n=0, m=1;
for(int x = 0, y = len;x<i && y!=i;x++,y--){
n++;
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
if(i>lem) for(int x=n,y=len-n-1;x<y;x++,y--){
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
else for(int x=n+1,y=len-n;x<y;x++,y--){
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
if(m==1) {printf("YES\n");b++;break;}
}
//if(length <= res) printf("NO\n");
if(b==0) printf("NO\n");
}
return 0;
}
Since you you only need to remove one character, you can do so in linear time by modifying palindrome checking. The idea is that you compare characters from the beginning to characters from the end and stop at the first mismatch. If you remove one character from the mismatching pair and get a palindrome, then return true, otherwise return false. I implemented the idea in C++ below.
#include<iostream>
#include<string>
using namespace std;
bool palindromeExists(string s)
{
int i = 0;
int j = s.length()-1;
while(i < j)
{
if(s[i] != s[j]) //first mismatch
break;
i++;
j--;
}
int tempj = j-1; //remove s[j]
int tempi = i;
while(tempi < tempj)
{
if(s[tempi] != s[tempj])
break;
tempi++;
tempj--;
}
if(tempi >= tempj) //palindrome found?
return true;
tempi = i+1; //remove s[i]
tempj = j;
while(tempi < tempj)
{
if(s[tempi] != s[tempj])
return false;
tempi++;
tempj--;
}
return true;
}
int main()
{
string s = "abca";
if(palindromeExists(s))
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
This should return true if the string is already a palindrome, or if it can be a palindrome after the removal of one character. I hope I didn't miss any corner cases.
You can refer complete program in c++ here. Input the string to get the index of character to be removed. String reversal is performed in palim() function. It returns -1 if string is already palindrome.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
bool palim(string s)
{
string s2;
s2=string(s.rbegin(),s.rend());
if(s2==s)
{
return true;
}
else
{
return false;
}
}
int check(string s)
{
int x;
if(s.length()%2==0)
{
for(int i=0,j=s.length()-1;i<s.length()/2,j>=s.length()/2;i++,j--)
{
if(s[i]!=s[j])
{
string s1=s;
s1.erase(j,1);
if(palim(s1))
{
x=j;
break;
}
else
{
string s1=s;
s1.erase(i,1);
if(palim(s1))
{
x=i;
break;
}
}
}
}
}
else
{
for(int i=0,j=s.length()-1;i<s.length()/2,j>s.length()/2;i++,j--)
{
if(s[i]!=s[j])
{
string s1=s;
s1.erase(j,1);
if(palim(s1))
{
x=j;
break;
}
else
{
string s1=s;
s1.erase(i,1);
if(palim(s1))
{
x=i;
break;
}
}
}
}
}
return x;
}
int main()
{
string s;
cin>>s;
if(palim(s))
{
cout<<"-1"<<endl;
}
else
{
cout<<check(s)<<endl;
}
return 0;
}
Similar to turingcomplete, but with sub functions:
bool isPalindrome(std::string::const_iterator& start, std::string::const_iterator& end)
{
while (start < end) {
--end;
if (*start != *end) {
return false;
}
++start;
}
return true;
}
bool test(const std::string& s)
{
auto start = s.begin();
auto end = s.end();
if (isPalindrome(start, end)) {
// If we remove the middle character of a palindrome,
// We still have a palindrome.
return true;
}
// Now test if there is a palindrome
// if we skip the mismatch char from the start or from the end.
auto start2 = start;
auto end2 = end;
++start2;
--end;
return isPalindrome(start, end) || isPalindrome(start2, end2);
}
Live example
I am trying to use 'user434507''s unsigned solution here:
C++ performance challenge: integer to std::string conversion
but instead I want it to return a char * and not accept in a string.
I have been playing around with it for awhile and this is what I have got, but it just returns nothing/garbage - My limited C and pointer knowledge is not helping me. I think I am using malloc right, but in his original code it's as if he uses an internal char* and just changed the elements of a string and returns the string. I figured if I allocated via malloc it would have the same effect :
char * itostr(unsigned val)
{
const char digit_pairs[201] = {
"00010203040506070809"
"10111213141516171819"
"20212223242526272829"
"30313233343536373839"
"40414243444546474849"
"50515253545556575859"
"60616263646566676869"
"70717273747576777879"
"80818283848586878889"
"90919293949596979899"
};
int size;
if(val>=10000) {
if(val>=10000000) {
if(val>=1000000000) {
size=10;
} else if(val>=100000000) {
size=9;
} else {
size=8;
}
} else {
if(val>=1000000) {
size=7;
} else if(val>=100000) {
size=6;
} else {
size=5;
}
}
} else {
if(val>=100) {
if(val>=1000) {
size=4;
} else {
size=3;
}
} else {
if(val>=10) {
size=2;
} else {
size=1;
}
}
}
char * c = (char *)malloc(size + 1);
c[size] = '\0';
//char* c = &s[size-1];
while(val>=100)
{
int pos = val % 100;
val /= 100;
*(short*)(c-1)=*(short*)(digit_pairs+2*pos);
c-=2;
}
while(val>0)
{
*c--='0' + (val % 10);
val /= 10;
}
return c;
}
c += size-1;
You need this line just before the first while loop. The two loops write the digits from right to left. It's needed so that writing starts at the right end of the string.