Code:
#include "answer10.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct BusList_t{
int id;
long int addressOffset;
long int reviewOffset;
struct BusList_t* next;
}BusList;
typedef struct BusTree_t{
char* name;
BusList* locations;
struct BusTree_t* left;
struct BusTree_t* right;
}BusTree;
struct YelpDataBST{
const char* business;
const char* reviews;
BusTree* Bushead;
};
typedef int (*compfn)(const void*, const void*);
BusList* BusNode_create(long int addressOffset, long int reviewOffset, int id);
BusList* BusNode_insert(BusList* head, long int addressOffset, long int reviewOffset, int id);
void BusList_destroy(BusList* head);
void BusList_print(BusList* head);
BusTree* BusTree_create(const char* name, BusList* busListHead, long int addressOffset, long int reviewOffset, int id);
BusTree* BusTree_insert(BusTree* root, BusTree* node);
void BusTree_destroy(BusTree* root);
void BusTree_print(BusTree* root);
long int List_length(BusList* list);
long int numBusinesses(BusTree* bst, char* name2);
BusTree* findBusiness(BusTree* yelpTree, char* name);
int compareStars(const void*, const void*);
int compareLocation(const void*, const void*);
struct YelpDataBST* create_business_bst(const char* businesses_path, const char* reviews_path){
if(fopen(businesses_path,"r") == NULL || fopen(reviews_path,"r") == NULL)
return NULL;
FILE* fp_bp = fopen(businesses_path, "r");
FILE* fp_rp = fopen(reviews_path, "r");
struct YelpDataBST* yelp = malloc(sizeof(struct YelpDataBST));
int ID = -1;
int tempID;
int tempID2;
int end;
long int addressOffset = -1;
long int reviewOffset = 0;
char line[2000];
char line2[2000];
char* token;
char token2[2000];
char name[2000];
char state[2000];
char zip_code[2000];
char address[2000];
int len;
BusList* busListHead = NULL;
BusTree* busTreeNode = NULL;
BusTree* busTreeHead = NULL;
fseek(fp_bp,0, SEEK_END);
end = ftell(fp_bp);
ID = 0;
tempID = 0;
fgets(line,2000,fp_rp);
fgets(line2,2000,fp_bp);
fseek(fp_rp,0, SEEK_SET);
fseek(fp_bp,0,SEEK_SET);
int ct = 0;
while(!feof(fp_rp)){
if(addressOffset == -1){
sscanf(line2, "%d\t%[^\t]", &ID, name);
}
len = strlen(line);
sscanf(line, "%d", &tempID);
if(ct == 0){
tempID = 1;
ct++;
}
if((ID != tempID || (ID < 0)) && tempID != 0){
if(tempID == 1)
tempID = 0;
sscanf(line2, "\t%d\t%[^\t]", &tempID2, token2);
if(token2 != NULL){
if(name != NULL)
if(strcmp(token2, name) == 0){
fgets(line2, 2000,fp_bp);
sscanf(line2, "\t%d\t%[^\t]", &tempID2, token2);
}
strcpy(name, token2);
}
reviewOffset = ftell(fp_rp);
if(tempID != 0)
reviewOffset -= len;
ID = tempID;//atoi(token);
if(addressOffset == -1){
addressOffset = 0;
fgets(line2, 2000,fp_bp);
}
if(addressOffset != end){
busTreeNode = BusTree_create(name, busListHead, addressOffset, reviewOffset, ID);
busTreeHead = BusTree_insert(busTreeHead, busTreeNode); //replace with create node for tree
}
if(addressOffset != -1)
addressOffset = ftell(fp_bp);
fgets(line2,2000,fp_bp);
}
fgets(line,2000,fp_rp);
}
yelp->Bushead = busTreeHead;
yelp->business = businesses_path;
yelp->reviews = reviews_path;
BusTree_print(yelp->Bushead);
BusTree_destroy(busTreeHead);
fclose(fp_bp);
fclose(fp_rp);
return yelp;
}
struct Business* get_business_reviews(struct YelpDataBST* bst, char* name, char* state, char* zip_code){
FILE* fp_bp = fopen(bst->business, "r");
FILE* fp_rp = fopen(bst->reviews, "r");
struct Business* yelpBusiness = malloc(sizeof(struct Business));
BusTree* businessTree = bst->Bushead;
int i;
char* token;
char line[6000];
char line2[6000];
int ID;
char address[6000];
char city[6000];
char tempName[6000];
char funny[6000];
char useful[6000];
char cool[6000];
int tempID;
int tempID2;
int numReviews = 0;
char* temp;
//yelpBusiness->name = name;
//find # of businesses
businessTree = findBusiness(businessTree, name);
yelpBusiness->num_locations = List_length(businessTree->locations);
//yelpBusiness->num_locations = numBusinesses(bst->Bushead, name);
//find the busTreeHead for whatever name you are searching
struct Location locations[yelpBusiness->num_locations];
for(i = 0; i < yelpBusiness->num_locations; i++){
fseek(fp_bp, businessTree->locations->addressOffset, SEEK_SET);
sscanf(line, "%d\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]", &ID,tempName, address, city, state);
locations[i].address = address;
locations[i].city = city;
locations[i].state = state;
locations[i].zip_code = zip_code;
//find number of reviews
fseek(fp_rp, businessTree->locations->reviewOffset, SEEK_SET);
tempID = ID;
fgets(line2,6000,fp_rp);
while(tempID == ID){
tempID = atoi(strtok(line2, "\t"));
numReviews++;
fgets(line2,6000,fp_rp);
}
locations[i].num_reviews = numReviews;
struct Review reviews[numReviews];
fseek(fp_rp, businessTree->locations->reviewOffset, SEEK_SET);
fgets(line2,6000,fp_rp);
for(i=0; i < numReviews; i++){
sscanf(line2, "%d\t%d\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]", &tempID2, (int*)&reviews[i].stars, funny, useful, cool, reviews[i].text);
fgets(line2,6000,fp_rp);
}
qsort(locations[i].reviews, numReviews, sizeof(struct Location), compareStars);
}
qsort(locations, yelpBusiness->num_locations, sizeof(struct Location), compareLocation);
return yelpBusiness;
}
void destroy_business_bst(struct YelpDataBST* bst){
}
void destroy_business_result(struct Business* b){
}
BusList* BusNode_create(long int addressOffset, long int reviewOffset, int id){
BusList* loc = malloc(sizeof(BusList));
loc->id = id;
loc->addressOffset = addressOffset;
loc->reviewOffset = reviewOffset;
loc->next = NULL;
return loc;
}
BusList* BusNode_insert(BusList* head, long int addressOffset, long int reviewOffset, int id){
if(head == NULL)
return BusNode_create(addressOffset, reviewOffset, id);
if(BusNode_create(addressOffset, reviewOffset, id) == NULL)
return head;
BusList* newNode = BusNode_create(addressOffset, reviewOffset, id);
newNode->next = head;
return newNode;
}
void BusList_destroy(BusList* head){
while(head != NULL){
BusList* next = head->next;
free(head);
head = next;
}
}
void BusList_print(BusList* head){
while(head != NULL){
printf("addressOffset: %ld reviewOffset: %ld\n",head->addressOffset, head->reviewOffset);
head = head->next;
}
}
//Business Tree of Business Linked Lists
BusTree* BusTree_create(const char* name, BusList* busListHead, long int addressOffset, long int reviewOffset, int id){
BusTree* node = malloc(sizeof(BusTree));
node->name = strdup(name);
node->locations = BusNode_insert(busListHead, addressOffset, reviewOffset, id);
node->left = NULL;
node->right = NULL;
return node;
}
BusTree* BusTree_insert(BusTree* root, BusTree* node){
if(root == NULL)
return node;
if(node == NULL)
return root;
int cmp = strcmp(node->name, root->name);
if(cmp < 0){
root->left = BusTree_insert(root->left, node);
}
else if(cmp> 0){
root->right = BusTree_insert(root->right, node);
}
else{
root->locations = BusNode_insert(root->locations, node->locations->addressOffset, node->locations->reviewOffset, node->locations->id);
}
return root;
}
void BusTree_destroy(BusTree* root){
if(root == NULL){
free(root);
return;
}
BusTree_destroy(root->left);
BusTree_destroy(root->right);
BusList_destroy(root->locations);
free(root->name);
free(root);
}
void BusTree_print(BusTree* root){
if(root == NULL)
return;
printf("%p '%s' (%p %p)\n", root, root->name, root->left, root->right);
BusList_print(root->locations);
BusTree_print(root->left);
BusTree_print(root->right);
}
long int List_length(BusList* list)
{
long int len = 0;
while(list != NULL)
{
++len;
list = list->next;
}
return len;
}
long int numBusinesses(BusTree* bst, char* name2){
if(strcmp(bst->name, name2)> 0 )
numBusinesses(bst->left, name2);
else if(strcmp(bst->name, name2)< 0)
numBusinesses(bst->right, name2);
return List_length(bst->locations);
}
BusTree* findBusiness(BusTree* yelpTree, char* busName){
if(strcmp(yelpTree->name, busName) > 0)
findBusiness(yelpTree->left, busName);
else if(strcmp(yelpTree->name, busName) < 0)
findBusiness(yelpTree->right, busName);
return yelpTree;
}
int compareStars(const void* p1, const void* p2){
struct Review* stars1 = (struct Review*) p1;
struct Review* stars2 = (struct Review*) p2;
int s1 = (int)(*stars1).stars;
int s2 = (int)(*stars2).stars;
if(s1 > s2)
return -1;
else if(s2 > s1)
return 1;
else
return(strcasecmp((*stars1).text,(*stars2).text));
}
int compareLocation(const void* p1, const void* p2){
struct Location* loc1 = (struct Location*) p1;
struct Location* loc2 = (struct Location*) p2;
char* str1 = malloc(sizeof(char) * 6000);
char* str2 = malloc(sizeof(char) * 6000);
if(str1 == NULL || str2 == NULL || (*loc1).state == NULL || (*loc2).state == NULL || (*loc1).city == NULL || (*loc2).city == NULL || (*loc1).address == NULL || (*loc2).address == NULL){
free(str1);
free(str2);
return 0;
}
strcpy(str1,(*loc1).state);
strcpy(str2,(*loc2).state);
strcat(str1,(*loc1).city);
strcat(str2,(*loc2).city);
strcat(str1,(*loc1).address);
strcat(str1,(*loc2).address);
int cmp = strcasecmp(str1, str2);
free(str1);
free(str2);
return cmp;
}