100% Tested with Dartmouth x IMT Online Judge/Task Grader

何強豪の C code log and learning journey

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


Unit 5.1 Structures

Define and Use Structures

Basic Syntax

#include <stdio.h> struct student{ char firstName[30]; char lastName[30]; int birthYear; double aveGrade; }; int main(void) { struct student me = {"Petra", "Bonfert-Taylor", 1989, 3.5}; struct student you = {"Remi", "Sharrock", 2005, 3.5}; printf("Names: %s %s, %s %s\n", me.firstName, me.lastName, you.firstName, you.lastName); printf("Year of birth: %d\n", me.birthYear); printf("Average grade: %.2lf\n", me.aveGrade); return 0; }

Dot Operator

#include <stdio.h> struct student{ char firstName[30]; char lastName[30]; int birthYear; double aveGrade; }; int main(void) { //! showMemory(start=65520) struct student learner; printf("First name: "); scanf("%s", learner.firstName); printf("Last name: "); scanf("%s", learner.lastName); printf("Year of birth:"); scanf("%d", &learner.birthYear); printf("Average grade: "); scanf("%lf", &learner.aveGrade); printf("Name: %s %s\n", learner.firstName, learner.lastName); printf("Year of birth: %d\n",learner.birthYear); printf("Average grade: %.2lf\n",learner.aveGrade); return 0; }

Pass Struct to Function

With Pointers

#include <stdio.h> struct student{ char firstName[30]; char lastName[30]; int birthYear; double aveGrade; }; void printStudent(struct student); void readStudent(struct student *studptr); int main(void) { //! showMemory(start=65520) struct student me; readStudent(&me); printStudent(me); return 0; } void readStudent(struct student *studptr) { printf("\nEnter a new student record: \n"); printf("First name: "); scanf("%s", (*studptr).firstName); printf("Last name: "); scanf("%s", (*studptr).lastName); printf("Birth year: "); scanf("%d", &(*studptr).birthYear); printf("Average grade: "); scanf("%lf", &(*studptr).aveGrade); } void printStudent(struct student stud) { printf("Name: %s %s\n", stud.firstName, stud.lastName); printf("Year of birth: %d\n",stud.birthYear); printf("Average grade: %.2lf\n",stud.aveGrade); }

Practice
You'd like to implement a date feature in the C programming language. To this end you are provided with a structure definition, a main function, and two function prototypes: "readDate()" and "printDate()". All that is left for you to do is to write these two functions.

Here are the exact specifications:

The function readDate() should read 3 integers from the user input. The first integer is the year (a 4-digit number), the second integer is the month, and the third integer is the day of the date being read. The function should store these three numbers in the appropriate parts of the structure being passed into it.

The function printDate() should print the date stored in the variable passed into it in the following format: mm/dd/yyyy with a new line afterwards. So the month should be printed with two digits (01, 02, 03, , 11, 12), the day should be printed as two digits (01, 02, 03, , 30, 31), and the year should be printed as a 4-digit number.

Input:
2018 10 2
Output:
10/02/2018
Solution

#include <stdio.h> struct date { int year; int month; int day; }; void readDate(struct date *); void printDate(struct date); int main(void) { struct date today; readDate(&today); printDate(today); return 0; } void readDate(struct date *inptr){ scanf("%d %d %d", &(*inptr).year, &(*inptr).month, &(*inptr).day); } void printDate(struct date in){ printf("%d/%02d/%d\n", in.month, in.day, in.year); }

Work with struct (Arrow)

-> Used for manipulation with pointer
Example:

struct Person { char name[50]; int age; }; int main() { struct Person person1; struct Person *ptrPerson = &person1; // Using the dot operator to access members person1.age = 25; // Using the arrow operator to access members through a pointer ptrPerson->age = 30; return 0; }

Accepting user input:

void readStudent(struct student *studptr) { printf("\nEnter a new student record: \n"); printf("First name: "); scanf("%s", studptr->firstName); printf("Last name: "); scanf("%s", studptr->lastName); printf("Birth year: "); scanf("%d", &studptr->birthYear); printf("Average grade: "); scanf("%lf", &studptr->aveGrade); }

Structure Space/Memory
Min = sum of all component; sum compiler implement memory alignment

Manipulate Struct with Function
In this problem you will continue developing the data feature which you started implementing in the previous problem. You will implement a "tomorrow" feature in the C programming language via a function called "advanceDay()". The function advanceDay() should take as input a date (stored in a struct date) and return the date of the following day. You do not have to take into account leap years (although you may if you wish to). That is, it is okay for your function to always return March 1 as the day following February 28, no matter the year.

You are provided with a familiar date structure definition, a main function as well as the function prototypes for the readDate(), printDate(), and advanceDay() functions. Do not modify any of the given code. Simply add your function definitions underneath the main() function. For the readDate() and printDate() functions you may simply copy and paste the code you developed in the previous task.

​​​​Input:
​​​​2018 10 2
​​​​Output:
​​​​10/02/2018

​​​​10/03/2018
​
​​​​Input:
​​​​2018 10 31
​​​​Output:
​​​​10/31/2018
​​​​
​​​​11/01/2018

Solution:

#include <stdio.h> struct date { int year; int month; int day; }; /* function prototypes */ void printDate(struct date); void readDate(struct date *); struct date advanceDay(struct date); int main(void) { struct date today, tomorrow; readDate(&today); printDate(today); tomorrow = advanceDay(today); printDate(tomorrow); return 0; } /* add your function definitions here */ void printDate(struct date in){ printf("%02d/%02d/%4d\n\n", in.month, in.day, in.year); } void readDate(struct date *inptr){ scanf("%d %d %d", &inptr->year, &inptr->month, &inptr->day); } struct date advanceDay(struct date today){ int newDate = today.day + 1; int newMonth = today.month; int newYear = today.year; int numDays[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if((today.year % 4 == 0 && today.year % 100 != 0) || (today.year % 400 == 0)) numDays[2] = 29; if(newDate > numDays[newMonth]){ newDate = newDate - numDays[newMonth]; newMonth++; } if(newMonth > 12){ newYear++; newMonth -= 12; } struct date nextDay; nextDay.year = newYear; nextDay.month = newMonth; nextDay.day = newDate; return nextDay; }

Unit 5.2 Structures and Pointers

Array of Structures

Triangle

#include <stdio.h> struct point{ int x; int y; }; void printPoint(struct point pt); void readPoint(struct point * ptr); void printTriangle(struct point *ptr); int main(void) { //! showMemory(start=65520) struct point triangle[3]; int i; for (i=0; i<3; i++){ readPoint(&triangle[i]); } printTriangle(triangle); return 0; } void readPoint(struct point * ptr) { printf("\nEnter a new point: \n"); printf("x-coordinate: "); scanf("%d", &ptr->x); printf("y-coordinate: "); scanf("%d", &ptr->y); } void printTriangle(struct point *ptr) { int i; for (i=0; i<3; i++) { printPoint(ptr[i]); } } void printPoint(struct point pt){ printf("(%d, %d)\n", pt.x, pt.y); }

Pointers

image

Allocate Memorty for Structures

Polygon

#include <stdio.h> #include <stdlib.h> struct point{ int x; int y; }; void printPoint(struct point pt); void readPoint(struct point * ptr); void printPoly(struct point *ptr, int vertices); int main(void) { //! showMemory(start=65520) struct point * polygon; int i, num; printf("How many vertices does your polygon have? "); scanf("%d", &num); polygon = (struct point *) malloc(num * sizeof(struct point)); for (i=0; i<num; i++){ readPoint(&polygon[i]); } printPoly(polygon, num); free(polygon); return 0; } void readPoint(struct point * ptr) { printf("\nEnter a new point: \n"); printf("x-coordinate: "); scanf("%d", &ptr->x); printf("y-coordinate: "); scanf("%d", &ptr->y); } void printPoly(struct point *ptr, int vertices) { int i; for (i=0; i<vertices; i++) { printPoint(ptr[i]); } } void printPoint(struct point pt){ printf("(%d, %d)\n", pt.x, pt.y); }

Practice:
In this task, we will continue to work with polygons. You are provided with the following:

  • A familiar structure definition for a 2-dimensional point.
  • Two familiar functions and their prototypes, "printPoint()" and "printPoly()".
  • A prototype for "initializePoly()", a function that you must write.
  • An empty main function which you must complete.

Please do not alter the provided code (except to fill in the main function and add your initializePoly() function).

initializePoly() should receive as input a pointer to the first structure in an array of structures as well as an integer, indicating how many points can be stored in the array. Your job is to initialize these points in the following way:

Using a for loop with i starting at 0, initialize the x-coordinate of the point at index i as -i, and the y-coordinate as i*i.

Your main function should read the number of vertices to store in the array of points from the user, then allocate the appropriate amount of memory, initialize the array with the function initializePoly, and finally print the vertices of the polygon using the function printPoly().

​​​​Input:
​​​​4
​​​​Output:
​​​​(0, 0)
​​​​(-1, 1)
​​​​(-2, 4)
​​​​(-3, 9)

Solution

#include <stdio.h> #include <stdlib.h> struct point{ int x; int y; }; void printPoint(struct point); void printPoly(struct point *, int); void initializePoly(struct point *, int); int main(void) { struct point * polygon; int num = 0; scanf("%d", &num); polygon = (struct point *) malloc(num * sizeof(struct point)); initializePoly(polygon, num); printPoly(polygon, num); free(polygon); } void printPoint(struct point pt) { printf("(%d, %d)\n", pt.x, pt.y); } void printPoly(struct point *ptr, int N) { int i; for (i=0; i<N; i++) { printPoint(ptr[i]); } } void initializePoly(struct point *ptr, int N) { for(int i = 0; i < N; i++){ ptr[i].x = -i; ptr[i].y = i*i; } }

Introduction to Linked List

Basic Mechanic

  • Each struct contain the next struct pointer
  • To call just deref using arrow operator,
  • To update just call the current struct next address
#include <stdio.h> struct point{ int x; int y; struct point * next; }; int main(void) { //! showMemory(start=65520) struct point pt1 = {1, 2, NULL}; struct point pt2 = {-2, 3, NULL}; struct point pt3 = {5, -4, NULL}; struct point * start, * ptr; start = &pt1; pt1.next = &pt2; pt2.next = &pt3; ptr = start; while (ptr!=NULL) { printf("(%d, %d)\n", ptr->x, ptr->y); ptr = ptr->next; } return 0; }

Append New Nodes Mechanism

#include <stdio.h> struct point{ int x; int y; struct point * next; }; void printPoints(struct point *start); struct point * append (struct point * end, struct point * newpt); int main(void) { //! showMemory(start=65520) struct point pt1 = {1, 2, NULL}; struct point pt2 = {-2, 3, NULL}; struct point pt3 = {5, -4, NULL}; struct point * start, * end; start = end = &pt1; end = append(end, &pt2); end = append(end, &pt3); printPoints(start); return 0; } void printPoints(struct point *start) { //! showMemory(start = 65520, cursors=[ptr]) struct point * ptr; ptr = start; while (ptr!=NULL) { printf("(%d, %d)\n", ptr->x, ptr->y); ptr = ptr->next; } } struct point * append (struct point * end, struct point * newpt) { end->next = newpt; return(end->next); }

Dynamic Linked List

  • Free the head first, create temp to save the next address
  • Malloc every creation, return the pointer
#include <stdio.h> #include <stdlib.h> struct point{ int x; int y; struct point * next; }; void printPoints(struct point *start); struct point * createPoint(int x, int y) ; struct point * append (struct point * end, struct point * newpt); void freePoints(struct point * start); int main(void) { //! showMemory(start=65520) struct point * start, * end, * newpt; int num, i; int x, y; printf("How many points? "); scanf("%d", &num); for (i=0; i<num; i++) { printf("x = "); scanf("%d", &x); printf("y = "); scanf("%d", &y); newpt = createPoint(x,y); if (i==0) { start = end = newpt; } else { end = append(end,newpt); } } printf("You entered: "); printPoints(start); freePoints(start); return 0; } void printPoints(struct point *start) { //! showMemory(start = 65520, cursors=[ptr]) struct point * ptr; ptr = start; while (ptr!=NULL) { printf("(%d, %d)\n", ptr->x, ptr->y); ptr = ptr->next; } } struct point * append (struct point * end, struct point * newpt) { end->next = newpt; return(end->next); } struct point * createPoint(int x, int y) { struct point *ptr; ptr = (struct point *)malloc(sizeof(struct point)); ptr->x = x; ptr->y = y; ptr->next = NULL; return(ptr); } void freePoints(struct point * start) { struct point * ptr = start; while (ptr!=NULL) { start = ptr; ptr = ptr->next; free(start); } }

Unit 5.3: Linked List

Single Node

Struct Malloc

Problem:
You would like to store student data (for each student, their name and age) in a linked list of students. You are given the following structure to store each student's information. Please do not modify this structure:

struct student { char name[50]; int age; struct student *next; };

Your first task is to write a function createStudent() that takes as inputs a string (namely a student's name) and an integer (their age) and that returns a pointer to a struct student which stores this information. Your function should dynamically allocate the memory required for this struct student and then write the student's name and age into this newly allocated memory.

You are given the createStudent() function prototype and a main() function to test your code, please do not modify these:

Provided Code
struct student *createStudent(char studentName[], int studentAge); int main(void) { struct student *studptr; int myAge; char myName[50]; scanf("%s %d", myName, &myAge); studptr = createStudent(myName, myAge); printf("New student created: %s is %d years old.\n", studptr->name, studptr->age); free(studptr); return 0; }
​​​​Input:
​​​​    Petra 25
​​​​Output:
​​​​    New student created: Petra is 25 years old. 
​​​​    
​​​​Input:
​​​​    Remi 18
​​​​Output:
​​​​    New student created: Remi is 18 years old.  

Solution:

#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; struct student *createStudent(char studentName[], int studentAge); int main(void) { struct student *studptr; int myAge; char myName[50]; scanf("%s %d", myName, &myAge); studptr = createStudent(myName, myAge); printf("New student created: %s is %d years old.\n", studptr->name, studptr->age); free(studptr); return 0; } struct student *createStudent(char studentName[], int studentAge){ struct student * newStudent; newStudent = (struct student *) malloc(sizeof(struct student)); int i = 0; while(studentName[i] != '\0'){ newStudent->name[i] = studentName[i]; i++; } newStudent->name[i] = '\0'; newStudent->age = studentAge; newStudent->next = NULL; return newStudent; }

Linking Nodes

Problem:
In this task you will continue working on the linked list of students in which you would like to store, for each student, their name and age. As before you are provided with some code that you should not modify:

A structure definition for the storage of each student's information.
A main() function to test your code.
Prototypes for the functions createStudent() (from the previous task) and append() (from the current task).
You will need the function definition (from the previous task) for createStudent(), as well as any other functions you added, such as copyStr() for example. If you were unable to solve the previous task you have the option to be given the code for the createStudent() function (see the quiz preceding this task) so that you can work on the current task.

Your new task is to write a function append() which takes as input two pointers: the first pointer holds the address of the current end of the linked list of students, the second pointer points to a newly created student. Your function should append this new student to the linked list and return the address (a struct student *) of the new end of the list.

Provided code
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; struct student *createStudent(char studentName[], int studentAge); struct student *append(struct student * end, struct student * newStudptr); /* add other prototypes here if needed */ int main(void) { struct student *start, *newStudptr, *end, *tmp; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printf("%s is %d years old.\n", start->name, start->age); printf("%s is %d years old.\n", start->next->name, start->next->age); printf("%s is %d years old.\n", start->next->next->name, start->next->next->age); tmp = start->next; free(start); start = tmp; tmp = start->next; free(start); free(tmp); return 0; } /* Place your function definitions here. Be sure to include the definition for createStudent() and any other functions you created for the previous task. */
​​​​Input: 
​​​​    25 18 32
​​​​Output: 
​​​​    Petra is 25 years old.
​​​​    Remi is 18 years old.
​​​​    Mike is 32 years old

Solution:

  • Create from the head,
  • save the end of the head with new node address
  • That node address also has a end, save the new new address to that, repeat
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; void copystr(char * ori, char * target); struct student *createStudent(char studentName[], int studentAge); struct student *append(struct student * end, struct student * newStudptr); int main(void) { struct student *start, *newStudptr, *end, *tmp; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printf("%s is %d years old.\n", start->name, start->age); printf("%s is %d years old.\n", start->next->name, start->next->age); printf("%s is %d years old.\n", start->next->next->name, start->next->next->age); tmp = start->next; free(start); start = tmp; tmp = start->next; free(start); free(tmp); return 0; } void copystr(char * ori, char * target){ int i = 0; while(ori[i] != '\0'){ target[i] = ori[i]; i++; } target[i] = '\0'; } struct student *createStudent(char studentName[], int studentAge){ struct student * newStudent; newStudent = (struct student *) malloc(sizeof(struct student)); copystr(studentName, newStudent->name); newStudent->age = studentAge; newStudent->next = NULL; return newStudent; } struct student *append(struct student * end, struct student * newStudptr){ end->next = newStudptr; return (end->next); }

Printing Linked List

Problem:
In this task you will continue working on the linked list of students in which you would like to store, for each student, their name and age. As before you are provided with some code that you should not modify:

A structure definition for the storage of each student's information.
A main() function to test your code.
Prototypes for the functions createStudent(), append() (from previous tasks) and printStudents() (from the current task).
You will need the function definitions (from previous tasks) for createStudent(), append() as well as any other functions you added, such as copyStr() for example. If you were unable to solve the previous task you have the option to be given the code for the append() function (see the quiz preceding this task) so that you can work on the current task.

Your new task is to write a function printStudents() which takes as input a pointer that holds the address of the start of a linked list of students. Your function should then print this list of students to the screen as specified in the example below. Your function should not return anything.

Provided Code
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; struct student *createStudent(char studentName[50], int studentAge); struct student * append(struct student * end, struct student * newStudptr); void printStudents(struct student *start); /* add other prototypes here if needed*/ int main(void) { struct student *start, *newStudptr, *end, *tmp; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printStudents(start); tmp = start->next; free(start); start = tmp; tmp = start->next; free(start); free(tmp); return 0; } /* Place your function definitions here. Be sure to include the definitions for createStudent() and append() as well as any other functions you created for the previous tasks. */
​​​​Input: 
​​​​    25 18 32
​​​​Output: 
​​​​    Petra is 25 years old.
​​​​    Remi is 18 years old.
​​​​    Mike is 32 years old.

Solution:

  • To print, you can get the head pointer first,
  • assign it as the index pointer
  • then update itself based on the next part of itself
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; void copystr(char * ori, char * target); struct student *createStudent(char studentName[], int studentAge); struct student *append(struct student * end, struct student * newStudptr); void printStudents(struct student * start); int main(void) { struct student *start, *newStudptr, *end, *tmp; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printStudents(start); tmp = start->next; free(start); start = tmp; tmp = start->next; free(start); free(tmp); return 0; } void copystr(char * ori, char * target){ int i = 0; while(ori[i] != '\0'){ target[i] = ori[i]; i++; } target[i] = '\0'; } struct student *createStudent(char studentName[], int studentAge){ struct student * newStudent; newStudent = (struct student *) malloc(sizeof(struct student)); copystr(studentName, newStudent->name); newStudent->age = studentAge; newStudent->next = NULL; return newStudent; } struct student *append(struct student * end, struct student * newStudptr){ end->next = newStudptr; return (end->next); } void printStudents(struct student * start){ struct student * state; state = start; while(state->next != NULL){ printf("%s is %d years old.\n", state->name, state->age); state = state->next; } printf("%s is %d years old.\n", state->name, state->age); }

Free The Linked List

In this task you will continue working on the linked list of students in which you would like to store, for each student, their name and age. As before you are provided with some code that you should not modify:

A structure definition for the storage of each student's information.
A main() function to test your code.
Prototypes for the functions createStudent(), append(), printStudents (from previous tasks) and freeStudents() (from the current task).
You will need the function definitions (from previous tasks) for createStudent(), append(), printStudents() as well as any other functions you added, such as copyStr() for example. If you were unable to solve the previous task you have the option to be given the code for the printStudents() function (see the quiz preceding this task) so that you can work on the current task.

Your current task is to write a function freeStudents() which takes as input a pointer that holds the address of the start of a linked list of students. Your function should then free the space allocated for each student in this list of students. Your function should not return anything.

Provided Code:
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; struct student *createStudent(char studentName[], int studentAge); struct student *append(struct student * end, struct student * newStudptr); void printStudents(struct student *start); void freeStudents(struct student *start); /* add any other prototypes as needed */ int main(void) { struct student *start, *newStudptr, *end; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printStudents(start); freeStudents(start); return 0; } /* Place your function definitions here. Be sure to include the definitions for createStudent(), append(), printStudents() as well as any other functions you created for the previous tasks. */
​​​​Input: 
​​​​    25 18 32
​​​​Output: 
​​​​    Petra is 25 years old.
​​​​    Remi is 18 years old.
​​​​    Mike is 32 years old.

Solution:

  • Before cutting the head, grab its tail
  • Cut the head
  • Serve the tail as the new head, repeat
  • Separate the index pointer with the temp in the definition
#include <stdio.h> #include <stdlib.h> struct student { char name[50]; int age; struct student *next; }; void copystr(char * ori, char * target); struct student *createStudent(char studentName[], int studentAge); struct student *append(struct student * end, struct student * newStudptr); void printStudents(struct student * start); void freeStudents(struct student * start); int main(void) { struct student *start, *newStudptr, *end; int ageP, ageR, ageM; scanf("%d %d %d", &ageP, &ageR, &ageM); start = createStudent("Petra", ageP); end = start; newStudptr = createStudent("Remi", ageR); end = append(end, newStudptr); newStudptr = createStudent("Mike", ageM); end = append(end, newStudptr); printStudents(start); freeStudents(start); return 0; } void copystr(char * ori, char * target){ int i = 0; while(ori[i] != '\0'){ target[i] = ori[i]; i++; } target[i] = '\0'; } struct student *createStudent(char studentName[], int studentAge){ struct student * newStudent; newStudent = (struct student *) malloc(sizeof(struct student)); copystr(studentName, newStudent->name); newStudent->age = studentAge; newStudent->next = NULL; return newStudent; } struct student *append(struct student * end, struct student * newStudptr){ end->next = newStudptr; return (end->next); } void printStudents(struct student * start){ struct student * state; state = start; while(state->next != NULL){ printf("%s is %d years old.\n", state->name, state->age); state = state->next; } printf("%s is %d years old.\n", state->name, state->age); } void freeStudents(struct student * start){ struct student * state = start; struct student * temp; while(state != NULL){ temp = state->next; free(state); state = temp; } }

Building a Linked List from User Input

Problem:
In this task you will work with the linked list of digits we have created in the lessons up to this point. As before you are provided with some code that you should not modify:

A structure definition for the storage of each digit's information.
A main() function to test your code.
The functions createDigit(), append(), printNumber(), freeNumber() and readNumber() which we have written in the lectures.
Your task is to write a new function divisibleByThree() which takes as input a pointer that holds the address of the start of a linked list of digits. Your function should then check whether the number stored in this linked list of digits is divisible by three. The function should return the value 1 if indeed the number is divisible by three and it should return the value 0 otherwise.

Provided Code
#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; // Write your prototypes here int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); if (divisibleByThree(start)) printf("is divisible by 3.\n"); else printf("is not divisible by 3.\n"); freeNumber(start); return 0; } struct digit *createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit *readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } // Write your divisibleByThree() function here
​​​​Input: 
​​​​    234
​​​​Output: 
​​​​    The number 234
​​​​    is divisible by 3.
​​​​Input: 
​​​​    74658
​​​​Output: 
​​​​    The number 74658
​​​​    is divisible by 3.
​​​​Input: 
​​​​    245
​​​​Output: 
​​​​    The number 245
​​​​    is not divisible by 3.

Solution:

#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; struct digit *createDigit(int dig); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *start); void freeNumber(struct digit *start); struct digit *readNumber(void); int divisibleByThree(struct digit * start); int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); if (divisibleByThree(start)) printf("is divisible by 3.\n"); else printf("is not divisible by 3.\n"); freeNumber(start); return 0; } struct digit *createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit *readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } int divisibleByThree(struct digit * start) { long long int placeholder = 0; struct digit * ptr = start; while(ptr != NULL){ placeholder += ptr->num; ptr = ptr->next; } //printf("%lld", placeholder); return (placeholder % 3) ? 0 : 1; }

Search & Update in Linked List

Problem
In this task you will work with the linked list of digits we have created in the lessons up to this point. As before you are provided with some code that you should not modify:

A structure definition for the storage of each digit's information.
A main() function to test your code.
The functions createDigit(), append(), printNumber(), freeNumber(), readNumber() and divisibleByThree() (although you may not need to use all of these).
Your task is to write a new function changeThrees() which takes as input a pointer that holds the address of the start of a linked list of digits. Your function should change all of those digits in this linked list that equal 3 to the digit 9, and count how many replacements were made. The function should return this number of replacements.

Provided Code
#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; struct digit * createDigit(int dig); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *start); void freeNumber(struct digit *start); int divisibleByThree(struct digit * start); struct digit * readNumber(void); //Add your own function prototypes here int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); printf("was modified in %d places.\n", changeThrees(start)); printf("The new number is "); printNumber(start); freeNumber(start); return 0; } struct digit * createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit * readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } int divisibleByThree(struct digit * start) { struct digit * ptr = start; int qsum = 0; while (ptr!=NULL) { qsum += ptr->num; ptr = ptr->next; } if (qsum%3==0) return 1; else return 0; } // Write your changeThrees() function here
​​​​Input: 
​​​​    234345632
​​​​Output: 
​​​​    The number 234345632
​​​​    was modified in 3 places.
​​​​    The new number is 294945692
​
​​​​Input: 
​​​​    4393293
​​​​Output: 
​​​​    The number 4393293
​​​​    was modified in 3 places.
​​​​    The new number is 4999299 

Solution:

  • as long aa the pointer is not null keep searching
  • update the next linked list
#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; struct digit * createDigit(int dig); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *start); void freeNumber(struct digit *start); int divisibleByThree(struct digit * start); struct digit * readNumber(void); int changeThrees(struct digit * start); int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); printf("was modified in %d places.\n", changeThrees(start)); printf("The new number is "); printNumber(start); freeNumber(start); return 0; } struct digit * createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit * readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } int divisibleByThree(struct digit * start) { struct digit * ptr = start; int qsum = 0; while (ptr!=NULL) { qsum += ptr->num; ptr = ptr->next; } if (qsum%3==0) return 1; else return 0; } int changeThrees(struct digit * start){ struct digit * state = start; int changes = 0; while(state != NULL){ if(state->num == 3){ state->num = 9; changes++; } state = state->next; } return changes; }

Insertion Sort for Sorting Linked List

Push new node at the start

  • create a new backwards pointer
  • copy the original value
  • put the copied value in front of the backwards pointer
  • update the forward pointer
  • keep copy
struct digit * insertAtFront(struct digit * start, struct digit * newptr) { //! heap=showMemory(start=348, cursors=[newptr,start]) newptr->next = start; return(newptr); } struct digit * reverseNumber(struct digit * start) { //! heap=showMemory(start=336, cursors=[ptr,start,bstart,newdigit]) struct digit *ptr = start; struct digit *bstart = NULL; struct digit *newdigit; if (start!=NULL) { bstart = createDigit(start->num); ptr = ptr->next; } while (ptr != NULL) { newdigit = createDigit(ptr->num); bstart = insertAtFront(bstart, newdigit); ptr = ptr->next; } return(bstart); }

Sorted Copy

  • Driver Function and Insert Function
  • Driver responsible for copy
  • Insert responsible for sorting
  • How to sort?
    • check the sortedStart
    • check the prev
    • move along, check the current list less than new digit
      • if reach the end (ptr is null) => add new node
        • set the last node.next as the address of the new digit
        • Set the new digit.next as ptr (current index)
      • if the prev is null => insert at the front
        • set start as the new head
    • Return the start

Example:

5 1 3 Action
1 5 x front
1 3 5 break
struct digit * insertAtFront(struct digit * start, struct digit * newptr) { newptr->next = start; return(newptr); } struct digit * insertIntoSorted(struct digit *start, struct digit *newDig) { struct digit *ptr = start; struct digit *prev = NULL; while ((ptr!=NULL) && (ptr->num < newDig->num)) { prev = ptr; ptr = ptr->next; } if (prev == NULL) { start = insertAtFront(start, newDig); } else { prev->next = newDig; newDig->next = ptr; } return(start); } struct digit * sortedCopy(struct digit * start) { struct digit *ptr = start; struct digit *sortedStart = NULL; struct digit *newDigit; if (start!=NULL) { sortedStart = createDigit(start->num); ptr = ptr->next; } while (ptr!=NULL) { newDigit = createDigit(ptr->num); sortedStart = insertIntoSorted(sortedStart, newDigit); ptr = ptr->next; } return(sortedStart); }

Practice: Remove Redundancy

Problem:
In this task you will again work with the linked list of digits we created during the lessons up to this point.

You are provided with (but are not required to use) the functions and prototypes we have written so far. You are also provided with a main() function to test your code. Please do not modify this main() function.

Your task is to write a new function countRedun() which takes as input a pointer that holds the address of the start of a linked list of digits. Your function should count how many redundancies can be observed in the number stored in this list and return this count of redundancies. A redundancy is a digit which has previously already occurred in the number. For example, in the number 39534, the second '3' is a redundancy.

Provided Code:
#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; // Add a prototype for countRedun() here struct digit * createDigit(int); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *); void freeNumber(struct digit *); struct digit *readNumber(void); int divisibleByThree(struct digit * start); int changeThrees(struct digit * start); // Do not modify this main() function int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); printf("contains %d redundancies.\n", countRedun(start)); freeNumber(start); return 0; } struct digit *createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit *readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } int divisibleByThree(struct digit * start) { struct digit * ptr = start; int qsum = 0; while (ptr!=NULL) { qsum += ptr->num; ptr = ptr->next; } if (qsum%3==0) return 1; else return 0; } int changeThrees(struct digit * start) { struct digit * ptr = start; int sum = 0; while (ptr!=NULL) { if (ptr->num == 3) { ptr->num = 9; sum++; } ptr = ptr->next; } return(sum); }
​​​​Input: 
​​​​    5243
​​​​Output: 
​​​​    The number 5243
​​​​    contains 0 redundancies.

​​​​Input: 
​​​​    5256202
​​​​Output: 
​​​​    The number 5256202
​​​​    contains 3 redundancies.

Solution:

#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; // Add a prototype for countRedun() here struct digit * createDigit(int); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *); void freeNumber(struct digit *); struct digit *readNumber(void); int divisibleByThree(struct digit * start); int changeThrees(struct digit * start); struct digit * front(struct digit * start, struct digit * newDigit); struct digit * insertSort(struct digit * start, struct digit * newDigit); int countRedun(struct digit * start); // Do not modify this main() function int main(void) { struct digit *start; start = readNumber(); printf("The number "); printNumber(start); printf("contains %d redundancies.\n", countRedun(start)); freeNumber(start); return 0; } struct digit *createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit *readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } int divisibleByThree(struct digit * start) { struct digit * ptr = start; int qsum = 0; while (ptr!=NULL) { qsum += ptr->num; ptr = ptr->next; } if (qsum%3==0) return 1; else return 0; } int changeThrees(struct digit * start) { struct digit * ptr = start; int sum = 0; while (ptr!=NULL) { if (ptr->num == 3) { ptr->num = 9; sum++; } ptr = ptr->next; } return(sum); } struct digit * front(struct digit * start, struct digit * newDigit){ newDigit->next = start; return(newDigit); } struct digit * insertSort(struct digit * start, struct digit * newDigit){ struct digit * state = start; struct digit * prev = NULL; // Move Along Until Break Point while((state != NULL) && (state->num < newDigit->num)) { prev = state; //Save the prev condition state = state->next; } // Check the breakpoint if(prev == NULL){ //Break at head start = front(start, newDigit); } else { //Break at the middle //Replace the prev with the new digit address prev->next = newDigit; //Link back the next component to the new digit newDigit->next = state; //No need to update the head } return(start); } int countRedun(struct digit * start){ struct digit * state = start; struct digit * newDigit; struct digit * sortedAddress = NULL; int counter = 0; int check = -99; // Establish the new sorted head if(start != NULL){ sortedAddress = createDigit(start->num); state = start->next; } // Move along and copy while(state != NULL){ //Copy the original node newDigit = createDigit(state->num); //Put the copied value into the insertSort, get the sorted head sortedAddress = insertSort(sortedAddress, newDigit); //Move to the next original node state = state->next; } //printNumber(sortedAddress);//Check the sorted // Check the sorted list for redundancies state = sortedAddress; while(state != NULL) { if(state->num == check) { counter++; } else { check = state->num; } state = state->next; } //Free the sorted list free(sortedAddress); return counter; }

Final Project

Problem:
In this project you will work with the linked list of digits we have created in the lessons during this course. As before you are provided with some code that you should not modify:

A structure definition for the storage of each digit's information.

A main() function to test your code.

The functions createDigit(), append(), printNumber(), freeNumber() and readNumber() which we have written in the lectures.

Your task is to write a new function reverseNumber() which receives as input a pointer that holds the address of the start of a linked list of digits and that returns a pointer that holds the address of the start of a new linked list of digits, namely the original list but in reverse order.

Hint: You should sit down with a piece of paper and a pen first to design the steps necessary to solve this problem. What additional functions might be useful? Do not start coding right away. For example, it may help to write function which finds the length of a linked list of digits. Another useful function might be one which finds the nth digit in a linked list of digits. Think this through first before starting to code.

Examples:

​​​​Input
​​​​    35267
​​​​Output
​​​​    The reverse of 35267
​​​​    is 76253

​​​​Input
​​​​    5
​​​​Output
​​​​    The reverse of 5
​​​​    is 5

Solution:

#include <stdio.h> #include <stdlib.h> struct digit { int num; struct digit *next; }; struct digit *readNumber(void); struct digit *createDigit(int dig); struct digit * append(struct digit * end, struct digit * newDigptr); void printNumber(struct digit *start); void freeNumber(struct digit *start); struct digit * putFront(struct digit * start, struct digit * newDigit); struct digit * reverseNumber(struct digit * start); int main(void) { struct digit *start, *backwards; start = readNumber(); backwards = reverseNumber(start); printf("The reverse of "); printNumber(start); printf("is "); printNumber(backwards); freeNumber(start); freeNumber(backwards); return 0; } struct digit *createDigit(int dig) { struct digit *ptr; ptr = (struct digit *) malloc(sizeof(struct digit)); ptr->num = dig; ptr->next = NULL; return ptr; } struct digit * append(struct digit * end, struct digit * newDigptr) { end->next = newDigptr; return(end->next); } void printNumber(struct digit *start) { struct digit * ptr = start; while (ptr!=NULL) { printf("%d", ptr->num); ptr = ptr->next; } printf("\n"); } void freeNumber(struct digit *start) { struct digit * ptr = start; struct digit * tmp; while (ptr!=NULL) { tmp = ptr->next; free(ptr); ptr = tmp; } } struct digit *readNumber(void) { char c; int d; struct digit *start, *end, *newptr; start = NULL; scanf("%c", &c); while (c != '\n') { d = c-48; newptr = createDigit(d); if (start == NULL) { start = newptr; end = start; } else { end = append(end, newptr); } scanf("%c", &c); } return(start); } struct digit * putFront(struct digit * start, struct digit * newDigit) { newDigit->next = start; return newDigit; } struct digit * reverseNumber(struct digit * start) { struct digit * state = start; struct digit * newDigit = NULL; struct digit * revAdd = NULL; // Init if(start != NULL){ revAdd = createDigit(start->num); state = start->next; } // Move Along while(state != NULL){ newDigit = createDigit(state->num); revAdd = putFront(revAdd, newDigit); state = state->next; } return revAdd; }