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.
Related
I am trying to make program that get infix to postfix but when I entered +- in the infix equation
the output should be +- but I find that the output is ++ and if infix is -+ the output is --
it have been a week since I started to solve that problem
#include <iostream>
#include <string>
using namespace std;
//classes
class arr
{
private:
char *items;
int size;
int length;
public:
//default constructor
arr()
{
items = new char[100];
size = 100;
length = 0;
}
//constructor with parameters
arr(int arraySize)
{
items = new char[arraySize];
size = arraySize;
length = 0;
}
//check if array is empty
bool is_empty()
{
return length == 0 ? true : false;
}
//check if array full
bool is_full()
{
return length >= size - 1 ? true : false;
}
//returns array length
int getLength()
{
return length;
}
//return array size
int getSize()
{
return size;
}
//get array address
char *getAddress()
{
return &items[0];
}
//fill number of items in array based on elementNum
void fill(int elementNum)
{
char ch;
cout << "Enter characters you want to add\n";
if (elementNum > size - 1)
{
cout << "can't use elements number largger than " << size - 1;
return;
}
for (int i = 0; i < elementNum; i++)
{
cin >> ch;
insert(i, ch);
}
}
//display all elements in the array
void display()
{
if (is_empty())
{
cout << "there are no data /n";
return;
}
cout << "Array items are :\n";
for (int i = 0; i < length; i++)
{
cout << items[i] << "\t";
}
cout << endl;
}
void append(char ch)
{
insert(length, ch);
}
void insert(int index, char newItem)
{
if (is_full() || length<index || length + 1 == size)
{
cout << "\nSorry array is full\ncan't append letter more\n";
return;
}
else {
for (int i = length; i >= index; i--)
{
items[i + 1] = items[i];
}
items[index] = newItem;
length++;
}
}
int search(char ch)
{
if (!is_empty())
for (int i = 1; i <= length; i++)
{
if (items[i] == ch)
return i;
}
return 0;
}
void del(int index)
{
if (is_empty() || length<index) {
cout << "sorry can't delete item which is doesn't exist";
return;
}
for (int i = index; i < length; i++)
{
items[i] = items[i + 1];
}
length--;
}
void changeSize(int newSize)
{
if (newSize <= length - 1)
{
cout << "can't change size because the new size is small";
return;
}
char *tempItems = new char[newSize];
size = newSize;
for (int i = 0; i < length; i++)
{
tempItems[i] = items[i];
}
items = tempItems;
tempItems = NULL;
}
//merge two arrays
void merge(arr a)
{
this->size = this->size + a.getSize();
for (int i = 0; i < a.getLength(); i++)
{
items[i + length] = a.getAddress()[i];
}
length = this->length + a.getLength();
}
};
class stackUsingArray {
private:
int top;
arr a;
public:
stackUsingArray()
{
top = -1;
}
stackUsingArray(int stackSize)
{
a.changeSize(stackSize);
top = -1;
}
bool is_empty()
{
return(top == -1);
}
bool is_full()
{
return(a.is_full());
}
void push(char ch)
{
top++;
a.append(ch);
}
char pop()
{
if (is_empty())
{
cout << "sorry the stack is empty";
}
else
return a.getAddress()[top--];
}
int peekTop() {
return top;
}
void display()
{
//first way of display
for (int i = top; i >= 0; i--)
{
cout << a.getAddress()[i];
}
//second way of display
//stackUsingArray c;
//char ch;
//for (int i = top; i >= 0; i--)
// c.push(this->pop());
//for (int i = c.peekTop(); i >= 0; i--)
//{
// ch=c.pop();
// this->push(ch);
// cout << ch;
//}
}
int search(char ch)
{
for (int i = top; i >= 0; i--)
{
if (a.getAddress()[i] == ch)
return i;
}
return -1;
}
char topDisplay()
{
return a.getAddress()[top];
}
};
class stackUsingLinkedList {};
//functions
string infixToPostfix(string infix);
short prec(char ch);
int main()
{
//infix and postfix
stackUsingArray c;
cout<<infixToPostfix("x+y-z");
system("pause");
return 0;
}
string infixToPostfix(string infix)
{
string postfix = "";
stackUsingArray sta;
char ch;
char test;
for (int i = 0; i < infix.length(); i++)
{
switch (prec(infix[i]))
{
case 0:
postfix.append(1, infix[i]);
break;
case 1:
sta.push(infix[i]);
break;
//case 2:
// ch = sta.pop();
// while (ch != '(')
// {
// postfix.append(1, ch);
// ch = sta.pop();
// }
// break;
case 3:
// if (sta.is_empty())
// {
// goto k270;
// }
// ch = sta.pop();
// while (prec(ch) > 3)
// {
// postfix.append(1, ch);
// if (sta.is_empty()) {
// //sta.push(infix[i]);
// goto k270;
// }
// ch = sta.pop();
// }
// sta.push(ch);
//k270:
// sta.push(infix[i]);
test = sta.topDisplay();
if (sta.is_empty())
{
sta.push(infix[i]);
test = sta.topDisplay();
}
else
{
ch = sta.pop();
test = sta.topDisplay();
if (prec(ch) >= 3)
{
postfix += ch;
}
sta.push(infix[i]);
}
}
}
while (!sta.is_empty())
{
postfix.append(1, sta.pop());
}
return postfix;
}
short prec(char ch)
{
if (ch == '(')
return 1;
if (ch == ')')
return 2;
if (ch == '+')
return 3;
if (ch == '-')
return 3;
if (ch == '*')
return 4;
if (ch == '/')
return 4;
return 0;
}
thanks to #IgorTandetnik I figured out that I should del last item from the array when I pop from stack
I was trying this parenthesis matching stack code and every time I run this it only gives me that parenthesis are not matching I don't know what is going wrong. Can you guys please help me out in this and tell me how can I improve this further and is this the right way to use stack in c++ because I was studying from a source that is using c language.
#include<iostream>
using namespace std;
struct stack
{
int size;
int top;
char *arr;
};
int isEmpty(struct stack *ptr)
{
if(ptr->top==-1)
{
return 1;
}
return 0;
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size-1)
{
return 1;
}
return 0;
}
void push(struct stack *ptr,char val)
{
if(isFull(ptr))
{
cout<<"stack overflow"<<endl;
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack *ptr)
{
if (isEmpty(ptr))
{
cout<<"stack underflow"<<endl;
return -1;
}
else
{
char val = ptr->arr[ptr->top];
ptr->top-1;
return val;
}
}
int parenthesisMatch (char * exp)
{
struct stack * sp = new struct stack;
sp->size = 80;
sp->top = -1;
sp->arr = new char(sp->size);
for(int i=0; exp[i]!='\0'; i++)
{
if (exp[i] == '(')
{
push(sp,'(');
}
else if(exp[i] == ')')
{
if (isEmpty(sp))
{
return 0;
}
pop(sp);
}
}
if (isEmpty(sp))
{
return 1;
}
return 0;
}
int main()
{
char *exp = "((8)(*--$$9))";
if(parenthesisMatch(exp))
{
cout<<"The parenthesis is matching\n";
}
else
{
cout<<"The parenthesis is not matching\n";
}
return 0;
}
Just tried to debug the code and found 2 potential errors:
As correctly pointed out by #Welbog in the comments, to create an array, use sp->arr = new char[sp->size; in the function parenthesisMatch().
In the function pop(), the value of the top is not decremented correctly.
Have a look at the working code:
#include<iostream>
struct stack
{
int size;
int top;
char *arr;
};
int isEmpty(struct stack *ptr)
{
if(ptr->top==-1)
{
return 1;
}
return 0;
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size-1)
{
return 1;
}
return 0;
}
void push(struct stack *ptr,char val)
{
if(isFull(ptr))
{
std::cout<<"stack overflow"<<std::endl;
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack *ptr)
{
if (isEmpty(ptr))
{
std::cout<<"stack underflow"<<std::endl;
return -1;
}
else
{
char val = ptr->arr[ptr->top];
ptr->top-=1;
return val;
}
}
int parenthesisMatch (char * exp)
{
struct stack * sp = new struct stack;
sp->size = 80;
sp->top = -1;
sp->arr = new char[sp->size];
for(int i=0; exp[i]!='\0'; i++)
{
if (exp[i] == '(')
{
push(sp,'(');
}
else if(exp[i] == ')')
{
if (isEmpty(sp))
{
return 0;
}
pop(sp);
}
}
if (isEmpty(sp))
{
return 1;
}
return 0;
}
int main()
{
char *exp = "((8)(*--$$9))";
if(parenthesisMatch(exp))
{
std::cout<<"The parenthesis is matching\n";
}
else
{
std::cout<<"The parenthesis is not matching\n";
}
return 0;
}
I have made two classes: stack1 and stack2 and defined my own stack operations of push(), pop(), isempty() and isfull(). I am trying to calculate a postfix expression from an input. I have made another class called operation that is a child of stack1 and stack2, so I can access the functions of push(),pop(), etc.. within operation. I have a function within operation called operate() that does the dirty work on the stacks. Within this function I have a while loop that depends on stack1 not being empty until the operation is complete; HOWEVER, when I step through this function top1, where stack1 is pointing to, has been reset to 0. Is there a way to overcome this/am I doing something wrong? This is the first time I am using classes and such, so I am not sure of the ins and outs.
Here are the definitions of my classes:
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
void push1(int data)
{
if (is_full1());
else
{
num1[top1] = data;
top1++;
}
}
int pop1(void)
{
if(is_empty1());
else
{
top1--;
return num1[top1];
}
}
int is_empty1(void)
{
if(top1 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full1(void)
{
if(top1 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
} };
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
void push2(int data)
{
if (is_full2());
else
{
num2[top2] = data;
top2++;
}
}
int pop2(void)
{
if(is_empty2());
else
{
top2--;
return num2[top2];
}
}
int is_empty2(void)
{
if(top2 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full2(void)
{
if(top2 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
} };
class operation: public stack2, public stack1 {
private:
int answer;
int a;
int b;
int num_cnt;
int ans;
int from_st1;
int from_st2;
public:
int c;
int oper(void)
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
c = 0;
stack1 st1;
stack2 st2;
while(!st1.is_empty1())
{
from_st1 = st1.pop1();
if(from_st1 == plus)
{
st2.push2(from_st1);
}else if(from_st1 == minus)
{
st2.push2(from_st1);
}else if(from_st1 == mult)
{
st2.push2(from_st1);
}else if (from_st1 == divide)
{
st2.push2(from_st1);
}else if(num_cnt == 1)
{
num_cnt = 0;
if(ans == 0)
{
answer = b;
ans++;
}
a = from_st1;
from_st2 = st2.pop2();
if(from_st2 == plus)
{
c = a+answer;
}else if(from_st2 == minus)
{
c = a-answer;
}else if(from_st2 == mult)
{
c = a*answer;
}else if(from_st2 == divide)
{
c = a/answer;
}
}else
{
b = from_st1;
}
num_cnt++;
}
return c;
}
operation()
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
from_st1 = 0;
from_st2 = 0;
} };
I think that the "problem" is with the line:
stack1 st1;
stack2 st2;
This will call the default constructor and set the value of the variables top1 and top2 as zero.
A workaround to this would be to initialise these variables with some positive non-zero value.
Hence the code would look something like(focusing only on the changed parts):
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
.....
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
}
stack1(int top1)
{this.top1 = top1;}
};
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
public:
.....
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
}
stack2(int top2)
{this.top2 = top2;}
};
class operation: public stack2, public stack1 {
.....
public:
int c;
int oper(void)
{
.....
//just an example, can be declared explicitly as well
stack1 st1(5);
stack2 st2(7);
.....
Also, I would advice you to make your code a bit more readable(for instance the presence of 3-liner {} in if cases spanning only a single line). It is just unnecessary consumption of space.
And finally, if the "redefinition" of parent class' variables means the variables re-asserting some value on being inherited, they don't, unless you specify explicitly(such as using a constructor in our case to assign different values to top1 and top2). The inherited class will get a copy of the state of the parent class*.
*meaning they cannot be changed directly by the inherited class. For example if you would've done: int top1=5; initially then top1 would've been 5 until it were to be redefined again somewhere(such as using a constructor)
I take from the problem statement you are trying to build a basic calculator with four operators and need basic expression evaluation done using stack.
Say you have an expression: a+b-cd/e
looks like this in stack: TOP e->/->d->->c->-->b->+->a EMPTY
And this track needs to be evaluated.
Based on these.. you may be looking for something like below:
class stack {
private:
int num[SIZE];
int top;
public:
void push(int data)
{
if (is_full1());
else
{
num[top] = data;
top++;
}
}
int pop(void)
{
if(is_empty());
else
{
top--;
return num[top];
}
}
int is_empty(void)
{
if(top == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full(void)
{
if(top == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack()
{
top = 0; num[SIZE] = {0};
}
};
class operation {
private:
int answer;
int op1;
int op;
boolean isOperator(int val) {
boolen retVal = false;;
if (val == plus ||
val == minus ||
val == divide ||
val == mult) {
retVal = true;
}
else {
retVal = false;
}
return retVal;
}
public:
int oper(stack st1)
{
int from_st1 = 0;
while(!st1.is_empty())
{
from_st1 = st1.pop();
if(isOperator(from_st1))
{
op = from_st1;
}
else if(answer != 0)
{
op1 = from_st1;
if(op == plus)
{
answer = op1 + answer;
}else if(op == minus)
{
answer = op1 - answer;
}else if(op == mult)
{
answer = op1 * answer;
}else if(op == divide)
{
answer = op1 / answer;
}
}
else
{
answer = from_st1;
}
}
return answer;
}
operation()
{
answer = 0;
op1 = 0;
op = 0;
}
};
Note: You can do all evaluation with one stack don't need two stacks. Your operands can not equal to integer values for +, -, * and / for this assignment. You have a valid expression input into stack in main() code.
I am trying to make a program that converts a number written in words to numbers.. (e.g in(sixty-four) -> out(64)) with some exceptions of course. well I struggle in this part of code. I don't know what to put as a return value..
int tys(string x) {
int a=0,n,i;
string sum;
for (auto &c: x) {
if (isalpha(c)) c=tolower(c);
for (i=0;i<x.size()+1;++i) {
if (x[i]=='-') {
for (a=i-2;a<i;++a) {
sum += x[a];
if (sum=="ty") {
i=i-3;
for (a=0;a<i;++a) sum+=x[a];
n=first_digits(sum)*10;
sum=' ';
a=i+4;
while (a<x.size()) {
++a;
sum+=x[a];
if (a==x.size()) {
n+=first_digits(sum);
return n;
}
}
}
}
}
else if (i==x.size()){
for (a=i-1;a<i+1;++a) {
sum += x[a];
if (sum=="ty") {
sum=' ';
while (a <x.size()-3) {
++a;
sum += x[a];
if (a==x.size()-3) {
n = first_digits(sum) * 10;
return n;
}
}
}
}
}
}
}
return true;
}
don't mind the first_digits because it's an int function that works already which gives the numbers from 0-20
about data structures,why i can't output paths of the maze? I use the stack to storage the information of the current position.Read map of maze through a text file,if the position cant't pass
will be marker by "#",it is a wall.the way marker by "+". written in C++.
PS:My English is very poor.
//stack.h
#ifndef _STACK_H_
#define _STACK_H_
#include<iostream>
#include<stdlib.h>
const int SIZE = 81;
using namespace std;
typedef struct
{
int x;
int y;
}PosType;
typedef struct SElemType{
int ord;//steps
PosType seat;//coordinate
int di;//direction
}SElemType;
typedef struct SqStack{
SElemType *base;
SElemType *top;
int StackSize;
}SqStack;
void Init_S(SqStack &S)
{
S.base = new SElemType[SIZE];
if(!S.base)
exit(EXIT_FAILURE);
S.top = S.base;
S.StackSize = SIZE;
}
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
void Push(SqStack &S,SElemType e)
{
SElemType *newbase;
if(S.top-S.base>=S.StackSize)
{
newbase = new SElemType[S.StackSize*2];
if(!S.base)
exit(EXIT_FAILURE);
for(int i(0);i<S.top-S.base;i++)
*(newbase+i) = *(S.base+i);
delete[]S.base;
S.base = newbase;
S.top = S.base+S.StackSize;
S.StackSize *= 2;
}
*(S.top)++ = e;
}
void Pop(SqStack &S,SElemType e)
{
if(StackEmpty(S))
cout<<"empty stack!\n";
else
e = *(--S.top);
}
#endif
//maze.cpp
#include<iostream>
#include<cstdlib>
#include<fstream>
#include"stack.h"
using namespace std;
const int m = 10;
const int n = 10;
typedef char MazeG[m][n];
void Show_MG(MazeG MG)
{
for(int i(0);i<m;i++)
{
for(int j(0);j<n;j++)
{
cout<<MG[i][j];
}
cout<<"\t\n";
}
}
PosType Next(PosType &pos,int di)
{
PosType repos;
switch(di)
{
case 0://north
repos.x = pos.x-1;
repos.y = pos.y;
break;
case 1://east
repos.x = pos.x;
repos.y = pos.y+1;
break;
case 2://south
repos.x = pos.x+1;
repos.y = pos.y;
break;
case 3://west
repos.x = pos.x;
repos.y = pos.y-1;
break;
default:
break;
}
return repos;
}
int MazePath(MazeG &MG,PosType begin,PosType end)
{
PosType curpos = begin;
SqStack S;
Init_S(S);
SElemType e;
e.ord = 0;
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
Pop(S,e);
e.ord--;
while(e.di==3&&!StackEmpty(S))
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e.ord--;
}
if(e.di<3)
{
e.di++;
Push(S,e);
e.ord++;
curpos = Next(curpos,e.di);
}
}
}while(!StackEmpty(S));
cout<<"此迷宫没有入口到出口的路径!\n";//no path of the maze
//return -1;
}
int main()
{
MazeG MG;
PosType begin,end;
begin.x = 1; begin.y = 1;
end.x = 8; end.y = 8;
ifstream fin;
fin.open("file.txt");
if(!fin.is_open())
{
cout<<"erorr file!!\n";
exit(EXIT_FAILURE);
}
if(fin.good())
{
for(int i(0);i<m;i++)
for(int j(0);j<n;j++)
fin>>MG[i][j];
}
cout<<"迷宫图为:(*代表能通过)\n";//map of maze:('*' is means through)
Show_MG(MG);
cout<<begin.x<<begin.y<<end.x<<end.y<<endl;
fin.close();
MazePath(MG,begin,end);
return 0;
}
This is wrong
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
It should be this
bool StackEmpty(SqStack S)
{
if(S.top == S.base) // == not =
return true;
return false;
}
Use == for equality not =.
Now,I understand my the error of code is that I mismatch the data will be stored by stack.
I have changed my code,that's right.
//stack.h
SElemType Gettop(SqStack S)
{
if(!Empty_S(S))
return *(S.top-1);
}
//maze_path.cpp
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
if(e.di<3)
{
e.ord++;
curpos = Next(curpos,e.di);
}
else
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e = Gettop(S);
}
}
}while(!StackEmpty(S));