Преобразование префикс выражения в инфиксной


Вот мой новый рабочий код. Человек, работая со строками в C-это утомительно и раздражает. Я построил алгоритм в короткие сроки, понадобилось несколько часов, выясняя, как это правильно реализовать на C. подскажите, если есть более ошибок или если некоторое улучшение возможно.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
  char data[100];
  struct node *next;
}SNode;

typedef struct{
 int count;
 SNode *top;
}stack;

int isEmpty(stack *s){
  return (s->count==0);
 }

void push(stack *s,char x[]){
  SNode *temp = (SNode *)malloc(sizeof(SNode));
  strcpy(temp->data,x);
  temp->next = s->top;
  s->top=temp;
  s->count++;
  }

char * pop(stack *s){
     if(isEmpty(s)){
      return "-1";

     }
    SNode *temp = s->top;
    s->top = temp->next;
    static char a[10];
    strcpy(a,temp->data);
    free(temp);
    s->count--;
    return a;
  }


 int main(){
    stack *s = (stack *)malloc(sizeof(stack));
    s->count = 0;
    char a[100];
    printf("Enter prefix expression: ");
    gets(a);
    int i;
    for(i=strlen(a)-1;i>=0;i--){
    if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'){
       char s1[10], s2[10];
       strcpy(s1,pop(s));
       strcpy(s2, pop(s));
       char b1[10] ="(",b2[10]=")";
       strcat(b1,s1);
       char t[2]="\0";
       t[0]=a[i];
       strcat(b1,t);
       strcat(b1,s2);
       strcat(b1,b2);
       push(s,b1);
      }
     else if(isalpha(a[i])){
         char t[2] = "\0";
          t[0] = a[i];
          push(s,t);
     }
    }
    char *infix = pop(s);
    printf("Infix expression: %s",infix);
    return 0; 
     } 


284
1
задан 30 марта 2018 в 12:03 Источник Поделиться
Комментарии
2 ответа

malloc()

В общем, malloc может потерпеть неудачу, и вернется NULL когда это произойдет, вы должны смириться с этим.

Результат malloc не должен быть приведен к целевому типу, кроме того, как правило, безопаснее использовать целевой переменной в sizeof выражение.

stack *s = malloc(sizeof *s); 
if (s == NULL) { // deal with it}

gets()

У вас есть буфер, который находится в 100 символов, старый стиль gets() буду писать за конец буфера, вы должны попробовать и использовать gets_s() если ваш компилятор поддерживает С11 или fgets() е.г fgets(buffer, 100, stdin)

Редактирования строку на месте

Смысл смены символов в строке без дополнительного выделения памяти. Ты меняешь строку на месте, это, вероятно, делает вещи намного более сложными, чем они должны быть. Используя входную и выходную строку, будет ясность. Используя указатель на строку, а не Индекс строки могли бы сделать вещи немного более читабельным, а также. Я не думаю, что я бы выбрал, чтобы изменить строку на месте, пока я не был вынужден сделать это. Не сдвигая строку также делает его легче визуализировать то, что происходит, как только у вас есть, чтобы переместить указатель вперед.

Доступ к строке по индексу

С char* buffer, buffer[i] и *buffer эквивалентны; я бы, наверное, тенденция больше в сторону используя строковый указатель, а не Индекс, что может быть дело вкуса.

Последовательность именования

У вас есть node структура typedefed как SNode и стек просто typedefed как stack. Это легко заметить, когда кто-то не согласуется, независимо от того, если я согласен со стилем или нет. Здесь есть два способа, как вы определяете структуру и двумя вариантами (один оприходованы, а другой нет) написания оператора typedef; придерживаться одну сторону.

pop()

Появляются пустые стопки ошибка, в большинстве случаев, если не вы, вероятно, должны рассматривать это как ошибку и утверждать на пустом стеке. Возвращаясь \0 скрывает тот факт, что вы пытались назвать поп на пустой стек, что делает его труднее отследить ошибку

Предупреждения

isalpha() определяется в <ctype.h> который не входит

Ошибка

*+ab+cd анализируется как a + b * c + d а с учетом приоритета операторов, что это неправильно - результат должен быть (a + b) * (c + d).

3
ответ дан 30 марта 2018 в 05:03 Источник Поделиться

Поскольку ваш код полагается на максимальная длина 100 вы можете уменьшить много код для вашего стека с помощью простого массива. Тест на переполнение стека должны быть добавлены.

typedef struct {
char *data[20];
char **top;
} Stack;

int main() {
Stack stack;
stack.top = stack.data;
......

// if you like..
for(i=0; i<sizeof(stack.data)/sizeof(*stack.data); i++)
if(stack.data[i]!=null) free(stack.data[i])
}

void push(Stack *s, char *t) {
if(*s->top==null)
*s->top = malloc(100);
strcpy(*s->top, t);
s->top++;
}
char *pop(Stack *s) {
if(s->top > s->data) {
s->top--;
return *s->top;
}
return null;
}

0
ответ дан 5 апреля 2018 в 09:04 Источник Поделиться