Exemple #1
0
/*
** Konverzní funkce infix2postfix.
** Ète infixový výraz ze vstupního øetìzce infExpr a generuje
** odpovídající postfixový výraz do výstupního øetìzce (postup pøevodu
** hledejte v pøedná¹kách nebo ve studijní opoøe). Pamì» pro výstupní øetìzec
** (o velikosti MAX_LEN) je tøeba alokovat. Volající funkce, tedy
** pøíjemce konvertovaného øetìzce, zajistí korektní uvolnìní zde alokované
** pamìti.
**
** Tvar výrazu:
** 1. Výraz obsahuje operátory + - * / ve významu sèítání, odèítání,
**    násobení a dìlení. Sèítání má stejnou prioritu jako odèítání,
**    násobení má stejnou prioritu jako dìlení. Priorita násobení je
**    vìt¹í ne¾ priorita sèítání. V¹echny operátory jsou binární
**    (neuva¾ujte unární mínus).
**
** 2. Hodnoty ve výrazu jsou reprezentovány jednoznakovými identifikátory
**    a èíslicemi - 0..9, a..z, A..Z (velikost písmen se rozli¹uje).
**
** 3. Ve výrazu mù¾e být pou¾it pøedem neurèený poèet dvojic kulatých
**    závorek. Uva¾ujte, ¾e vstupní výraz je zapsán správnì (neo¹etøujte
**    chybné zadání výrazu).
**
** 4. Ka¾dý korektnì zapsaný výraz (infixový i postfixový) musí být uzavøen
**    ukonèovacím znakem '='.
**
** 5. Pøi stejné prioritì operátorù se výraz vyhodnocuje zleva doprava.
**
** Poznámky k implementaci
** -----------------------
** Jako zásobník pou¾ijte zásobník znakù tStack implementovaný v pøíkladu c202.
** Pro práci se zásobníkem pak pou¾ívejte výhradnì operace z jeho rozhraní.
**
** Pøi implementaci vyu¾ijte pomocné funkce untilLeftPar a doOperation.
**
** Øetìzcem (infixového a postfixového výrazu) je zde my¹leno pole znakù typu
** char, jen¾ je korektnì ukonèeno nulovým znakem dle zvyklostí jazyka C.
**
** Na vstupu oèekávejte pouze korektnì zapsané a ukonèené výrazy. Jejich délka
** nepøesáhne MAX_LEN-1 (MAX_LEN i s nulovým znakem) a tedy i výsledný výraz
** by se mìl vejít do alokovaného pole. Po alokaci dynamické pamìti si v¾dycky
** ovìøte, ¾e se alokace skuteènì zdraøila. V pøípadì chyby alokace vra»te namísto
** øetìzce konstantu NULL.
*/
char* infix2postfix (const char* infExpr) {
    char *postExpr = malloc(MAX_LEN * sizeof(char));
    unsigned postLen = 0;

    tStack stack;
    stackInit(&stack);

    char tmp;
    for(unsigned i = 0; (tmp = infExpr[i]) != '='; i++) {
        switch(tmp) {
        case '+':
        case '-':
        case '*':
        case '/':
            // Zpracuj operator
            doOperation(&stack, tmp, postExpr, &postLen);
            break;
        case '(':
            // Pridaj lavu zatvorku do zasobniku.
            stackPush(&stack, '(');
            break;
        case ')':
            // Zpracuj pravu zatvorku.
            untilLeftPar(&stack, postExpr, &postLen);
            break;
        default:
            // Zpracuj hodnotu.
            // isalnum()
            if((tmp >= '0' && tmp <='9') || (tmp >= 'a' && tmp <= 'z') || (tmp >= 'A' && tmp <= 'Z'))
                postExpr[postLen++] = tmp;
            break;
        }
    }
    while(!stackEmpty(&stack)) {
        stackTop(&stack, &tmp);
        postExpr[postLen++] = tmp;
        stackPop(&stack);
    }
    postExpr[postLen++] = '=';
    postExpr[postLen] = '\0';

    return postExpr;
}
Exemple #2
0
/* 
** Konverzní funkce infix2postfix.
** Ète infixový výraz ze vstupního øetìzce infExpr a generuje
** odpovídající postfixový výraz do výstupního øetìzce (postup pøevodu
** hledejte v pøedná¹kách nebo ve studijní opoøe). Pamì» pro výstupní øetìzec
** (o velikosti MAX_LEN) je tøeba alokovat. Volající funkce, tedy
** pøíjemce konvertovaného øetìzce, zajistí korektní uvolnìní zde alokované
** pamìti.
**
** Tvar výrazu:
** 1. Výraz obsahuje operátory + - * / ve významu sèítání, odèítání,
**    násobení a dìlení. Sèítání má stejnou prioritu jako odèítání,
**    násobení má stejnou prioritu jako dìlení. Priorita násobení je
**    vìt¹í ne¾ priorita sèítání. V¹echny operátory jsou binární
**    (neuva¾ujte unární mínus).
**
** 2. Hodnoty ve výrazu jsou reprezentovány jednoznakovými identifikátory
**    a èíslicemi - 0..9, a..z, A..Z (velikost písmen se rozli¹uje).
**
** 3. Ve výrazu mù¾e být pou¾it pøedem neurèený poèet dvojic kulatých
**    závorek. Uva¾ujte, ¾e vstupní výraz je zapsán správnì (neo¹etøujte
**    chybné zadání výrazu).
**
** 4. Ka¾dý korektnì zapsaný výraz (infixový i postfixový) musí být uzavøen 
**    ukonèovacím znakem '='.
**
** 5. Pøi stejné prioritì operátorù se výraz vyhodnocuje zleva doprava.
**
** Poznámky k implementaci
** -----------------------
** Jako zásobník pou¾ijte zásobník znakù tStack implementovaný v pøíkladu c202. 
** Pro práci se zásobníkem pak pou¾ívejte výhradnì operace z jeho rozhraní.
**
** Pøi implementaci vyu¾ijte pomocné funkce untilLeftPar a doOperation.
**
** Øetìzcem (infixového a postfixového výrazu) je zde my¹leno pole znakù typu
** char, jen¾ je korektnì ukonèeno nulovým znakem dle zvyklostí jazyka C.
**
** Na vstupu oèekávejte pouze korektnì zapsané a ukonèené výrazy. Jejich délka
** nepøesáhne MAX_LEN-1 (MAX_LEN i s nulovým znakem) a tedy i výsledný výraz
** by se mìl vejít do alokovaného pole. Po alokaci dynamické pamìti si v¾dycky
** ovìøte, ¾e se alokace skuteènì zdraøila. V pøípadì chyby alokace vra»te namísto
** øetìzce konstantu NULL.
*/
char* infix2postfix (const char* infExpr) {
	char *postExpr;
	unsigned postLen = 0;
	int stringSize;
	tStack *s;

	// alokace vystupniho retezce
	if ((postExpr = (char *) malloc(MAX_LEN)) == NULL) {
		return NULL;
	}

	// alokace zasobniku
	if ((s = malloc(sizeof(char *) * STACK_SIZE)) == NULL) {
		free(postExpr);
		return NULL;
	}

	// inicializace zasobniku
	stackInit(s);

	// zjisteni delky retezce
	stringSize = snprintf(NULL, 0, "%s", infExpr);

	// zpracovani retezce
	for (unsigned i = 0; i <= stringSize; i++) {
		if (
		    (infExpr[i] >= '0' && infExpr[i] <= '9') ||
		    (infExpr[i] >= 'A' && infExpr[i] <= 'Z') ||
		    (infExpr[i] >= 'a' && infExpr[i] <= 'z')
		   ) {
			// nacteni alfanumerickeho znaku do vystupniho retezce
			postExpr[postLen] = infExpr[i];
			postLen++;
		} else if (infExpr[i] == '(') {
			// je-li zpracovana polozka leva zavorka, umistim na
			// vrchol zasobniku
			stackPush(s, infExpr[i]);
		} else if (infExpr[i] == ')') {
			// Je-li zpracovávanou polo¾kou pravá závorka, 
			// odebíram z vrcholu zasobniku polo¾ky a dávam
			// na konec výstupního øetìzce a¾ narazim na levou
			// závorku.
			untilLeftPar(s, postExpr, &postLen);
		} else if (infExpr[i] == '=') {
			// Je-li zpracovávanou polo¾kou '=', pak postupnì 
			// odstraòuju prvky z vrcholu zásobníku a pøidávam na
			// konec øetìzce, a¾ se zásobník zcela vyprázdní.
			// Na konec se pøidá rovnítko, jako omezovaè výrazu.
			while (!stackEmpty(s)) {
				stackTop(s, &postExpr[postLen]);
				postLen++;
				stackPop(s);
			}
				postExpr[postLen] = '=';
				postLen++;
				postExpr[postLen] = '\0';
		} else {
			// zpracovani operatoru
			doOperation(s, infExpr[i], postExpr, &postLen);
		}
	}
	
	free(s);

	return postExpr;
}