Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Éditeur live
Cacher identiques
Sans retour à la ligne
Vue
Divisé
Unifié
Niveau de précision
Intelligent
Mot
Caractère
Coloration syntaxique
Choisir la syntaxe
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
Untitled diff
Créé
il y a 8 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
101 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
146 lignes
Copier tout
94 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
175 lignes
Copier tout
Copier
Copié
Copier
Copié
/* Компиля:
#include <
locale
.h>
* gcc -o rpn rpn.c
#include <
vector
>
*
* Использование:
* ./rpn <выражение>
*
* Пример:
* ./rpn 3 5 +
*
* Замечание: знак умножения `*' заменен на `x', т.к. символ `*' используется
* командной оболочкой.
**/
#include <
errno.h>
#include <stdio
.h>
#include <
stdlib.h
>
#define STKDPTH 32 /* Глубина стека */
#define STKDPTH 32 /* Глубина стека */
/* Значения, возвращаемые функцией parse */
/* Значения, возвращаемые функцией parse */
#define VAL 0 /* В стек занесено новое значение */
#define VAL 0 /* В стек занесено новое значение */
#define ADD 1 /* Сложение */
#define ADD 1 /* Сложение */
#define SUB 2 /* Вычитание */
#define SUB 2 /* Вычитание */
#define MUL 3 /* Умножение */
#define MUL 3 /* Умножение */
#define DIV 4 /* Деление */
#define DIV 4 /* Деление */
#define SOF -1 /* Переполнение стека */
#define SOF -1 /* Переполнение стека */
#define SUF -2 /* В стеке недостаточно операндов */
#define SUF -2 /* В стеке недостаточно операндов */
#define UNK -3 /* Неопознанное значение */
#define UNK -3 /* Неопознанное значение */
Copier
Copié
Copier
Copié
#define NODEBIT (size_t(1) << (sizeof(size_t) * 8 - 1))
struct node {
size_t left;
size_t right;
int type;
node(int type, size_t left, size_t right)
: type(type), left(left), right(right)
{
}
};
/* Глобальные переменные */
/* Глобальные переменные */
int scount;
int scount;
Copier
Copié
Copier
Copié
double
stack[STKDPTH];
std::vector<node> tree;
std::vector<
double
> operands;
size_t
stack[STKDPTH];
/* Функция распознавания аргументов */
/* Функция распознавания аргументов */
int parse(char *);
int parse(char *);
Copier
Copié
Copier
Copié
/* Функция печати дерева */
void printTree();
/* Точка входа */
/* Точка входа */
int main(int argc, char **argv)
int main(int argc, char **argv)
{
{
Copier
Copié
Copier
Copié
setlocale(LC_ALL, "Russian");
/* Организуем цикл для перебора аргументов командной строки */
/* Организуем цикл для перебора аргументов командной строки */
Copier
Copié
Copier
Copié
while
(
*++argv
) {
while
(
*++argv
) {
/* Пытаемся распознать текущий аргумент как число или
/* Пытаемся распознать текущий аргумент как число или
Copier
Copié
Copier
Copié
* символ арифметической операции */
* символ арифметической операции */
switch (
parse(*argv)
) {
int type =
parse(*argv)
;
case VAL: continue;
switch( type
) {
case VAL: continue;
/* Вычисляем */
/* Вычисляем */
Copier
Copié
Copier
Copié
case ADD:
case ADD:
stack[scount - 1] += stack[scount];
case SUB:
break;
case MUL:
case DIV:
case SUB:
tree.emplace_back(type,
stack[scount - 1]
,
stack[scount]
);
stack[scount - 1] -= stack[scount];
stack[scount - 1] = NODEBIT | (tree.size() -
1);
break;
break;
case MUL:
stack[scount - 1] *= stack[scount];
break;
case DIV:
if (stack[scount] != 0) {
stack[scount - 1]
/=
stack[scount]
;
break;
} else {
fprintf(stderr, "Деление на ноль!\n");
return(
1);
}
Copier
Copié
Copier
Copié
/* Обработка ошибок */
/* Обработка ошибок */
case SUF:
case SUF:
fprintf(stderr, "Недостаточно операндов!\n");
fprintf(stderr, "Недостаточно операндов!\n");
return(1);
return(1);
Copier
Copié
Copier
Copié
case SOF:
case SOF:
fprintf(stderr, "Переполнение стека!\n");
fprintf(stderr, "Переполнение стека!\n");
return(1);
return(1);
Copier
Copié
Copier
Copié
case UNK:
case UNK:
fprintf(stderr, "Неопознанный аргумент!\n");
fprintf(stderr, "Неопознанный аргумент!\n");
return(1);
return(1);
}
}
}
}
/* Вывести результат */
/* Вывести результат */
Copier
Copié
Copier
Copié
auto int i;
print
Tree(
);
for (i = 0; i < scount; i++)
print
f("%0.3f\n", stack[i]
);
return(0);
return(0);
}
}
int parse(char *s)
int parse(char *s)
{
{
double tval = 0;
double tval = 0;
char * endptr;
char * endptr;
/* Распознаем знаки арифметических операций */
/* Распознаем знаки арифметических операций */
Copier
Copié
Copier
Copié
switch
(*s
) {
switch
( *s
) {
case '-':
case '-':
/* Если минус является первым и не последним символом аргумента,
/* Если минус является первым и не последним символом аргумента,
* значит пользователь ввел отрицательное число и опознавать его
* значит пользователь ввел отрицательное число и опознавать его
* как операцию вычитания не нужно */
* как операцию вычитания не нужно */
if
(
*(s
+
1) != '\0'
) break;
if
(
*(s
+
1) != '\0'
) break;
if
(
scount >= 2
) {
if
(
scount >= 2
) {
scount -= 1;
scount -= 1;
return(SUB);
return(SUB);
}
}
else return(SUF);
else return(SUF);
Copier
Copié
Copier
Copié
case '+':
case '+':
if
(
scount >= 2
) {
if
(
scount >= 2
) {
scount -= 1;
scount -= 1;
return(ADD);
return(ADD);
}
}
else return(SUF);
else return(SUF);
Copier
Copié
Copier
Copié
case 'x':
case 'x':
if
(
scount >= 2
) {
if
(
scount >= 2
) {
scount -= 1;
scount -= 1;
return(MUL);
return(MUL);
}
}
else return(SUF);
else return(SUF);
Copier
Copié
Copier
Copié
case '/':
case '/':
if
(
scount >= 2
) {
if
(
scount >= 2
) {
scount -= 1;
scount -= 1;
return(DIV);
return(DIV);
}
}
else return(SUF);
else return(SUF);
}
}
errno = 0;
errno = 0;
/* Пытаемся сконвертировать строковый аргумент в число */
/* Пытаемся сконвертировать строковый аргумент в число */
tval = strtod(s, &endptr);
tval = strtod(s, &endptr);
/* Вернуть ошибку `неопознанный аргумент' в случае неудачи */
/* Вернуть ошибку `неопознанный аргумент' в случае неудачи */
Copier
Copié
Copier
Copié
if
(
errno != 0 || *endptr != '\0'
) return(UNK);
if
(
errno != 0 || *endptr != '\0'
) return(UNK);
/* Проверяем, есть ли свободное место в стеке
/* Проверяем, есть ли свободное место в стеке
Copier
Copié
Copier
Copié
* и сохраняем в нем операнд, иначе возвращаем ошибку переполнения */
* и сохраняем в нем операнд, иначе возвращаем ошибку переполнения */
if
(
scount < STKDPTH
) stack[scount++] =
tval
;
operands.push_back(tval);
if
(
scount < STKDPTH
) stack[scount++] =
operands.size() - 1
;
else return(SOF);
else return(SOF);
return(VAL);
return(VAL);
}
}
Copier
Copié
Copier
Copié
void printTree()
{
std::vector<std::pair<size_t, int>> local;
for( int i = 0; i < scount; i++ ) {
local.emplace_back(stack[i], 0);
while( !local.empty() ) {
auto st = local.back();
local.pop_back();
// indent
for( int i = st.second; i--; putc('\x20', stdout), putc('\x20', stdout) );
if( (st.first & NODEBIT) != 0 ) {
auto &n = tree[st.first & ~NODEBIT];
local.emplace_back(n.right, st.second + 1);
local.emplace_back(n.left, st.second + 1);
switch( n.type ) {
case ADD:
printf("+ (add)\n");
break;
case SUB:
printf("- (sub)\n");
break;
case MUL:
printf("x (mul)\n");
break;
case DIV:
printf("/ (div)\n");
break;
default:
printf("unexpected\n");
}
} else {
printf("%0.3f\n", operands[st.first]);
}
}
}
}
Différences enregistrées
Texte d'origine
Ouvrir un fichier
/* Компиля: * gcc -o rpn rpn.c * * Использование: * ./rpn <выражение> * * Пример: * ./rpn 3 5 + * * Замечание: знак умножения `*' заменен на `x', т.к. символ `*' используется * командной оболочкой. **/ #include <errno.h> #include <stdio.h> #include <stdlib.h> #define STKDPTH 32 /* Глубина стека */ /* Значения, возвращаемые функцией parse */ #define VAL 0 /* В стек занесено новое значение */ #define ADD 1 /* Сложение */ #define SUB 2 /* Вычитание */ #define MUL 3 /* Умножение */ #define DIV 4 /* Деление */ #define SOF -1 /* Переполнение стека */ #define SUF -2 /* В стеке недостаточно операндов */ #define UNK -3 /* Неопознанное значение */ /* Глобальные переменные */ int scount; double stack[STKDPTH]; /* Функция распознавания аргументов */ int parse(char *); /* Точка входа */ int main(int argc, char **argv) { /* Организуем цикл для перебора аргументов командной строки */ while (*++argv) { /* Пытаемся распознать текущий аргумент как число или * символ арифметической операции */ switch (parse(*argv)) { case VAL: continue; /* Вычисляем */ case ADD: stack[scount - 1] += stack[scount]; break; case SUB: stack[scount - 1] -= stack[scount]; break; case MUL: stack[scount - 1] *= stack[scount]; break; case DIV: if (stack[scount] != 0) { stack[scount - 1] /= stack[scount]; break; } else { fprintf(stderr, "Деление на ноль!\n"); return(1); } /* Обработка ошибок */ case SUF: fprintf(stderr, "Недостаточно операндов!\n"); return(1); case SOF: fprintf(stderr, "Переполнение стека!\n"); return(1); case UNK: fprintf(stderr, "Неопознанный аргумент!\n"); return(1); } } /* Вывести результат */ auto int i; for (i = 0; i < scount; i++) printf("%0.3f\n", stack[i]); return(0); } int parse(char *s) { double tval = 0; char * endptr; /* Распознаем знаки арифметических операций */ switch (*s) { case '-': /* Если минус является первым и не последним символом аргумента, * значит пользователь ввел отрицательное число и опознавать его * как операцию вычитания не нужно */ if (*(s+1) != '\0') break; if (scount >= 2) { scount -= 1; return(SUB); } else return(SUF); case '+': if (scount >= 2) { scount -= 1; return(ADD); } else return(SUF); case 'x': if (scount >= 2) { scount -= 1; return(MUL); } else return(SUF); case '/': if (scount >= 2) { scount -= 1; return(DIV); } else return(SUF); } errno = 0; /* Пытаемся сконвертировать строковый аргумент в число */ tval = strtod(s, &endptr); /* Вернуть ошибку `неопознанный аргумент' в случае неудачи */ if (errno != 0 || *endptr != '\0') return(UNK); /* Проверяем, есть ли свободное место в стеке * и сохраняем в нем операнд, иначе возвращаем ошибку переполнения */ if (scount < STKDPTH) stack[scount++] = tval; else return(SOF); return(VAL); }
Texte modifié
Ouvrir un fichier
#include <locale.h> #include <vector> #define STKDPTH 32 /* Глубина стека */ /* Значения, возвращаемые функцией parse */ #define VAL 0 /* В стек занесено новое значение */ #define ADD 1 /* Сложение */ #define SUB 2 /* Вычитание */ #define MUL 3 /* Умножение */ #define DIV 4 /* Деление */ #define SOF -1 /* Переполнение стека */ #define SUF -2 /* В стеке недостаточно операндов */ #define UNK -3 /* Неопознанное значение */ #define NODEBIT (size_t(1) << (sizeof(size_t) * 8 - 1)) struct node { size_t left; size_t right; int type; node(int type, size_t left, size_t right) : type(type), left(left), right(right) { } }; /* Глобальные переменные */ int scount; std::vector<node> tree; std::vector<double> operands; size_t stack[STKDPTH]; /* Функция распознавания аргументов */ int parse(char *); /* Функция печати дерева */ void printTree(); /* Точка входа */ int main(int argc, char **argv) { setlocale(LC_ALL, "Russian"); /* Организуем цикл для перебора аргументов командной строки */ while( *++argv ) { /* Пытаемся распознать текущий аргумент как число или * символ арифметической операции */ int type = parse(*argv); switch( type ) { case VAL: continue; /* Вычисляем */ case ADD: case SUB: case MUL: case DIV: tree.emplace_back(type, stack[scount - 1], stack[scount]); stack[scount - 1] = NODEBIT | (tree.size() - 1); break; /* Обработка ошибок */ case SUF: fprintf(stderr, "Недостаточно операндов!\n"); return(1); case SOF: fprintf(stderr, "Переполнение стека!\n"); return(1); case UNK: fprintf(stderr, "Неопознанный аргумент!\n"); return(1); } } /* Вывести результат */ printTree(); return(0); } int parse(char *s) { double tval = 0; char * endptr; /* Распознаем знаки арифметических операций */ switch( *s ) { case '-': /* Если минус является первым и не последним символом аргумента, * значит пользователь ввел отрицательное число и опознавать его * как операцию вычитания не нужно */ if( *(s + 1) != '\0' ) break; if( scount >= 2 ) { scount -= 1; return(SUB); } else return(SUF); case '+': if( scount >= 2 ) { scount -= 1; return(ADD); } else return(SUF); case 'x': if( scount >= 2 ) { scount -= 1; return(MUL); } else return(SUF); case '/': if( scount >= 2 ) { scount -= 1; return(DIV); } else return(SUF); } errno = 0; /* Пытаемся сконвертировать строковый аргумент в число */ tval = strtod(s, &endptr); /* Вернуть ошибку `неопознанный аргумент' в случае неудачи */ if( errno != 0 || *endptr != '\0' ) return(UNK); /* Проверяем, есть ли свободное место в стеке * и сохраняем в нем операнд, иначе возвращаем ошибку переполнения */ operands.push_back(tval); if( scount < STKDPTH ) stack[scount++] = operands.size() - 1; else return(SOF); return(VAL); } void printTree() { std::vector<std::pair<size_t, int>> local; for( int i = 0; i < scount; i++ ) { local.emplace_back(stack[i], 0); while( !local.empty() ) { auto st = local.back(); local.pop_back(); // indent for( int i = st.second; i--; putc('\x20', stdout), putc('\x20', stdout) ); if( (st.first & NODEBIT) != 0 ) { auto &n = tree[st.first & ~NODEBIT]; local.emplace_back(n.right, st.second + 1); local.emplace_back(n.left, st.second + 1); switch( n.type ) { case ADD: printf("+ (add)\n"); break; case SUB: printf("- (sub)\n"); break; case MUL: printf("x (mul)\n"); break; case DIV: printf("/ (div)\n"); break; default: printf("unexpected\n"); } } else { printf("%0.3f\n", operands[st.first]); } } } }
Trouver la différence