add solution of HW4
This commit is contained in:
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
@@ -52,6 +52,24 @@
|
|||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
"miDebuggerPath": "/usr/bin/gdb",
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
"preLaunchTask": "C/C++: g++ build active file"
|
"preLaunchTask": "C/C++: g++ build active file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nybusninesses",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${fileDirname}/${fileBasenameNoExtension}",
|
||||||
|
"args": [
|
||||||
|
"large_input1.json",
|
||||||
|
"output.txt",
|
||||||
|
"93101",
|
||||||
|
"Shopping",
|
||||||
|
"debug"
|
||||||
|
],
|
||||||
|
"cwd": "${fileDirname}",
|
||||||
|
"environment": [],
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
|
"preLaunchTask": "C/C++: g++ build active file"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
22
.vscode/settings.json
vendored
22
.vscode/settings.json
vendored
@@ -51,6 +51,26 @@
|
|||||||
"stdexcept": "cpp",
|
"stdexcept": "cpp",
|
||||||
"streambuf": "cpp",
|
"streambuf": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"cassert": "cpp"
|
"cassert": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"charconv": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"span": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"variant": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"__nullptr": "cpp",
|
||||||
|
"__bit_reference": "cpp",
|
||||||
|
"__hash_table": "cpp",
|
||||||
|
"__string": "cpp",
|
||||||
|
"queue": "cpp",
|
||||||
|
"stack": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
127
hws/yelp_businesses/Business.cpp
Normal file
127
hws/yelp_businesses/Business.cpp
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "Business.h"
|
||||||
|
|
||||||
|
//extracts a string value for the given field
|
||||||
|
std::string extractJsonString(const std::string &line, const std::string &field) {
|
||||||
|
std::string pattern = "\"" + field + "\":";
|
||||||
|
size_t pos = line.find(pattern);
|
||||||
|
if (pos == std::string::npos) {return "";} //in case pattern not found
|
||||||
|
pos += pattern.length();
|
||||||
|
//skip any whitespace
|
||||||
|
while (pos < line.size() && isspace(line[pos])) {pos++;}
|
||||||
|
if (pos >= line.size() || line[pos] != '\"') {return "";} //in case the opening quote is not found
|
||||||
|
pos++;
|
||||||
|
//skip the opening quote
|
||||||
|
size_t endPos = line.find("\"", pos);
|
||||||
|
if (endPos == std::string::npos) {return "";} //in case the closing quote is not found
|
||||||
|
return line.substr(pos, endPos - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//extracts an integer value for the given field
|
||||||
|
int extractJsonInt(const std::string &line, const std::string &field) {
|
||||||
|
std::string pattern = "\"" + field + "\":";
|
||||||
|
size_t pos = line.find(pattern);
|
||||||
|
if (pos == std::string::npos) {return -1;} //in case the pattern is not found
|
||||||
|
pos += pattern.length();
|
||||||
|
//skip any whitespace
|
||||||
|
while (pos < line.size() && isspace(line[pos])) {pos++;}
|
||||||
|
size_t endPos = pos;
|
||||||
|
//skip the negative sign
|
||||||
|
if (line[endPos] == '-') {endPos++;}
|
||||||
|
//skip the digits
|
||||||
|
while (endPos < line.size() && isdigit(line[endPos])) {endPos++;}
|
||||||
|
std::string numStr = line.substr(pos, endPos - pos);
|
||||||
|
int value = std::stoi(numStr);
|
||||||
|
if (value == 0) {return -1;} //in case the number is not found
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//extracts a double value for the given field
|
||||||
|
double extractJsonDouble(const std::string &line, const std::string &field) {
|
||||||
|
std::string pattern = "\"" + field + "\":";
|
||||||
|
size_t pos = line.find(pattern);
|
||||||
|
if (pos == std::string::npos) {return 0.0;} // in case the pattern is not found
|
||||||
|
pos += pattern.length();
|
||||||
|
//skip any whitespace
|
||||||
|
while (pos < line.size() && isspace(line[pos])) {pos++;}
|
||||||
|
if (line[pos] == '\"') {
|
||||||
|
//in case the data is quoted
|
||||||
|
pos++;
|
||||||
|
size_t endPos = line.find("\"", pos);
|
||||||
|
if (endPos == std::string::npos) {return 0.0;}
|
||||||
|
std::string numStr = line.substr(pos, endPos - pos);
|
||||||
|
double value = std::stod(numStr);
|
||||||
|
if (value == 0.0) {return 0.0;} //in case the number is not found
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
//in case the data is not quoted
|
||||||
|
size_t endPos = pos;
|
||||||
|
while (endPos < line.size() && (isdigit(line[endPos]) || line[endPos] == '.' || line[endPos]=='-')) {
|
||||||
|
endPos++;
|
||||||
|
}
|
||||||
|
std::string numStr = line.substr(pos, endPos - pos);
|
||||||
|
double value = std::stod(numStr);
|
||||||
|
if (value == 0.0) {return 0.0;} //in case the number is not found
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//extracts a price value for the given field
|
||||||
|
int extractJsonPrice(const std::string &line, const std::string &field) {
|
||||||
|
std::string pattern = "\"" + field + "\":";
|
||||||
|
size_t pos = line.find(pattern);
|
||||||
|
if (pos == std::string::npos) {return -1;} //in case the pattern is not found
|
||||||
|
pos += pattern.length();
|
||||||
|
//skip any whitespace
|
||||||
|
while (pos < line.size() && isspace(line[pos])) {pos++;}
|
||||||
|
if (line[pos] == '\"') {
|
||||||
|
pos++;
|
||||||
|
size_t endPos = line.find("\"", pos);
|
||||||
|
if (endPos == std::string::npos) {return -1;}
|
||||||
|
std::string numStr = line.substr(pos, endPos - pos);
|
||||||
|
if (numStr == "None") {return -1;} //in case the number is not found
|
||||||
|
return std::stoi(numStr);
|
||||||
|
} else {
|
||||||
|
size_t endPos = pos;
|
||||||
|
while (endPos < line.size() && (isdigit(line[endPos]) || line[endPos]=='-')) {
|
||||||
|
endPos++;
|
||||||
|
}
|
||||||
|
std::string numStr = line.substr(pos, endPos - pos);
|
||||||
|
if (numStr == "None") {return -1;} //in case the number is not found
|
||||||
|
return std::stoi(numStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//load the business data from a JSON line
|
||||||
|
Business::Business(const std::string &jsonLine) {
|
||||||
|
name = extractJsonString(jsonLine, "name");
|
||||||
|
categories = extractJsonString(jsonLine, "categories");
|
||||||
|
rating = extractJsonDouble(jsonLine, "stars");
|
||||||
|
price = extractJsonPrice(jsonLine, "RestaurantsPriceRange2");
|
||||||
|
review_count = extractJsonInt(jsonLine, "review_count");
|
||||||
|
city = extractJsonString(jsonLine, "city");
|
||||||
|
postal_code = extractJsonString(jsonLine, "postal_code");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Business::getName() const {return name;}
|
||||||
|
std::string Business::getCategories() const {return categories;}
|
||||||
|
double Business::getRating() const {return rating;}
|
||||||
|
int Business::getPrice() const {return price;}
|
||||||
|
int Business::getReviewCount() const {return review_count;}
|
||||||
|
std::string Business::getCity() const {return city;}
|
||||||
|
std::string Business::getPostalCode() const {return postal_code;}
|
||||||
|
|
||||||
|
//returns a string representing the star rating.
|
||||||
|
std::string Business::getStarString() const {
|
||||||
|
int fullStars = static_cast<int>(rating);
|
||||||
|
double fraction = rating - fullStars;
|
||||||
|
std::string stars;
|
||||||
|
for (int i = 0; i < fullStars; ++i)
|
||||||
|
stars += "\u2605";
|
||||||
|
if (fraction >= 0.5)
|
||||||
|
stars += "\u00BD";
|
||||||
|
return stars;
|
||||||
|
}
|
||||||
31
hws/yelp_businesses/Business.h
Normal file
31
hws/yelp_businesses/Business.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef BUSINESS_H
|
||||||
|
#define BUSINESS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Business {
|
||||||
|
public:
|
||||||
|
//constructs a Business by parsing a JSON-formatted line
|
||||||
|
Business(const std::string &jsonLine);
|
||||||
|
//Accessors
|
||||||
|
std::string getName() const;
|
||||||
|
std::string getCategories() const;
|
||||||
|
double getRating() const;
|
||||||
|
int getPrice() const;
|
||||||
|
int getReviewCount() const;
|
||||||
|
std::string getCity() const;
|
||||||
|
std::string getPostalCode() const;
|
||||||
|
//returns a string representation of the star rating
|
||||||
|
std::string getStarString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::string categories;
|
||||||
|
double rating;
|
||||||
|
int price;
|
||||||
|
int review_count;
|
||||||
|
std::string city;
|
||||||
|
std::string postal_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUSINESS_H
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
HOMEWORK 4: Yelp Businesses
|
HOMEWORK 4: Yelp Businesses
|
||||||
|
|
||||||
|
|
||||||
NAME: < insert name >
|
NAME: Jinshan Zhou
|
||||||
|
|
||||||
|
|
||||||
COLLABORATORS AND OTHER RESOURCES:
|
COLLABORATORS AND OTHER RESOURCES:
|
||||||
@@ -10,13 +10,14 @@ List the names of everyone you talked to about this assignment
|
|||||||
LMS, etc.), and all of the resources (books, online reference
|
LMS, etc.), and all of the resources (books, online reference
|
||||||
material, etc.) you consulted in completing this assignment.
|
material, etc.) you consulted in completing this assignment.
|
||||||
|
|
||||||
< insert collaborators / resources >
|
Not really, but when I handle the list, I check many lab examples. Also, I check the
|
||||||
|
sstream example from alb and my previous homework as well.
|
||||||
|
|
||||||
Remember: Your implementation for this assignment must be done on your
|
Remember: Your implementation for this assignment must be done on your
|
||||||
own, as described in "Academic Integrity for Homework" handout.
|
own, as described in "Academic Integrity for Homework" handout.
|
||||||
|
|
||||||
|
|
||||||
ESTIMATE OF # OF HOURS SPENT ON THIS ASSIGNMENT: < insert # hours >
|
ESTIMATE OF # OF HOURS SPENT ON THIS ASSIGNMENT: 13
|
||||||
|
|
||||||
|
|
||||||
MISC. COMMENTS TO GRADER:
|
MISC. COMMENTS TO GRADER:
|
||||||
@@ -33,4 +34,9 @@ What parts of the assignment did you find challenging? Is there anything that
|
|||||||
finally "clicked" for you in the process of working on this assignment? How well
|
finally "clicked" for you in the process of working on this assignment? How well
|
||||||
did the development and testing process go for you?
|
did the development and testing process go for you?
|
||||||
|
|
||||||
< insert reflection >
|
I just start writing the code and implementation directly. Then, I found there are
|
||||||
|
a few given codes on the end instruction. But, it's too late for me. I didn't fully
|
||||||
|
read through the instruction at the beginning. Which brings me some extra work.
|
||||||
|
When I realize that, other parts of my code already depends on my extract JSON functions.
|
||||||
|
So, I have to keep writing on top of that. If, I can do this again, I will check the
|
||||||
|
instruction in detail and find if there are useful cases.
|
||||||
|
|||||||
93
hws/yelp_businesses/nybusninesses.cpp
Normal file
93
hws/yelp_businesses/nybusninesses.cpp
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Business.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc < 5) {
|
||||||
|
std::cerr << "Usage: " << argv[0]
|
||||||
|
<< " input.json output.txt zipcode [categories...]"
|
||||||
|
<< std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//load the arguments
|
||||||
|
std::string inputFile = argv[1];
|
||||||
|
std::string outputFile = argv[2];
|
||||||
|
std::string zipcode = argv[3];
|
||||||
|
//read all categories from arguments
|
||||||
|
std::vector<std::string> searchCategories;
|
||||||
|
for (int i = 4; i < argc; ++i) {
|
||||||
|
searchCategories.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
//open the input file
|
||||||
|
std::ifstream inFile(inputFile.c_str());
|
||||||
|
if (!inFile) {
|
||||||
|
std::cerr << "Error: Could not open input file: "
|
||||||
|
<< inputFile << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//open the output file
|
||||||
|
std::ofstream outFile(outputFile.c_str());
|
||||||
|
if (!outFile) {
|
||||||
|
std::cerr << "Error: Could not open output file: "
|
||||||
|
<< outputFile << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//read each line and create a Business object if it matches the zipcode and at least one search category
|
||||||
|
std::list<Business> matchingBusinesses;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(inFile, line)) {
|
||||||
|
Business biz(line);
|
||||||
|
//check zipcode
|
||||||
|
if (biz.getPostalCode() != zipcode)
|
||||||
|
continue;
|
||||||
|
//check categories: at least one category must be found
|
||||||
|
bool categoryMatch = false;
|
||||||
|
std::string bizCategories = biz.getCategories();
|
||||||
|
for (std::vector<std::string>::const_iterator catIt = searchCategories.begin();
|
||||||
|
catIt != searchCategories.end(); ++catIt) {
|
||||||
|
if (bizCategories.find(*catIt) != std::string::npos) {
|
||||||
|
categoryMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (categoryMatch) {
|
||||||
|
matchingBusinesses.push_back(biz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//sort the list by rating in descending order
|
||||||
|
matchingBusinesses.sort([](const Business &a, const Business &b) {
|
||||||
|
return a.getRating() > b.getRating();
|
||||||
|
});
|
||||||
|
//output the results in a format similar to Yelp.
|
||||||
|
if (matchingBusinesses.empty()) {
|
||||||
|
outFile << "Sorry, we couldn't find any results" << std::endl;
|
||||||
|
} else {
|
||||||
|
int index = 1;
|
||||||
|
for (std::list<Business>::const_iterator it = matchingBusinesses.begin();
|
||||||
|
it != matchingBusinesses.end(); ++it) {
|
||||||
|
outFile << "=====================" << std::endl;
|
||||||
|
//add line 1: Index and Business Name
|
||||||
|
outFile << index << ". " << it->getName() << std::endl;
|
||||||
|
//add line 2: Star rating, numeric rating, and review count
|
||||||
|
outFile << it->getStarString() << " " << it->getRating()
|
||||||
|
<< " (" << it->getReviewCount() << " reviews)" << std::endl;
|
||||||
|
//add line 3: City and then the price range (if available)
|
||||||
|
outFile << it->getCity() << " ";
|
||||||
|
if (it->getPrice() != -1) {
|
||||||
|
for (int i = 0; i < it->getPrice(); ++i)
|
||||||
|
outFile << "$";
|
||||||
|
}
|
||||||
|
outFile << std::endl;
|
||||||
|
//add line 4: Categories
|
||||||
|
outFile << it->getCategories() << std::endl;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
outFile << "=====================" << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user