Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
531d1f9
Writing functions for building a tree, counting expressions, and writ…
MinyazevR Nov 12, 2021
ee27bff
Solving the problem
MinyazevR Nov 12, 2021
0d36fbd
Changing the function for tree output
MinyazevR Nov 12, 2021
378356e
Merge pull request #40 from MinyazevR/ParsingTree
MinyazevR Nov 12, 2021
918278c
a flaw has been changed (0 is a valid number)
MinyazevR Nov 13, 2021
66ff87e
Merge pull request #42 from MinyazevR/ParsingTree
MinyazevR Nov 13, 2021
8780d7e
changed the function for adding a node
MinyazevR Nov 19, 2021
e1c6faa
changing functions to add an element, changing tests
MinyazevR Nov 19, 2021
41a7a49
Merge pull request #53 from MinyazevR/ParsingTree
MinyazevR Nov 19, 2021
2986452
changing bugs in the function that reads a string from a file
MinyazevR Nov 19, 2021
42479cd
changing the function to read a line from a file
MinyazevR Nov 19, 2021
761ccf5
changing the file location
MinyazevR Nov 19, 2021
0215130
nodeVisited
MinyazevR Nov 19, 2021
9e88d89
fixed a bug with a one-character expression
MinyazevR Nov 19, 2021
014c909
the necessary files have been restored
MinyazevR Nov 26, 2021
1b46e0f
the necessary files have been restored
MinyazevR Nov 26, 2021
fe132ff
the necessary files have been restored
MinyazevR Nov 26, 2021
51a7b22
changing the function to traverse the tree and changed the format of …
MinyazevR Dec 3, 2021
d1eb0d2
changing functions to work with a tree
MinyazevR Dec 3, 2021
30f11f0
fixing memory leaks
MinyazevR Dec 3, 2021
48984d1
removed the extra code
MinyazevR Dec 3, 2021
2216d55
more const
MinyazevR Dec 3, 2021
4c9585b
changing the format of an expression in a file
MinyazevR Dec 3, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions ParsingTree/ParsingTree.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31410.357
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ParsingTree", "ParsingTree\ParsingTree.vcxproj", "{AEA90FA6-F26C-4B74-9508-AD999204C4FA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x64.ActiveCfg = Debug|x64
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x64.Build.0 = Debug|x64
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x86.ActiveCfg = Debug|Win32
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x86.Build.0 = Debug|Win32
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x64.ActiveCfg = Release|x64
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x64.Build.0 = Release|x64
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x86.ActiveCfg = Release|Win32
{AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {65329AED-E765-4723-93C5-B2671094F619}
EndGlobalSection
EndGlobal
9 changes: 9 additions & 0 deletions ParsingTree/ParsingTree/Main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "TestParsingTree.h"

int main()
{
if (!testFindAnswer() || !testBuildTree())
{
return -1;
}
}
282 changes: 282 additions & 0 deletions ParsingTree/ParsingTree/ParsingTree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
#include "ParsingTree.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

typedef struct Node
{
struct Node* leftSon;
struct Node* rightSon;
struct Node* parent;
char value;
int number;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну тоже переменные названы замечательно, непонятно, кто из них кто.

char help;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Не называйте переменные "help", это мило, но не мнемонично.

} Node;

Node* createTree()
{
return NULL;
}

void deleteTreeRecursive(Node* root)
{
if (root == NULL)
{
return;
}
deleteTreeRecursive(root->leftSon);
deleteTreeRecursive(root->rightSon);
free(root);
}

void deleteTree(Node** root)
{
deleteTreeRecursive(*root);
*root = NULL;
}

Node* returnHead(Node* root)
{
if (root == NULL)
{
return root;
}
while (root->parent != NULL)
{
root = root->parent;
}
return root;
}

int returnAnswer(Node* root)
{
return root->number;
}

bool compare(char symbol)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тоже название не очень. compare чего с чем? Тем более тут проверяется, является ли символ оператором, так что я бы isOperator это назвал

{
return symbol == '+' || symbol == '-'
|| symbol == '*' || symbol == '/';
}

Node* buildTree(char* array)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char* array
Чтобы явно сказать всем, что мы не собираемся менять элементы массива, и разрешить, в частности, принимать строковые литералы сюда, что сделает работу с этой функцией в сотню раз более удобной

{
int counter = 0;
Node* tree = createTree();
while (array[counter] != '\0')
{
if (array[counter] == '(' || array[counter] == ')' || array[counter] == ' ')
{
counter++;
continue;
}
Node* newRoot = (Node*)calloc(1, sizeof(Node));
if (newRoot == NULL)
{
return NULL;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так всё построенное до этого дерево потеряется

}
if (tree == NULL)
{
newRoot->value = array[counter];
tree = newRoot;
newRoot->help = '!';
newRoot->number = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Будет ли это хорошо работать на строках вида "1"? В принципе, несложно сделать так, чтобы и строки, содержащие только один операнд, поддерживались

counter++;
continue;
}
if (compare(array[counter]))
{
if (tree->leftSon == NULL && compare(tree->value))
{
tree->leftSon = newRoot;
newRoot->parent = tree;
newRoot->help = '!';
newRoot->value = array[counter];
newRoot->number = 0;
tree = newRoot;
counter++;
continue;
}
else if (tree->rightSon == NULL && compare(tree->value))
{
tree->rightSon = newRoot;
newRoot->parent = tree;
newRoot->help = '!';
newRoot->value = array[counter];
newRoot->number = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что-то копипаст. Можно инициализацию узла вынести в отдельную функцию

tree = newRoot;
counter++;
continue;
}
while (tree->parent != NULL)
{
tree = tree->parent;
if (tree->leftSon == NULL && compare(tree->value))
{
tree->leftSon = newRoot;
newRoot->parent = tree;
newRoot->help = '!';
newRoot->value = array[counter];
newRoot->number = 0;
counter++;
tree = newRoot;
break;
}
else if (tree->rightSon == NULL && compare(tree->value))
{
tree->rightSon = newRoot;
newRoot->parent = tree;
newRoot->help = '!';
newRoot->value = array[counter];
newRoot->number = 0;
counter++;
tree = newRoot;
break;
}
}
continue;
}
if (array[counter] <= '9' && array[counter] >= '0')
{
if (compare(tree->value) && tree->leftSon == NULL)
{
tree->leftSon = newRoot;
newRoot->parent = tree;
newRoot->value = array[counter];
newRoot->help = '$';
newRoot->number = array[counter] - '0';
counter++;
continue;
}
else if (tree->rightSon == NULL && compare(tree->value))
{
tree->rightSon = newRoot;
newRoot->parent = tree;
newRoot->value = array[counter];
newRoot->help = '$';
newRoot->number = array[counter] - '0';
counter++;
continue;
}
while (tree->parent != NULL)
{
tree = tree->parent;
if (tree->leftSon == NULL && compare(tree->value))
{
tree->leftSon = newRoot;
newRoot->parent = tree;
newRoot->value = array[counter];
newRoot->help = '$';
newRoot->number = array[counter] - '0';
counter++;
break;
}
else if (tree->rightSon == NULL && compare(tree->value))
{
tree->rightSon = newRoot;
newRoot->parent = tree;
newRoot->value = array[counter];
newRoot->help = '$';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это какой-то тайный шифр?

newRoot->number = array[counter] - '0';
counter++;
break;
}
}
}
}
return tree;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Капец как сложно. Это рекурсивно в 20 строк пишется:

if (isOperator(array[*i])
{
    Node *operator = createOperator(array[*i]);
    ++*i;
    operator->left = buildTree(array, i);
    operator->right = buildTree(array, i);
    return operator;
}
else 
{
    Node *operand = createOperand(array[*i])
   ++*i;
    return operand;
}


void restoreField(Node* root)
{
if (root == NULL)
{
return;
}
restoreField(root->leftSon);
restoreField(root->rightSon);
if (compare(root->value))
{
root->help = '!';
}
else
{
root->help = '$';
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тернарным оператором было бы короче

}

void findAnswer(Node* root)
{
if (root == NULL)
{
return;
}
if (root->leftSon != NULL && root->rightSon != NULL && root->rightSon->help == '$' && root->leftSon->help == '$' && root->help != '$')
{
root->help = '$';
if (root->value == '+')
{
root->number = root->leftSon->number + root->rightSon->number;
}
if (root->value == '-')
{
root->number = root->leftSon->number - root->rightSon->number;
}
if (root->value == '*')
{
root->number = root->leftSon->number * root->rightSon->number;
}
if (root->value == '/')
{
root->number = root->leftSon->number / root->rightSon->number;
}
if (root->parent != NULL)
{
findAnswer(root->parent);
}
else
{
restoreField(root);
return;
}
}
else if (root->leftSon != NULL && compare(root->leftSon->value) && root->leftSon->help != '$')
{
findAnswer(root->leftSon);
}
else if (root->rightSon != NULL && compare(root->rightSon->value) && root->rightSon->help != '$')
{
findAnswer(root->rightSon);
}
}

void printTree(Node* root)
{
if (root == NULL)
{
return;
}
printTree(root->leftSon);
printTree(root->rightSon);
printf("%c ", (root->value));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
printf("%c ", (root->value));
printf("%c ", root->value);

}

Node* rightSon(Node* root)
{
return root->rightSon;
}

Node* leftSon(Node* root)
{
return root->leftSon;
}

Node* parent(Node* root)
{
return root->parent;
}

char getValue(Node* root)
{
return root->value;
}
37 changes: 37 additions & 0 deletions ParsingTree/ParsingTree/ParsingTree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

// Structure representing a tree
typedef struct Node Node;

// Function for creating a tree
Node* createTree();

// Function for deleting a tree
void deleteTree(Node** root);

// Function that returns the root of the tree
Node* returnHead(Node* root);

// Function for building a tree
Node* buildTree(char* array);

// Function for calculating the value of an expression
void findAnswer(Node* root);

// Function for tree output
void printTree(Node* root);

// Function for returning the result of counting
int returnAnswer(Node* root);

// Function for accessing the right son of the current root
Node* rightSon(Node* root);

// Function for accessing the left son of the current root
Node* leftSon(Node* root);

// Function for accessing the parent of the current root
Node* parent(Node* root);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не слишком ли много дерево раскрывает о себе? Сокрытие деталей реализации тут не очень, и принцип минимальности интерфейса абстракции тоже страдает


// Function to get the value
char getValue(Node* root);
Loading