트리 구조에서 연산식을 삽입하는 바법점 알려주세요

nidle의 이미지

제질문에 이렇게 답변을 해주셨습니다
그런데트리구조에 연산식을 삽입해야 하는 부분을 어떻게 해야하는지
잘모르겟어요,, 어떤 알고리즘으로 삽입을해야 되는지.. 책을 아무지찾아봐도
잘 나와있지가 않아서요
아직초보자라서 트리라는 구조도 이번에 알게 되네요
그러니 아직 삽입이나 삭제를 어떻게 해야되는지조차 모르겠어요

수식트리를 만드는 방법은 부모는 연산자 자식은 숫자 이런식으로
만들면 되구요. 숫자는 항상 단말노드가 되겠죠.
그리고 연산자의 우선순위에 따라서 부모 자식 관계가 됩니다.

(a + b) * c
이식을 수식 트리로 만들면?
....*....
.../\....
..+ c...
../\.....
.a b....
이트리를 prefix로 탐색하면서 찍어주면 prefix식 만들어 집니다.
트리 만드는 법은 한번 생각해 보세요

트리구조에 연산식을 삽입해야 하는 부분을 어떻게 해야하는지
잘모르겟어요,,
어떤 알고리즘으로 삽입을해야 되는지.. 책을 아무지찾아봐도
잘 나와있지가 않아서요

slayer의 이미지

infix -> postfix 변환 알고리즘을 응용하면 될 것 같은데요?
다른 거라면 트리의 형태라는 것..
스택에 infix -> postfix 알고리즘대로 연산자를 push, pop 하는 건 같고..
다른 거라면 심볼들을 트리로 만들어서 그 결과를 누적시킨다는게 다르군요..
말이 좀 이상하지만, 조금만 생각해보면 할 수 있습니다..

urmajest의 이미지

operator precedence를 생각해 주어야 하네요

post-fix로 변환해서 넣으면 되겠는데요?

binary tree의 구조는

struct Node {
enum {value, operator} type;
int attribute;
Node* left_child;
Node* right_child;
};

이런식으로 하면 될테구요 type이 operator일때는 operator마다 attribute값을 정해주세요.

(a+b) * c => (post-fix) ab+c*

ab+ -> left-child
c -> right-child
* -> this node

이렇게 할당해 주고

left-child는 reculsive 하게

a -> left-child
b -> right-child
+ -> this node

이렇게 top-down 방식으로 변환해 주는 알고리즘을 사용하면 될 거 같네요

yamong의 이미지

위의 분들이 말씀 하신건 스택을 이용해서 postfix방식으로 접근 하신것 같은데요... 그렇게 해도 됩니다. 그렇게 해도 연산자 우선 순위를 고려해서 계산을 할 수 있습니다. 흠... 그런데 트리구조라면... 아마 이것을 원하고 있는게 아닐까 하네요....
다음은 그냥 생각나는 대로 마치 pseudo code처럼 쓴거라서 컴파일은 안되구요. 그냥 이해해 보세요. 어려운 것은 아닙니다.

식은 다음과 같이 표현됩니다.
<expression> = <term> {(+|-) <term>}
<term> = <factor> {(*|/) <factor>}
<factor> = id | <expression>

즉.
4+5*2+6-5는 위와 같은 알고리즘에 의해서...

expression + + -
term *
factor 4 5 2 6 5
와 같은 구조를 갖게 됩니다.
이때 트리구조를 갖게 되는데.... (사실은 위에 그게 트리구조로 그려야 되는뎅...)
리커시브하게 트리를 생성해 내게됩니다.
main()에서 expression()을 호출 하면 다시 term()을 호출하고 term()은 factor()을 호출하면서 계산이 됩니다.

lexeme[]라는 곳에 식이 들어 있다고 가정하면.... result에 계산값이 나오게 됩니다.

int main()
{
int index = 0;
int result;
Token = lexeme

    ;
    result = expression();
    return 0;
    }

    int expression()
    {
    int operand1, operand2;
    operand1 = term();
    while( lexeme

      == '+' || lexeme
        == '-' )
        {
        if (lexeme[index++] == '+') {
        operand2 = term();
        operand1 += operand2;
        return operand1;
        }
        else if (lexeme[index++] == '-') {
        operand2 = term();
        operand1 -= operand2;
        return operand1;
        }
        }
        }

        int term()
        {
        operand1 = factor();
        while ( lexeme

          == '*' || lexeme
            == '/' )
            {
            if (lexeme[index++] == '*') {
            operand2 = term();
            operand1 *= operand2;
            return operand1;
            }
            else if (lexeme[index++] == '/') {
            operand2 = term();
            operand1 /= operand2;
            return operand1;
            }
            }
            }

            int factor()
            {
            int operand1;
            operand1 = lexeme[index++];
            return operand1;

            }

            대충 알고리즘만 이해하세요. 이대로 코딩 했다가는 오류 투성이일 겁니다.
            좀더 제대로 만드려면 lexical analyzer라는 함수를 만들어야 할 겁니다. 그 함수는 lexeme[]에 있는 값들중 현재 index가 가르키는 값을 찾아서 숫자일때 까지 그 숫자들을 합하고, operator(+,-,*,/)라면 그 이제껏 합친 숫자를 리턴합니다.
            제가 위에 쓴 코드는 그것 말고도 /계산을 할수 없습니다. /을 계산 하려면 분자와 분모값을 가지는 구조체를 정의하고 구조체를 리턴해야 할 겁니다. 마지막에 main()에서 그 구조체의 값을 게산하면 될 것이고.... 또 제가 쓴것은 괄호에 대한 연산도 하지 못합니다. 괄호를 계산하려면 factor()에서 괄호인 경우 다시한번 expression()을 호출해야 합니다.
            그럼...

            urmajest의 이미지

            yylex랑 parser 쓰면 간편하겠네요 ^^

            댓글 달기

            Filtered HTML

            • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
            • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
            • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
            • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

            BBCode

            • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
            • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
            • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
            • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

            Textile

            • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
            • You can use Textile markup to format text.
            • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

            Markdown

            • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
            • Quick Tips:
              • Two or more spaces at a line's end = Line break
              • Double returns = Paragraph
              • *Single asterisks* or _single underscores_ = Emphasis
              • **Double** or __double__ = Strong
              • This is [a link](http://the.link.example.com "The optional title text")
              For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
            • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
            • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

            Plain text

            • HTML 태그를 사용할 수 없습니다.
            • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
            • 줄과 단락은 자동으로 분리됩니다.
            댓글 첨부 파일
            이 댓글에 이미지나 파일을 업로드 합니다.
            파일 크기는 8 MB보다 작아야 합니다.
            허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
            CAPTCHA
            이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.