This program is suppose to take a json in the format of a dict. The keys are zipcodes and the values are vectors of rent prices.
When i run it using g++ I get a floating point exception 8: error. To my knowledge that error only triggers if the value overflows its data type but that could only occur if the averager function's mean variable is surpassing the max value of an unsigned long long which shouldn't occur.
I am also open to a more elegant way to write this code.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace std;
unsigned int average(unsigned int n1,unsigned int n2){
unsigned int mean;
mean = (n1 + n2)/2;
return mean;
}
unsigned long long average(vector<unsigned int> nValues){
unsigned long long mean = 0;
for(auto element : nValues){
mean += element;
}
mean /= nValues.size();
return mean;
}
unsigned int strCleaner(string str){
unsigned int na = 0;
string temp;
if(str == "N/A"){
return na;
}
for(auto element : str){
if(element == '$' || element == ',' || element == ' ' || element == '"'){
continue;
}
temp += element;
}
cout << temp << endl;
int newStr = stoi(temp);
return (unsigned int)newStr;
}
int main(void)
{
string line;
ifstream my_json("records_v1.json");
ifstream zips("zip_set.txt");
json my_stat;
json j;
my_json >> j;
while(getline(zips,line)){
vector<unsigned int> summation;
auto map = j[line];
for(auto element: map){
string element_str = element.dump();
size_t result = element_str.find("-");
if(result != string::npos){
string n1, n2;
for (int i = 0; i < element_str.size(); i++)
{
if(i < result){
n1 += element_str[i];
}
if(i > result){
n2 += element_str[i];
}
}
auto mean = average(strCleaner(n1),strCleaner(n2));
summation.push_back(mean);
}else if(element_str != "N/A"){
continue;
}else{
unsigned int cleanedInt = strCleaner(element);
summation.push_back(cleanedInt);
}
}
auto city_mean = average(summation);
my_stat[line] = city_mean;
}
ofstream f_myrecord("fileZ.json");
f_myrecord << setw(4) << my_stat << endl;
}
Related
I am trying to add large numbers using arrays without using bigint or anything like that. I can get my program to add the two arrays. However, I need to take the addition of the arrays and output the correct answer like a regular number. I cannot seem to make an algorithm to take the sum of my arrays and ouptut the answer. Does anybody have any tips or suggestions?
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;
const int DIGITS = 20;
void readNum(int list[], int& length, string input1);
void reverseArray(int arr[], int start, int end);
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2);
int main()
{
// Write your main here
string input1;
string input2;
int list[DIGITS];
int list2[DIGITS];
int total[DIGITS];
int input1Length;
int input2Length;
cout << "Please enter your 1st number: " << endl;
cin >> input1;
cout << "Please enter your 2nd number: " << endl;
cin >> input2;
input1Length = input1.length();
input2Length = input2.length();
readNum(list, input1Length, input1);
readNum(list2, input2Length, input2);
reverseArray(list, 0, input1Length);
reverseArray(list2, 0, input2Length);
sumNum(list, input1Length, list2, input2Length);
}
void readNum(int list[], int& length, string input1)
{
int array[DIGITS];
for (int i = 0; i < length; i++)
{
array[i] = input1[i] - '0';
list[i] = array[i];
}
}
void reverseArray(int arr[], int start, int length)
{
int end;
end = length - 1;
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2)
{
int length;
int sum = 0;
int carry = 0;
int total[DIGITS];
if (numOfElementsList1 > numOfElementsList2)
{
length = numOfElementsList1;
}
else
{
length = numOfElementsList2;
}
for (int i = 0; i < length; i++)
{
sum = list1[i] + list2[i] + carry;
if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
{
carry = 0;
}
total[i] = sum;
cout << total[i];
}
}
Strings are arrays of characters, you could just use them as-is. The advantage being... they're just strings, and you can output them as a string just as easily. Not a new technique, it's called a binary coded decimal which in this case is a zoned BCD (where the zone is 0x30 in ASCII, or zone 0xF0 in EBCDIC).
#include <iostream>
#include <string>
#include <stdexcept>
using std::string;
using std::cout;
using std::cin;
using std::runtime_error;
static string sumNum(string, string);
int main() {
string input1;
string input2;
cout << "Please enter your 1st number: ";
cin >> input1;
cout << "Please enter your 2nd number: ";
cin >> input2;
auto sum = sumNum(input1, input2);
cout << "Sum is: " << sum << "\n";
}
string sumNum(string a, string b) {
//a = string(a.rbegin(), a.rend());
//b = string(b.rbegin(), b.rend());
string sum;
auto digit = [carry = 0](int value) mutable {
value += carry;
if (value > 9) {
carry = 1;
value -= 10;
} else {
carry = 0;
}
return static_cast<char>(value + '0');
};
auto num = [](char c) {
if (c < '0' || c > '9') {
throw runtime_error("not a digit");
}
return c - '0';
};
auto aa = a.rbegin();
auto bb = b.rbegin();
while(aa != a.rend() && bb != b.rend()) {
sum.push_back(digit((num(*aa)) + (num(*bb))));
++aa;
++bb;
}
while (aa != a.rend()) {
sum.push_back(digit(num(*aa)));
++aa;
}
while (bb != b.rend()) {
sum.push_back(digit(num(*bb)));
++bb;
}
char last = digit(0);
if (last != '0')
sum.push_back(last);
return string(sum.rbegin(), sum.rend());
}
I am getting Assertion Failed. It show it after cin. I have checked also the file whose path it shows, but no solution.
"string iterator + offset out of range" is the massage it shows. It happens after I use "cin >> a" at line 65. Can anyone help me? Thanks in advance.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int gcd(int a, int b){
cout << "gcd" << endl;
if (b == 0) return a;
else return gcd(b, a % b);
}
int gcd_n(vector<int>nums){
int g;
size_t n = nums.size();
g = nums.at(0);
cout << "son" << endl;
for (int i = 1; i < n; i++){
g = gcd(nums.at(i), g);
}
return g;
}
long long int multi_vect(vector<int> v){
long long int m = 1;
for (size_t i = 0; i < v.size(); i++)
m *= v.at(i);
return m;
}
int main() {
int a;
vector <vector<int>> all_vects;
cin >> a;
string input, sub;
getline(cin, input);
int n = input.find(' ');
vector<int> vect;
while(true){
int num;
sub = input.substr(0, n);
istringstream(sub) >> num;
vect.push_back(num);
input = input.substr(n+1, input.back()+1);
n = input.find(' ');
if (n == -1){
istringstream(input) >> num;
vect.push_back(num);
break;
}
}
all_vects.push_back(vect);
}
When I tested this code, I found that n=-1 needs to be judged in advance. Suppose that input. Assuming that the string input has no ' ', then n will become -1, And the sub = input.substr(0, n); is not true. So, the vector vect will be empty. That is why string iterator + offset out of range will appear.
The following are my changes to this code. And you could refer to it.
if (n == -1)
{
istringstream(input) >> num;
vect.push_back(num);
break;
}
else {
sub = input.substr(0, n);
istringstream(sub) >> num;
vect.push_back(num);
input = input.substr(n + 1, input.back() + 1);
n = input.find(' ');
}
Assume that the value of a = 1, b = 2, c = 3, ... , z = 26. You are given a numeric string S. Write a program to return the list of all possible codes that can be generated from the given string.
For most of the cases this code works but it gives wrong output for inputs which have numbers greater than 26. For eg: 12345.
#include <iostream>
#include <string.h>
using namespace std;
using namespace std;
int atoi(char a)
{
int i=a-'0';
return i;
}
char itoa(int i)
{
char c='a'+i-1;
return c;
}
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
return 1;
}
if(input.size()==1)
{
output[0]=output[0]+itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
for(int i=0;i<size1;i++)
{
output[i]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[i+size1]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return size1+size2;
}
int main(){
string input;
cin >> input;
string output[10000];
int count = getCodes(input, output);
for(int i = 0; i < count && i < 10000; i++)
cout << output[i] << endl;
return 0;
}
if i give input 12345, the output is:
"
abcde
awde
lcde
l"
instead of :
"
abcde
awde
lcde"
i got it fellow members. i did not initialised the size2 variable to zero. also i didn't use >= operator.
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
output[0]="";
return 1;
}
if(input.size()==1)
{
output[0]=itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2=0;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>=10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
int k=0;
for(int i=0;i<size1;i++)
{
output[k++]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[k++]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return k;
}
this is the final code for getCodes function. Thanks everyone :)
You can do that more simply with something like this:
#include <utility>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void getCodesRec(unsigned int num, string& current, vector<string>& result)
{
// First and last chars for the codes
static constexpr char FIRST_CHAR = 'a';
static constexpr char LAST_CHAR = 'z';
if (num == 0)
{
// When there is no more number add the code to the results
result.push_back(current);
}
else
{
// Add chars to the existing code
unsigned int next = num;
unsigned int rem = next % 10;
unsigned int f = 1;
// While we have not gone over the max char number
// (in practice this loop will run twice at most for a-z letters)
while (next > 0 && rem <= (unsigned int)(LAST_CHAR - FIRST_CHAR) + 1)
{
next = next / 10;
if (rem != 0) // 0 does not have a replacement
{
// Add the corresponding char
current.insert(0, 1, FIRST_CHAR + char(rem - 1));
// Recursive call
getCodesRec(next, current, result);
// Remove the char
current.erase(0, 1);
}
// Add another number
f *= 10;
rem += f * (next % 10);
}
}
}
vector<string> getCodes(unsigned int num)
{
vector<string> result;
string current;
getCodesRec(num, current, result);
return result;
}
int main()
{
unsigned int num = 12345;
vector<string> codes = getCodes(12345);
cout << "Codes for " << num << endl;
for (string& code : codes)
{
cout << "* " << code << endl;
}
return 0;
}
Output:
Codes for 12345
* abcde
* lcde
* awde
I am working on a brute force task, but when I run my program, it gives an empty output file. Can anybody please help me fix this? The problem statement is below along with my code after that.
PROBLEM STATEMENT:
Write a program that reads two numbers (expressed in base 10):
N (1 <= N <= 15)
S (0 < S < 10000)
and then finds and prints (in base 10) the first N numbers strictly greater than S that are palindromic when written in two or more number bases (2 <= base <= 10).
Solutions to this problem do not require manipulating integers larger than the standard 32 bits.
CODE
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <fstream>
using namespace std;
string convert(int num, int base)
{
int quo = 100000;
int rem = 0;
string to_reverse;
while (quo > 0)
{
quo = num / base;
rem = num % base;
to_reverse += to_string(rem);
num /= base;
}
reverse(to_reverse.begin(), to_reverse.end());
return to_reverse;
}
bool is_pal(string conv_num)
{
string reversed_conv_num = conv_num;
reverse(reversed_conv_num.begin(), reversed_conv_num.end());
if (reversed_conv_num == conv_num)
{
return true;
}
return false;
}
int main()
{
ofstream fout("dualpal.out");
ifstream fin("dualpal.in");
int n, start;
fin >> n >> start;
vector<int> finals;
int times = 0;
for (int i = start + 1; i <= 10000; i++)
{
if (times == n)
{
for (auto x : finals)
{
fout << x << "\n";
}
break;
}
else
{
for (int j = 2; j <= 10; j++)
{
if(is_pal(convert(i, j)) == true)
{
times++;
finals.push_back(i);
}
}
}
}
return 0;
}
Try this code. I made some changes.
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <fstream>
using namespace std;
string convert(int num, int base)
{
int quo = 100000;
int rem = 0;
string to_reverse;
ostringstream str1; /*this and the next commented lines are added because "to_string" didnt work in my compiler*/
while (quo > 0)
{
quo = num / base;
rem = num % base;
str1 << rem; //this
to_reverse += str1.str(); //and this
num /= base;
}
reverse(to_reverse.begin(), to_reverse.end());
return to_reverse;
}
bool is_pal(string conv_num)
{
string reversed_conv_num = conv_num;
reverse(reversed_conv_num.begin(), reversed_conv_num.end());
if (reversed_conv_num == conv_num)
{
return true;
}
return false;
}
int main()
{
ofstream fout;
fout.open("dualpal.out", ios::out); //open the file in binary mode
//ifstream fin("dualpal.in");
int n, start;
cin >> n >> start;
vector<int> finals;
int times = 0;
for (int i = start + 1; i <= 10000; i++)
{
if (times == n)
{
//just a simple iterator for vector
for (vector<int>::iterator it = finals.begin(); it != finals.end(); ++it)
{
fout << *it << "\n";
}
break;
}
else
{
for (int j = 2; j <= 10; j++)
{
if(is_pal(convert(i, j)) == true)
{
times++;
finals.push_back(i);
}
}
}
}
fout.close(); //close the file
return 0;
}
USE OF STRING STREAMS
int number = 1000;
ostringstream s;
s << number;
string str = s.str();
This method can be used to convert number to strings.
This code requires <sstream> header file.
I can not figure out where I'm having my problem with my heap sort.
The program takes a filename from the command line, imports the words into a vector then that vector is turned into a vector pair of vector<string,int> where string is the word and int is the count of how many instances of that word are in the file.
The vector<PAIR> is then sorted by either the string (value or v) or by int (key or k). My sorting by Key works fine however sort by value is off. I suspect I'm missing an if statement in max_heapify when sorting by value. Here's my code:
main.cpp
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
#include <string.h>
#include <stdio.h>
#include <map>
#include <time.h>
#include "readwords.h"
using namespace std;
readwords wordsinfile;
vector<string> allwords;
bool times;
char *filename;
timespec timestart,timeend;
vector< pair<string,int> > allwords_vp;
timespec diffclock(timespec start, timespec end);
int main ( int argc, char *argv[] ) {
filename = argv[1];
//Lets open the file
ifstream ourfile2(filename);
//Lets get all the words using our requirements
allwords = wordsinfile.getwords(ourfile2);
//Convert all the words from file and count how many times they
//appear. We will store them in a vector<string,int> string
//being the word and int being how many time the word appeared
allwords_vp = wordsinfile.count_vector(allwords);
cout << "HeapSort by Values" << endl;
if (times) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ×tart);
wordsinfile.heapsort(const_cast<char *>("v"));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeend);
cout << "HeapSort by Values ran in "
<< diffclock(timestart,timeend).tv_nsec << " nanosecond or "
<< diffclock(timestart,timeend).tv_nsec/1000 << " millisecond"
<< endl;
} else {
wordsinfile.heapsort(const_cast<char *>("v"));
}
cout << "HeapSort by Keys" << endl;
if (times) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ×tart);
wordsinfile.heapsort(const_cast<char *>("k"));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeend);
cout << "HeapSort by Keys ran in "
<< diffclock(timestart,timeend).tv_nsec << " nanosecond or "
<< diffclock(timestart,timeend).tv_nsec/1000 << " millisecond"
<< endl;
} else {
wordsinfile.heapsort(const_cast<char *>("k"));
}
}
timespec diffclock(timespec start, timespec end) {
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
readwords.h
#ifndef READWORDS_H
#define READWORDS_H
#include <vector>
#include <map>
#include <utility>
#include <time.h>
typedef std::pair<std::string, int> PAIR;
bool isasciifile(std::istream& file);
class readwords {
private:
std::vector<PAIR> vp;
public:
std::vector<std::string> getwords(std::istream& file);
std::vector<PAIR> count_vector(std::vector<std::string> sv);
void print_vectorpair(std::vector<PAIR> vp);
void print_vector(std::vector<std::string> sv);
void heapsort(char how[]);
void buildmaxheap(std::vector<PAIR> &vp, int heapsize, char how[]);
void max_heapify(std::vector<PAIR> &vp, int i, int heapsize, char how[]);
void swap_pair(PAIR &p1, PAIR &p2);
};
readwords.cpp
#include <fstream>
#include <iostream>
#include <map>
#include "readwords.h"
#include <vector>
#include <string>
#include <utility>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
//using std::vector;
using namespace std;
typedef pair<string, int> PAIR;
// Do we have a ASCII file?
// Lets test the second 10 chars to make sure
// This method is flawed if the file is less than 10 chars
bool isasciifile(std::istream& file) {
int c = 0;
bool foundbin = false;
for(c=0; c < 10;c++) {
if(!isprint(file.get())){
// Looks like we found a non ASCII file, or its empty.
foundbin = true;
}
}
return foundbin;
}
// This is our workhorse as it splits up the words based on our criteria and
// passes them back as a vector of strings.
vector<string> readwords::getwords(std::istream& file) {
char c;
string aword;
vector<string> sv;
//Let go through the file till the end
while(file.good()) {
c = file.get();
if (isalnum(c)) {
//convert any uppercase to lowercase
if(isupper(c)) {
c = (tolower(c));
}
//if its a space lets go onto the next char
if(isspace(c)) { continue; }
//everything looks good lets add the char to our word
aword.insert(aword.end(),c);
} else {
//its not a alphnum or a space so lets skip it
if(!isspace(c)) { continue; }
//reset our string and increment
if (aword != "") {sv.push_back(aword);}
aword = "";
continue;
}
}
return sv;
}
vector<PAIR> readwords::count_vector(vector<string> sv) {
unsigned int i = 0;
int j = 0;
int match = 0;
// cout << "Working with these string: " << endl;
// print_vector(sv);
for (i=0; i < sv.size(); i++) {
// cout << "count of i: " << i << " word is: " << sv.at(i) << endl;
match = 0;
if(readwords::vp.size() == 0) {
readwords::vp.push_back(make_pair(sv.at(i),1)); continue;
}
for (j=readwords::vp.size() - 1; j >= 0; --j) {
if (sv.at(i) == readwords::vp.at(j).first) {
// cout << "Match found with: " << sv.at(i) << endl;;
readwords::vp.at(j).second = readwords::vp.at(j).second + 1;
match = 1;
}
// cout << "Value of j and match: " << j << match << endl;
if ( j == 0 && match == 0) {
// cout << "Match found at end with: " << sv.at(i) << endl;;
readwords::vp.push_back(make_pair(sv.at(i),1));
}
}
}
//Prob need to sort by first data type then second here, prior to sort functions.
//Might not be the best place as the sort functions would alter it, if not here
//then each sort requires to do secondary search
return readwords::vp;
}
void readwords::print_vectorpair(vector<PAIR> vp) {
unsigned int i = 0;
for (i=0; i < vp.size(); ++i) {
cout << vp.at(i).first << " " << vp.at(i).second << endl;
}
}
void readwords::print_vector(vector<string> sv) {
unsigned int i = 0;
for (i=0; i < sv.size(); ++i) {
cout << sv.at(i) << endl;
}
}
void readwords::heapsort(char how[]) {
int heapsize = (readwords::vp.size() - 1);
buildmaxheap(readwords::vp, heapsize, how);
for(int i=(readwords::vp.size() - 1); i >= 0; i--) {
swap(readwords::vp[0],readwords::vp[i]);
heapsize--;
max_heapify(readwords::vp, 0, heapsize, how);
}
print_vectorpair(readwords::vp);
}
void readwords::buildmaxheap(vector<PAIR> &vp, int heapsize, char how[]) {
for(int i=(heapsize/2); i >= 0 ; i--) {
max_heapify(vp, i, heapsize, how);
}
}
void readwords::max_heapify(vector<PAIR> &vp, int i, int heapsize, char how[]) {
int left = ( 2 * i ) + 1;
int right = left + 1;
int largest;
if(!strcmp(how,"v")) {
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if( vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}
if(right <= heapsize && vp.at(right).second >= vp.at(largest).second) {
if( vp.at(right).first >= vp.at(largest).first) {
largest = right;
}
}
}
if(!strcmp(how,"k")) {
if(left <= heapsize && vp.at(left).first > vp.at(i).first) {
largest = left;
} else {
largest = i;
}
if(right <= heapsize && vp.at(right).first > vp.at(largest).first) {
largest = right;
}
}
if(largest != i) {
swap(vp[i], vp[largest]);
max_heapify(vp, largest, heapsize, how);
}
}
The vector is then sorted by either the string (value or v) or by int (key or k).
That description doesn't match the code, sorting with a how parameter of "k" sorts by the first component only, which is the string, and sorting with "v" as how parameter takes both components into account.
I think it's a rather bad idea to pass a char[] to determine the sorting criterion, it should be a comparator function, so you need only one implementation in max_heapify.
My sorting by Key works fine however sort by value is off. I suspect I'm missing an if statement in max_heapify when sorting by value.
The problem is that a heap sort needs a total ordering or it won't sort properly.
Your conditions
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if( vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}
check whether both components of vp.at(left) (resp. right) are at least as large as the corresponding component of vp.at(i), resulting in the product partial ordering, two general pairs are not comparable, and in that case, your max_heapify doesn't do anything.
Example, for <"a",3>, <"b",2> and <"c",1> in the positions i, left, right, in whichever order, your max_heapify sets largest to i.
If your sorting by "v" is meant to sort based on the int component first, and in case of a tie, take the string component into account, you'd need to distinguish the cases vp.at(left).second > vp.at(i).second and equality (for right too, of course). For example
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if(vp.at(left).second > vp.at(i).second || vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}
To sort a vector<pair<string, int> > by values, consider adding vector<pair<int, string> >
vector<pair<int, string> > v(orignal.size());
for (int i = 0; i < v.size(); ++i) v[i] = make_pair(original[i].second, original[i].first);
sort(v.begin(), v.end());