Browse Source

TP8

master
Geoffrey Frogeye 2 years ago
parent
commit
04bb2bec3a
12 changed files with 313 additions and 0 deletions
  1. 4
    0
      TP8/.gitignore
  2. 27
    0
      TP8/Makefile
  3. 35
    0
      TP8/main.c
  4. 78
    0
      TP8/part2.c
  5. 2
    0
      TP8/samples/.gitignore
  6. 2
    0
      TP8/samples/balanced.txt
  7. 2
    0
      TP8/samples/degenerated.txt
  8. 1
    0
      TP8/samples/empty.txt
  9. 1
    0
      TP8/samples/leaf.txt
  10. 2
    0
      TP8/samples/unspecified.txt
  11. 112
    0
      TP8/trees.c
  12. 47
    0
      TP8/trees.h

+ 4
- 0
TP8/.gitignore View File

@@ -0,0 +1,4 @@
*.a
*.o
main
part2

+ 27
- 0
TP8/Makefile View File

@@ -0,0 +1,27 @@
all: main pdfs dots

main: main.c libtrees.a
gcc $^ -o $@

part2: part2.c libtrees.a
gcc $^ -o $@

%.o: %.c
gcc -c $^ -o $@

lib%.a: %.o
ar rcs $@ $^

pdfs: $(patsubst %.txt,%.pdf,$(shell ls samples/*.txt))
dots: $(patsubst %.txt,%.dot,$(shell ls samples/*.txt))

samples/%.pdf: samples/%.dot
dot -Tpdf $< -o $@

samples/%.dot: samples/%.txt part2
./part2 $<

.PHONY: clean

clean:
rm -r lib*.a *.o samples/*.dot samples/*.pdf

+ 35
- 0
TP8/main.c View File

@@ -0,0 +1,35 @@
/*Source Code From Laure Gonnord*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "trees.h"


int main(){
Tree mt1,mt2,mt3;
mt1 = mkEmptyTree();
mt2 = mkEmptyTree();

if (isEmpty(mt1)) printf("mt1 empty\n");
mt3 = cons(42,mt1,mt2);
print_lvr(mt3);

printf("\n -- \n");
FILE* fp = fopen("samples/balanced.txt","r");
/* FILE* fp = fopen("samples/unspecified.txt","r"); */
/* FILE* fp = fopen("samples/degenerated.txt","r"); */

Tree abr1= mkEmptyTree();

load_tree(fp, &abr1);

//Only values
print_lvr(abr1);
printf("\n -- \n");
//father->son
print_rec_edges(abr1);
printf("\n -- \n");

return 0;
}

+ 78
- 0
TP8/part2.c View File

@@ -0,0 +1,78 @@
/*Source Code From Bernard Carré and Laure Gonnord */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "trees.h"

#define MAX_STRING 255

// Main -- Do not modify !

// iterate the process: load, print (Part 1) and then generate_dot (Part 2) on the n files_names
void handle(int n, char *file_names[]);

// main - usage: main <file_name_1> <file_name_2> <file_name_3>...
int main (int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "usage: main <file_names (.txt files)>\n");
} else {
handle(argc-1, &argv[1]); // handle the files
}
return 0;
}

// utility: build a new file name dest from src whose extension is replaced by the parameter ext
// for example : file.txt -> file.dot
void build_name(char *src, char *dest, char *ext);

// iterate the process: load, print (Part 1) and then generate_dot (Part 2) on the n files_names
void handle(int n, char *file_names[]) {
Tree t;
FILE *fp;
int i;
for (i=0; i<n; i++) {
fp=fopen(file_names[i], "r");
if (fp==NULL) {
fprintf(stderr, "no such file, or unreachable: %s\n", file_names[i]);
} else {
// Part 1
t=NULL;
load_tree(fp, &t);
fclose(fp);
printf("---------------\n%s:\n", file_names[i]);
print_lvr(t); // on std output
printf("\n");
//Part 2
char dot_file_name[MAX_STRING], pdf_file_name[MAX_STRING], command[MAX_STRING];
// new name for he dot file = file_name in which ".txt" is replaced by ".dot"
build_name(file_names[i], dot_file_name, ".dot");
fp=fopen(dot_file_name, "w");
if (fp == NULL) {
fprintf(stderr, "unreachable: %s\n", dot_file_name);
} else {
generate_dot(t,fp); // Call to the printing function
printf("dot file %s has been generated\n",dot_file_name);
fclose(fp);
// new name for the pdf file = file_name in which ".txt" is replaced by ".pdf"
build_name(file_names[i], pdf_file_name, ".pdf");
// transform to .pdf with the dot system command
sprintf(command, "dot -Tpdf %s -o %s", dot_file_name, pdf_file_name);
system(command);
printf("pdf file %s has been generated\n", pdf_file_name);
}
}
}
}

// utility: build a new file name dest from src whose extension is replaced by the parameter ext
// for example : file.txt -> file.dot
void build_name(char *src, char *dest, char *ext) {
strcpy(dest, src);
strcpy(&dest[strlen(src)-4], ext);
}

+ 2
- 0
TP8/samples/.gitignore View File

@@ -0,0 +1,2 @@
*.pdf
*.dot

+ 2
- 0
TP8/samples/balanced.txt View File

@@ -0,0 +1,2 @@
8 4 2 1 3 6 5 7 12 10 9 11 14 13 15


+ 2
- 0
TP8/samples/degenerated.txt View File

@@ -0,0 +1,2 @@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15


+ 1
- 0
TP8/samples/empty.txt View File

@@ -0,0 +1 @@


+ 1
- 0
TP8/samples/leaf.txt View File

@@ -0,0 +1 @@
1

+ 2
- 0
TP8/samples/unspecified.txt View File

@@ -0,0 +1,2 @@
9 4 2 11 3 6 5 15 12 10 8 1 14 13 7


+ 112
- 0
TP8/trees.c View File

@@ -0,0 +1,112 @@
/*Source Code From Laure Gonnord and Bernard Carré*/

#include "trees.h"

// construction of a tree
Tree cons(int val, Tree left, Tree right) {
PtNode new = (PtNode)malloc(sizeof(Node));
new->val=val;
new->left=left;
new->right=right;
return new;
}

// create an empty tree
Tree mkEmptyTree(){
return NULL;
}

// t is empty?
bool isEmpty (Tree t) {
return t==NULL;
}

// t is a leaf?
bool isLeaf (Tree t) {
return (!isEmpty(t) && isEmpty(t->left) && isEmpty(t->right));
}

// add x in a bst wtr its value.
void add(Tree *p_t, int x) {
if (*p_t == NULL) {
*p_t = cons(x, NULL, NULL);
} else if (x <= (*p_t)->val) {
add(&(*p_t)->left, x);
} else {
add(&(*p_t)->right, x);
}
}

// build a tree "add"ing values of the file fp
void load_tree(FILE *fp, Tree *p_t) {
int val;
while (!feof(fp)) {
fscanf(fp, "%d ", &val);
add(p_t, val);
}

}

// print values of t in ascendant order (left-value-right)
void print_lvr (Tree t) {
if (t != NULL) {
print_lvr(t->left);
printf("%d ", t->val);
print_lvr(t->right);
}
}

//Section 1.5
void print_rec_edges(Tree t){
if (t != NULL) {
if (t->left != NULL) {
printf("%d %d\n", t->val, t->left->val);
print_rec_edges(t->left);
}
if (t->right != NULL) {
printf("%d %d\n", t->val, t->right->val);
print_rec_edges(t->right);
}

}
}

//PART II

// pre: !isEmpty(t) & !isLeaf(t)
// recursively prints arcs of the tree <value,left,right> into the file fp:
// "value -> left;" if exist
// "value -> right;" if exist
// to do...
void recursive_dot(Tree t, FILE *fp) {
if (t != NULL) {
if (t->left != NULL) {
fprintf(fp, " %d -> %d;\n", t->val, t->left->val);
recursive_dot(t->left, fp);
}
if (t->right != NULL) {
fprintf(fp, " %d -> %d;\n", t->val, t->right->val);
recursive_dot(t->right, fp);
}

}
}


// generate a .dot file for the tree
// limits (no arcs) :
// isEmpty(t) => "empty" digraph
// isLeaf(t) => only one node
// general case :
// calls recursive_dot which prints arcs
void generate_dot (Tree t, FILE *fp) {
fprintf (fp, "digraph G {\n");
if (!isEmpty(t)) {
if (isLeaf(t)) {
fprintf(fp, "\t%d", t->val);
} else {
recursive_dot(t,fp);
}
}
fprintf (fp, "}\n");
}

+ 47
- 0
TP8/trees.h View File

@@ -0,0 +1,47 @@
/*
* trees.h
*
*
* From a code of Bernard Carre
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


typedef struct node {
int val;
struct node *left;
struct node *right;
}Node, *PtNode, *Tree;


/*Construct a new tree from a value for the root node, a given left tree and a given right tree*/
Tree cons(int , Tree , Tree );

// make an empty tree
Tree mkEmptyTree();

/*Is the given tree empty ?*/
bool isEmpty (Tree);

/*Is the given tree a leaf ?*/
bool isLeaf (Tree);

/*Add a given integer in a binary search tree*/
// do not verify the presence of x.
void add(Tree *, int);

/*Print the values of the tree in ascendant order*/
void print_lvr (Tree);

/* build a tree adding values of the file */
void load_tree(FILE *, Tree *);

void print_rec_edges(Tree t);

/*PART 2*/

void generate_dot (Tree , FILE *);