851 words
4 minutes
CS50 Problem Set 5
CS50 Problem Set 5
Here’s my answer for the CS50 Problem Set 5. Hope that will help you a bit.
Problem 1: Inheritance
// Simulate genetic inheritance of blood type#define _DEFAULT_SOURCE#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <time.h>
// Each person has two parents and two allelestypedef struct person{ struct person *parents[2]; char alleles[2];} person;
const int GENERATIONS = 3;const int INDENT_LENGTH = 4;
person *create_family(int generations);void print_family(person *p, int generation);void free_family(person *p);char random_allele();
int main(void){ // Seed random number generator srandom(time(0));
// Create a new family with three generations person *p = create_family(GENERATIONS);
// Print family tree of blood types print_family(p, 0);
// Free memory free_family(p);}
// Create a new individual with `generations`person *create_family(int generations){ // TODO: Allocate memory for new person person *p = malloc(sizeof(person));
// If there are still generations left to create if (generations > 1) { // Create two new parents for current person by recursively calling create_family person *parent0 = create_family(generations - 1); person *parent1 = create_family(generations - 1);
// TODO: Set parent pointers for current person p->parents[0] = parent0; p->parents[1] = parent1;
// TODO: Randomly assign current person's alleles based on the alleles of their parents p->alleles[0] = parent0->alleles[random() % 2]; p->alleles[1] = parent1->alleles[random() % 2]; }
// If there are no generations left to create else { // TODO: Set parent pointers to NULL p->parents[0] = NULL; p->parents[1] = NULL;
// TODO: Randomly assign alleles p->alleles[0] = random_allele(); p->alleles[1] = random_allele(); }
// TODO: Return newly created person return p;
return NULL;}
// Free `p` and all ancestors of `p`.void free_family(person *p){ // TODO: Handle base case if (p == NULL) { return; }
// TODO: Free parents recursively free_family(p->parents[0]); free_family(p->parents[1]);
// TODO: Free child free(p);}
// Print each family member and their alleles.void print_family(person *p, int generation){ // Handle base case if (p == NULL) { return; }
// Print indentation for (int i = 0; i < generation * INDENT_LENGTH; i++) { printf(" "); }
// Print person if (generation == 0) { printf("Child (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]); } else if (generation == 1) { printf("Parent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]); } else { for (int i = 0; i < generation - 2; i++) { printf("Great-"); } printf("Grandparent (Generation %i): blood type %c%c\n", generation, p->alleles[0], p->alleles[1]); }
// Print parents of current generation print_family(p->parents[0], generation + 1); print_family(p->parents[1], generation + 1);}
// Randomly chooses a blood type allele.char random_allele(){ int r = random() % 3; if (r == 0) { return 'A'; } else if (r == 1) { return 'B'; } else { return 'O'; }}Problem 2: Speller
// Implements a dictionary's functionality
#include <ctype.h>#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <strings.h>
#include "dictionary.h"
// Represents a node in a hash tabletypedef struct node{ char word[LENGTH + 1]; struct node *next;} node;
int word_counter = 0;
// TODO: Choose number of buckets in hash tableconst unsigned int N = 26;
// Hash tablenode *table[N];
// Returns true if word is in dictionary, else falsebool check(const char *word){ // TODO // Hash the word to obtain its hash value int hash_value = hash(word);
// Search the hash table at the location specified by the word’s hash value // Return "true" if the word is found node *cursor = table[hash_value]; while (cursor != NULL) { if (strcasecmp(cursor->word, word) == 0) { return true; } else { cursor = cursor->next; } }
return false;}
// Hashes word to a numberunsigned int hash(const char *word){ // TODO: Improve this hash function return toupper(word[0]) - 'A';}
// Loads dictionary into memory, returning true if successful, else falsebool load(const char *dictionary){ // TODO // Make sure there is no garbage values for (int i = 0; i < N; i++) { table[i] = NULL; }
// Open the dictionary file FILE *dict = fopen(dictionary, "r"); if (dict == NULL) { printf("The dictinary does not exist.\n"); return false; }
// Read strings from file one at a time char temp_word[LENGTH];
while (fscanf(dict, "%s", temp_word) != EOF) { // Create space for a new hash table node node *new_word = malloc(sizeof(node));
// Copy the word into the new node strcpy(new_word->word, temp_word);
// Hash the word to obtain its hash value int hash_value = hash(temp_word);
// Insert the new node into the hash table (using the index specified by its hash value) new_word->next = table[hash_value]; table[hash_value] = new_word; word_counter += 1; }
// close the dictinary file fclose(dict);
return true;}
// Returns number of words in dictionary if loaded, else 0 if not yet loadedunsigned int size(void){ // TODO return word_counter;}
// Unloads dictionary from memory, returning true if successful, else falsebool unload(void){ // TODO for (int i = 0; i < N; i++) { node *tmp = table[i]; node *cursor = table[i];
while (cursor != NULL) { cursor = cursor->next; free(tmp); tmp = cursor; } } return true;} CS50 Problem Set 5
https://tech.kinghua0629.com/posts/cs50-problem-set-5/