Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C] Различные нотации записи выражений


Автор: Kronit 19.11.2006, 13:01
Здравствуйте. У меня такое задание. Мне нужно перевести выражение из префиксной записи в обратную польскую (т.е, например,  +a*bc  -->  bc*a+ ). Я так понимаю, что польская обратная запись - это просто постфиксная запись. Я даже понимаю, что мое изначальное выражение (в преф. записи) нужно просто переписать в обратном порядке (в постф. запись). Естественно со всеми проверками на корректнось введенного префиксного выражения. Только символы, не являющиеся знаками, переписать надо в обратном порядке, но не меняя их местами...т.е. как bc не меняются на cb в моем примере. Надеюсь Вы поняли..)

только у меня проблема. Как переписать выражение в обратном порядке - это эллементарно. Но вот как при этом не менять местами символы, не равные знаку?

выбрать их можно:
Код

(a[i] >='0' && a[i] <= '9') || (a[i] >='A' && a[i] <= 'Z') ||(a[i] >='a' && a[i] <= 'z')

а что дальше?

буду ждать ваших предложений. Заранее спасибо.

Автор: Sartorius 19.11.2006, 13:57
 Выбирай из входной строки подстроки разделенные знаками начиная с конца. Потом их целиком в выходную строку скидывай. 

Автор: Kronit 19.11.2006, 17:52
Цитата(Sartorius @ 19.11.2006,  13:57)
Выбирай из входной строки подстроки разделенные знаками начиная с конца. Потом их целиком в выходную строку скидывай.

Только я не совсем понимаю как это сделать...делать так:
 
Код

l = strlen(a);
j=0;
 for (i=l-1;i>=0;i--) if (a[i]!='+' || a[i]!='*' || .....){ b[g]=a[i] ; g++;}


Но только так в массиве b будут все символы-незнаки подряд и в обратном порядке...
А как вбивать в отдельные массивы? сколько массивов создавать? я же не знаю сволько будит этих блоков символов между знаками.

          
    
     
         

Автор: Partizan 20.11.2006, 15:58
strrev() не поможет?

Автор: Kronit 20.11.2006, 16:31
Цитата(Partizan @ 20.11.2006,  15:58)
strrev() не поможет?

Впринципе переписать строку в обратном порядке так действительно проще, чем через цикл for. Но мне же надо чтобы символьные подстроки(не знаки) не менялись местами.
теперь мне надо чтоб строка: +abc*ab была переписана в строку +cba*ba.
Тогда после strrev() у меня и получится нужная строка ab*abc+

как мне буквы поменять местами?

Автор: Partizan 20.11.2006, 18:19
разбить строку на токены с пом strtok()...в качестве символов-разделителей взять символы арифметических операций и для каждой полученной подстроки сделать strrev....
нерационально, но работать должно...

Автор: Partizan 20.11.2006, 18:49
с помощью strtok всё становится совсем просто...

Автор: Partizan 20.11.2006, 21:55
держи вот...написал пока делать нечего было...

Код

// notations.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <iostream>
#define MAX_LEN 255
#define MAX_TOKENS 50
#define MAX_OPERS 255

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

    char cOrigStr[MAX_LEN];
    char *cOutputStr;
    char *tokens[MAX_TOKENS];
    char opers[MAX_OPERS] = "\0"; 
    const char cSeparators[] = "+-*/";
    int i = 0;
    cin >> cOrigStr;

    
    i = 0;   

    for (int j = 0; j < strlen(cOrigStr); j++)
        if (cOrigStr[j] == '+' || cOrigStr[j] == '-' || cOrigStr[j] == '*' || cOrigStr[j] == '/'){
            opers[i] = cOrigStr[j];
            opers[i+1]='\0';
            cout << opers[i] << endl;
            i++;
        }


    i = 0;
    tokens[i] = strtok(cOrigStr, cSeparators);
    
    while(tokens[i] != NULL){
                  i++;
      tokens[i] = strtok(NULL, cSeparators);
    };

    cOutputStr = new char[MAX_LEN];
    cOutputStr[0] = '\0';

    for (int j = 0; j<i; j++){
      
      strcat(cOutputStr, tokens[i-j-1]);
      strncat(cOutputStr, &opers[i-j-1], 1);
    };

    cout << cOutputStr;
    cin >>cOutputStr;
    return 0;
}


Автор: Kronit 20.11.2006, 23:09
Цитата(Partizan @ 20.11.2006,  21:55)
держи вот...написал пока делать нечего было...

Код

// notations.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <iostream>
#define MAX_LEN 255
#define MAX_TOKENS 50
#define MAX_OPERS 255

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

    char cOrigStr[MAX_LEN];
    char *cOutputStr;
    char *tokens[MAX_TOKENS];
    char opers[MAX_OPERS] = "\0"; 
    const char cSeparators[] = "+-*/";
    int i = 0;
    cin >> cOrigStr;

    
    i = 0;   

    for (int j = 0; j < strlen(cOrigStr); j++)
        if (cOrigStr[j] == '+' || cOrigStr[j] == '-' || cOrigStr[j] == '*' || cOrigStr[j] == '/'){
            opers[i] = cOrigStr[j];
            opers[i+1]='\0';
            cout << opers[i] << endl;
            i++;
        }


    i = 0;
    tokens[i] = strtok(cOrigStr, cSeparators);
    
    while(tokens[i] != NULL){
                  i++;
      tokens[i] = strtok(NULL, cSeparators);
    };

    cOutputStr = new char[MAX_LEN];
    cOutputStr[0] = '\0';

    for (int j = 0; j<i; j++){
      
      strcat(cOutputStr, tokens[i-j-1]);
      strncat(cOutputStr, &opers[i-j-1], 1);
    };

    cout << cOutputStr;
    cin >>cOutputStr;
    return 0;
}


Оки...спасибо выручил..щас буду разбираться. Правда я на С пишу, но думаю Сpp тоже пойму.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)