-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
软件:Course Project 1 (optional) #35
Comments
Option 1 Generic list (115 pts)Knowledge points:
Generic Programming:
A simple example: int max(int a, int b);
double max(double a, double b);
char max(char a, char b); We need three function to achieve our goal, can we use just one? function max(type a, type b) //???? Generic List:For a list in c language, its type is set to be int, double, char or struct. The question is that, can we achieve just one list that can be used for various type in c language? void for various type of dataType void * can point to various data types, this can help us to solve this problem. The function prototype and some data definition is provided for you: Glist.h/*
* list.h
*
* Created on: Oct 22, 2015
* Author: Jiaqi Ye
*/
#ifndef BOOLEAN
#define BOOLEAN
typedef enum {true = 1, false = 0} bool;
#endif
#ifndef LIST_H_
#define LIST_H_
struct node {
void * data;
struct node* next;
};
struct list {
// the head node of the list
struct node * head;
// the data size of each element in the list
int data_size;
// the size of the list
int length;
};
#ifndef NODE_SIZE
#define NODE_SIZE sizeof(struct node)
#endif // NODE_SIZE
#ifndef LIST_SIZE
#define LIST_SIZE sizeof(struct list)
#endif // LIST_SIZE
// Poniter for struct node
typedef struct node* Iterator;
// Pointer for struct list
typedef struct list* List;
/*
InitList
@function: Initialize a list with the given data size
@param: List * list indicates the list pointer's pointer
int datasize indicates the datasize for each element in the list
@return: if the operation is success return true, else retuen false
*/
bool InitList(List *list, int data_size);
/*
Append
@function: set a new node to the end of the list
@param: List * list indicates the list pointer's pointer
void * data indicates the generic data
bool(*assign)(void *, void *) indicates a function pointer to provide assign rule for the data
@return: if the operation is success return true, else retuen false
*/
bool Append(List list, void * data, bool(*assign)(void *, void *));
/*
Append
@function: set a new node after the index of the list
@param: List * list indicates the list pointer's pointer
int index indicates the index to be inserted data
void * data indicates the generic data
bool(*assign)(void *, void *) indicates a function pointer to provide assign rule for the data
@return: if the operation is success return true, else retuen false
*/
bool AppendAt(List list, int index, void * data, bool(*assign)(void *, void *));
/*
Remove
@function: remove a node of the list
@param: List * list indicates the list pointer's pointer
void * data indicates the generic data to be deleted
bool(*equal)(const void*, const void *) is a function poniter indicates the rule of "equal"
@return: if the operation is success return true, else retuen false
*/
bool Remove(List list, void *data, bool(*equal)(const void*, const void *));
/*
RemoveAt
@function: remove a node of the list using index
@param: List * list indicates the list pointer's pointer
int index indicates the index of element to be deleted
@return: if the operation is success return true, else retuen false
*/
bool RemoveAt(List list, int index);
/*
RemoveAt
@function: update nodes of the list
@param: List * list indicates the list pointer's pointer
void * newData indicates the new data for the list
filter is a function indicates the rule for which elements should be updated
assign is a function indicates the rule to assign
@return: if the operation is success return true, else retuen false
*/
bool Update(List list, void *newData, bool(*filter)(const void*, const void *), bool(*assign)(void *, void *));
/*
Query
@function: query some elements that fit a condition
@param: List * list indicates the list pointer's pointer
filter is a function indicates the rule for which elements should be updated
assign is a function indicates the rule to assign
@return: A list with result
*/
List Query(List list, bool(*filter)(const void *), bool(*assign)(void *, void *));
/*
traversal
@function: traversal with an operation rule
@param: List * list indicates the list pointer's pointer
filter is a function indicates the rule for which elements should be updated
operation is a function to apply actions on the elements
@return: A list with result
*/
bool traversal(const List list, bool(*filter)(const void *), bool(*operation)(const void *));
/*
DeleteList
@function: deconstuct the list deleting all the elements
@param: a list
*/
bool DeleteList(List *list);
#endif /* LIST_H_ */ When you are doing the project, you probably use the following function: static bool newNode(Iterator * it, int data_size, void * data, bool(*assign)(void *, void *)) {
(*it) = (Iterator)malloc(sizeof(NODE_SIZE));
if((*it) == NULL) {
return false;
}
(*it)->data = NULL;
(*it)->next = NULL;
(*it)->data = malloc(data_size);
if((*it)->data == NULL) {
return false;
}
assign((*it)->data, data);
return true;
} And here is a script for you to test your logic: #include <stdio.h>
#include <stdlib.h>
#include "list.h"
static bool asign(void * a, void * b) {
int * tempa = (int *)a;
int * tempb = (int *)b;
*tempa = *tempb;
return true;
}
static bool filter(const void * a) {
if(a != NULL) {
return true;
}
return false;
}
static bool filter_1(const void * a, const void * b) {
if(a != NULL) {
if (*((int *)a) >= 4) {
return true;
}
}
return false;
}
static bool filter_odd(const void * a) {
if(a != NULL) {
if ((*((int *)a) & 1) != 0) {
return true;
}
}
return false;
}
static bool operation(const void * a) {
if(a != NULL) {
printf("%d->", *((int *)a));
return true;
}
return false;
}
static bool equal(const void * a, const void * b) {
if(a == NULL || b == NULL) {
return false;
}
return *((int*)a) == *((int*)b);
}
int main() {
printf("Hello world!\n");
List li = NULL;
int a;
InitList(&li, sizeof(int));
for(a = 1; a < 10; a++)
Append(li, (void *)&a, asign);
for(a = 9; a >= 1; a--)
Remove(li, &a, equal);
for(a = 1; a < 10; a++)
Append(li, (void *)&a, asign);
traversal(li, filter, operation);
printf("NULL\n");
traversal(li, filter_odd, operation);
printf("NULL\n");
List li2 = NULL;
li2 = Query(li, filter_odd, asign);
a = 0;
Update(li, (void *)&a, filter_1, asign);
traversal(li, filter, operation);
printf("NULL\n");
traversal(li2, filter, operation);
printf("NULL\n");
DeleteList(&li2);
DeleteList(&li);
return 0;
}
|
Option 2 Json Parser (105 pts)Knowledge points:
Json
From wikipedia The test in SOJ and YOJ are in json format, here is an example: {
"input": "yi qian liu bai er shi wu wan ling liu shi si\n",
"output": "sixteen million two hundred and fifty thousand sixty-four\n",
"score": 40
} Assume that we have 4 types of the data, int32, bool(true or false), array, object(nested json), we can have a compelete example: {
"nested_obj": {"num": 50097, "str": "GBRDCMJQGAYDAMJRGEYDCMJQGAYDC==="},
"sparse_978": "GBRDCMBQGA======",
"dyn2": 100097,
"dyn1": 100097,
"nested_arr": ["many"],
"str2": "GBRDCMJQGAYDAMJRGEYDCMJQGAYDC===",
"str1": "GBRDCMJQGAYDAMJRGEYDAMBQGAYDAMI=",
"thousandth": 97,
"sparse_979": "GBRDCMBQGA======",
"num": 100097,
"bool": true,
"sparse_973": "GBRDCMBQGA======",
"sparse_972": "GBRDCMBQGA======",
"sparse_971": "GBRDCMBQGA======",
"sparse_970": "GBRDCMBQGA======",
"sparse_977": "GBRDCMBQGA======",
"sparse_976": "GBRDCMBQGA======",
"sparse_975": "GBRDCMBQGA======",
"sparse_974": "GBRDCMBQGA======"
} Now our job is to parse the object above into "keys" and "values", exclude the nested objects'. Why Parse JsonBecause Json is string and we need to know what it's exactly expressing unless we parse it in to pair (key, value). For example for a string: { "input": "yi qian liu bai er shi wu wan ling liu shi si\n","output": "sixteen million two hundred and fifty thousand sixty-four\n","score": 40} We do not know that what's the input or output or score in the string unless we parse it. Limits:
Design Logic:Json stores data format as a string array. We define the structure, including the start pointer, end pointer, JSON data type (used to determine the read of the string as the key or value) and data type (used to judge the value of the type, including: int, bool, string, array, nested and other types). Using pointers to read JSON key or value, start pointer and the end pointer representing its starting position in the string array and end position, first read for the key and the second read the value, and so on (as shown in the figure). Judgment value of the first character in a text string, if the character is digital, the value of data type is int; if the character "t" or "F", the string bool type; if the quotation marks "," ", the string is the string; if the symbol" [", the string is an array type; if the symbol" {", the string as the nested; otherwise for unknown type. We have the following function prototype: #ifndef JSONPARSER
#define JSONPARSER
#ifndef BOOLEAN
#define BOOLEAN
typedef enum {true = 1, false = 0} bool;
#endif
// 0 for json attributes(keys) and 1 for value
typedef enum {atr = 0, value = 1} json_type;
// 5 data type
typedef enum {int32 = 0, bool8 = 1, stringn = 2, array1 = 3, object1 = 4, unknown = 5} data_type;
// list define
typedef struct json_parser {
// Json element start position
unsigned int start;
// Json element end position
unsigned int end;
// key or value
json_type type;
// data type
data_type dtype;
// next parser element
struct json_parser * next;
} json_parser;
/*
ParseJson
@function: parse a Json string into parser elements
@param: char * JsonStr indicates the Json string
@return: A list of json parser elements and the length of the list
*/
extern json_parser * ParseJson(char * JsonStr, int * len);
/*
DeleteJson
@function: delete the list of json parser elements
@param: a list of json parser elements
*/
extern void DeleteJson(json_parser * head);
#endif Simple test #include <stdio.h>
#include "Json.h"
static void print(unsigned int start, unsigned int end, char * s) {
int i;
for(i = start; i <= end; i++) {
printf("%c", s[i]);
}
}
int main() {
char Json[10000];
fgets(Json, 10000, stdin);
int len;
//puts(Json);
json_parser * Parser;
Parser = ParseJson(Json, &len);
json_parser * positioner = Parser;
while(positioner!=NULL) {
print(positioner->start,positioner->end, Json);
printf(" %d", positioner->dtype);
positioner = positioner->next;
printf("\n");
}
return 0;
} Requirement: |
nice |
Project1:
For a deep understand for c pointers and functions, we will take a project.
An introduction to List
From wikipedia
Our course project is about List.
List is a data type that defined by programmers or the language. The best advantage of the list(linear list) is that it can store variable length of data. Usually, we use struct in c language with a member variable as a 'next' pointer points to the next element of the list. And we will have some functions for the list operations. These operations is the core of C programming language including the usage of pointers, various data types and also some basic knowledge of a computer.
Detail Introduction: link
Try your best to finish the hardest project.
Basic Knowledge(15 pts)
answer the questions in deep thinking part in your report
1. Memory distribution map for a runtime program (very important for your 4-year study)
From Professor Wan Hai's courseWare
This is an overview for a program when it's loaded into the memory of the computer. There are totally 4 area for it, Code area, Static area, Heap and stack.
Code area: This area is used to store program codes(instructions for cpu to execute)
Static area: This area is for the ralatively ‘static’ variables. Global variables, static local variables, static global variables are allocated in the static storage area.
Heap: This area is management by the operating system and it's shared by other programs. You can get dynamic memory allocations in this area. This is the area we need to use in list
Stack: The stack is a area of memory that allocated by the compile. All variables declared in stack.
Notice that stack and heap in operating system are totally different in data structure
For example:
Notice that we have a operation before the program end.
free(b)
. Because we use the memory in the heap which means that these memory should be managed by the programmer. Even though the memory will be free by a mordern operating system, we should prevent memory lost (memory leak).For example:
The example above cause a memory leak problem because pointer point to another memory area and the previous memory area1 is lost.
2. Malloc() to get memory from heap
The two examples above show how to get memory in heap. In fact, we it's a serial of functions.
C language with the memory of the functions are mainly calloc, alloca, malloc, free, realloc and so on.
<1> alloca is the application of the stack to the memory, so there is no need to release.
<2> malloc allocates memory is located in the heap, and there is no memory of the contents of the initial memory, so after the basic malloc, call the function memset to initialize this part of the memory space.
<3> calloc will initialize this part of the memory, set to 0
<4> realloc is the size of the memory of the malloc application.
<5> The heap needs to be released by the function free.
Notice that everytime you apply memory from heap, you should remember it and delete it(free) when your use of it is end.
3. List operations
The operations about list are appending, deleting, modifying, querying.
we use this simple list again:
2.If append a node at the end of the list
node * temp = head;
while(temp != NULL) {
Traversal(temp);
temp = temp->next;
}
Deep Thinking
1. Why use a list instead of an array? What's the advantages of them and disadvantages for them respectively?
2.See the following function:
(1) Which area in memory does the function store? And which dose the variable
int a
?(2) What's the advantages of using static functions?
3. See the following program which is attempt to allocate a dynamic array.
Can we create an 2D array in the heap using this way? Give your explanations and give another way that can allocated a dynamic 2D array
4.
(1)See the following program.
Why it's a wrong operation for deleting a element in the list?
(2)Write a simple pseudo code program to insert '88' before the last element and then insert '76' before the head. Notice that what you know is the head element address of the list. Think about the difference between instering at the head and not at the head.
5. How to use an array to create a list know as a static list in logic?
For example:
6. (optional) Think about that can we use an int_64 (long long) to create a list using the high 32 bits to store an int data and use the low 32 bits to store the next address pointer? If so, write a program to test. If not, wirte a program to explain your reasons.
Grading List
Deep thinking for part 1 (15pts)
Option 1 Generic list (115 pts)
Option 2 Json Parser (105 pts)
The text was updated successfully, but these errors were encountered: