상용 데이터 구조 창고 의 응용 - 표현 식 값 구하 기
창고.
스 택 은 자주 사용 하 는 데이터 구조 로 스 택 은 스 택 이 라 고도 부 르 며 제 한 된 선형 표 이다.표 의 한 끝 에 요 소 를 삽입 하고 삭제 할 수 있 도록 제한 합 니 다.스 택 에 있 는 요 소 는 후진 선 출 (FILO) 의 성질 에 부합 합 니 다.요 소 를 삽입 하고 삭제 할 수 있 는 한 끝 을 스 택 지붕 이 라 고 하고 다른 한 끝 은 스 택 바닥 이 라 고 합 니 다.창고 에는 두 가지 관건 적 인 조작 이 있 는데, 각각 창고 에서 나 오 는 것 과 창고 에서 나 오 는 것 이다.
창고 에는 두 가지 관건 적 인 조작 이 있 는데, 각각 창고 에서 나 오 는 것 과 창고 에서 나 오 는 것 이다.
스 택 에서 흔히 볼 수 있 는 응용 은 주로 컴 파일 러 에서 문법 분석의 기호 일치, 표현 식 값 구하 기, 프로그램의 함수 호출 등 이 있다.예 를 들 어 운영 체제 의 프로 세 스 의 컨 텍스트 전환, CPU 프로 세 스 의 현장 정보, 예 를 들 어 레지스터 등 정 보 를 스 택 에 저장 하고 CPU 바퀴 가 이 프로 세 스 로 전 환 될 때 스 택 을 사용 하여 현장 을 복원 합 니 다.
표현 식 값 구하 기
표현 식 값 구 하 는 것 은 창고 의 중요 한 응용 이다.예 를 들 어 계산기 의 가감 승제 표현 식 의 계산 은 모두 스 택 을 사용 하여 값 을 구한다.표현 식 의 표현 방법 은 주로 접두사 표현법 과 접두사 표현법 이 있다.
접두사 가 나타 내 는 예 1 + 3 * (4 + 5)
접미사 식 의 예 21 + 3 * 대응 접미사 식 은 (2 + 1) * 3
접미사 표현 식 값 구하 기
접미사 표현 식 을 사용 하여 값 을 구 할 때 괄호 와 연산 기호의 우선 규칙 을 고려 하지 않 고 왼쪽 에서 오른쪽으로 값 을 계산 하면 됩 니 다.
접미사 표현 식 의 값 구 하 는 과정 은:
예 를 들 어 접미사 표현 식
(2+1)*3
에 대응 하 는 접미사 표현 식 은 21+3*
입 니 다.1,2
1,2
. 이때 스 택 이 비어 있 습 니 다 3(1 + 2 = 3)
를 얻 고 3
를 스 택 S 에 눌 러 넣 습 니 다. 이때 스 택 S 는 3
3
, 스 택 S 에 눌 러 넣 습 니 다. 이때 스 택 은 3,3
3,3
이때 스 택 S 가 비어 있 습 니 다 9
. 9
를 스 택 S 9
즉 계산 결과 입 니 다.컴퓨터 는 보통 접미사 표현 식 을 사용 하여 표현 식 값 을 구하 지만, 사람들 은 일반적으로 계산 하 는 표현 식 을 접미사 표현 식 으로 입력 합 니 다. 따라서 표현 식 값 을 구 할 때 접미사 표현 식 을 접미사 표현 식 으로 바 꾼 다음 접미사 표현 식 을 사용 하여 표현 식 값 을 구 해 야 합 니 다.접미사 표현 식 의 값 을 구 하 는 과정 은 매우 간단 합 니 다. 이미 위 에서 분석 하 였 습 니 다.현재 중요 한 단 계 는 접미사 표현 식 을 접미사 표현 식 으로 바 꾸 는 것 입 니 다.
접미사 식 접미사 식
접미사 표현 식 접미사 표현 식 은 표현 식 의 값 을 구 하 는 관건 적 인 단계 입 니 다. 그 과정 은 다음 과 같 습 니 다. 접미사 표현 식 IEXP 를 입력 하고 접미사 표현 식 SEXP 를 출력 하여 접미사 표현 식 IEXP 를 순서대로 읽 습 니 다. 스 택 S 를 초기 화하 여 연산 자 OP 를 저장 합 니 다.
(
이 라면 어떠한 출력 도 없 이 스 택 (
에서 S 까지 step 1 에 들 어 갑 니 다.)
이면 스 택 S 의 요 소 를 SEXP 에 출력 하고 요소 (
를 만 날 때 까지 (
SEXP 에 출력 하지 않 고 step 1 에 들 어 갑 니 다.OP 가 (
와 )
가 아니라면 step 3 (
인지 판단 하고 (
이면 OP 를 S 에 직접 저장 합 니 다.(
가 아니라면 스 택 S 의 요 소 를 SEXP 에 출력 하고 스 택 상단 요소 의 우선 순위 가 OP 보다 작 거나 스 택 이 비 어 있 을 때 까지 step 4 (2+1)*3
이 고 빈 스 택 S 를 초기 화 합 니 다.(
를 읽 고 스 택 S 에 직접 눌 러 넣 습 니 다. 이때 스 택 S 는 (、
입 니 다.2
를 읽 으 면 SEXP 로 직접 출력 합 니 다. 이때 S 는 (
이 고 SEXP 는 2
+
를 읽 었 습 니 다. 스 택 S 스 택 상단 요소 (
이기 때문에 직접 +
을 스 택 S 에 눌 렀 습 니 다. 이때 SEXP 는 2
이 고 스 택 S 는 (、+
1
를 읽 고 직접 출력 합 니 다. 이때 SEXP 21
, 스 택 S (、+
입 니 다.)
를 읽 으 면 스 택 S 의 요 소 를 만 날 때 까지 (
출력 하지 않 음 (
과 )
, SEXP 21+
, 스 택 S 가 비어 있 음 *'
를 읽 고 S 에 저장 합 니 다. 이때 SEXP 는 21+
이 고 스 택 S 는 *
3
를 읽 고 SEXP 에 직접 출력 합 니 다. SEXP 는 21+3
이 고 스 택 S 는 *
21+3*
마지막 으로 접미사 표현 식 21+3*
을 얻 을 수 있 습 니 다. 접미사 의 관건 은 읽 은 연산 자가 괄호 인 case 입 니 다. 스 택 에 있 는 (
은 연산 자 )
를 만 날 때 까지 보류 합 니 다. 그렇지 않 으 면 스 택 에서 나 오지 않 습 니 다.코드 예제
//int
#include
#include
#define INCREMENT 20
struct Stack_{
int* a;
int capacity;
int size;
int top;
};
int pop_(struct Stack_* stack) {
if(stack->size <= 0 || stack->top < 0)
return NULL;
stack->size--;
return stack->a[stack->top--];
}
void push_(struct Stack_* stack, int c) {
//
if(stack->size <= stack->capacity) {
stack->capacity += INCREMENT;
int* p = (int*)malloc(sizeof(int) * ( stack->capacity));
int i;
int* q;
q = p;
for(i = 0; i < stack->size; i++) {
*(q++) = *(stack->a++);
}
stack->a = p;
}
//
stack->size++;
stack->top++;
stack->a[stack->top] = c;
}
struct Stack_* initStack_(int capacity) {
struct Stack_* stack = (struct Stack_*)malloc(sizeof(struct Stack_));
int* a = (int*)malloc(sizeof(int) * capacity);
stack->size = 0;
stack->top = -1;
stack->a = a;
return stack;
};
// test
int in(char* a, int n, char test) {
int i = 0;
for(i; i < n; i++) {
if(a[i] == test)
return 1;
}
return 0;
}
//
int compare(char a, char b) {
if(a == b)
return 0;
if(a == '+') {
if(b == '*' || b == '(' || b == ')')
return -1;
}
if(a == '*') {
if(b == '+')
return +1;
if(b == '(' || b == ')')
return -1;
}
}
//
char* infix2Suffix(char* infix, int n) {
struct Stack* stack = initStack(n);
char add = '+';
char mult = '*';
char left = '(';
char right = ')';
char op[4] = {'+', '*', '(', ')'};
int i = 0;
char *result = (char*)malloc(sizeof(char) * n);
char top;
int j = 0;
for(i; i < n; i++) {
char c = infix[i];
// ,
//
if(!in(op, 4, c))
result[j++] = c;
else {//
if(stack->size == 0)
push(stack, c);
else {
//
if(c != '(' && c != ')') {
while(1) {
top = pop(stack);
if(top == NULL)
break;
if(top == '(' || compare(c, top) > 0) {
push(stack, top);
break;
} else if (compare(c, top) <= 0)
result[j++] = top;
}
push(stack, c);
}
if(c == '(')
push(stack, c);
if(c == ')') {
while(1) {
top = pop(stack);
if(top != NULL && top != '(')
result[j++] = top;
else
break;
}
}
}
}
}
//
while(1) {
top = pop(stack);
if(top == NULL)
break;
result[j++] = top;
}
result[j++] = '#';
return result;
}
//
int evaluate(char* infix, int n) {
char *suffix = infix2Suffix(infix, n);
struct Stack_* stack = initStack_(n);
char op[4] = {'+', '*', '(', ')'};
int i = 0;
char opnum1, opnum2;
char c;
while((c = suffix[i++]) != '#') {
if(!in(op, 4, c))
push_(stack, (int)c - (int)'0');
else if(in(op, 4, c)){
int opnum1 = pop_(stack);
int opnum2 = pop_(stack);
int tmp;
if(c == '+')
tmp = opnum1 + opnum2;
if(c == '*')
tmp = opnum1 * opnum2;
push_(stack, tmp);
}
}
return pop_(stack);
}
int main() {
char infixExp[13] = {'6', '+', '5', '+', '7',
'*', '8', '*', '(', '1',
'+', '2', ')'};
int result = evaluate(infixExp, 13);
char *suffixExp = infix2Suffix(infixExp, 13);
printf("
");
while(*suffixExp!= '#')
printf("%c", *suffixExp++);
printf("
%d", result);
return;
}
다음으로 전송:https://www.cnblogs.com/Spground/p/8536160.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.