Related
I am trying to solve this problem:
https://www.geeksforgeeks.org/count-possible-decodings-given-digit-sequence/
Example:
Input:
Input str = "121"
Total decoding:: 3 :: ABA AU LA
I am able to code this problem through recursion. But the code fails to process a bigger input sequence (for e.g., i/p str = 11111111111111111111111111111111111111111)
This is happening because I am calculating sub-problems again-and-again.
Can anyone help me by letting me know how to memoize below sample code?
PS - I know there are other ways to solve this problem. But I don't want to do that. I want to memoize this solution only. It will help me to build my concept. Please help.
Here is the code:
#include "iostream"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
namespace solution3
{
void solve(string str, string& out, vector<string>& v)
{
if (str.size() == 0)
{
v.push_back(out);
return;
}
//we have 2 choices:
//ch#1: take 1st char of str
//ch#2: take 1st and 2nd chars of str
if (str.size() >= 1)//ch#1: take 1st char of str
{
string out1 = out;
string str1 = str;
int num1 = stoi(str.substr(0, 1)); // converting string at index 0 to integer
if (num1) // we will not consider if the string at index 0 is zero.
{
out1.push_back(('#' + num1)); //<-- It will conevrt 1 into A; 2 into B; and so on.
str1 = str1.erase(0, 1);//erase the index 0 from str1.
solve(str1, out1, v);
}
}
if (str.size() >= 2)//ch#2: take 1st and 2nd chars of str
{
string out2 = out;
string str2 = str;
int num2 = stoi(str.substr(0, 2)); // converting string at index 0 and 1 to integer
// checking if num2 is a valid number for decoding.
// num2 should be - NON-ZERO, 1st char is not ZERO, is within the range of 1 and 26.
if (num2 && str[0] != '0' && num2 > 0 && num2 <= 26)
{
out2.push_back(('#' + num2));
//Erase 1st two chars from str
str2 = str2.erase(0, 1);//erase the index 0 from str1.
str2 = str2.erase(0, 1);//erase the index 0 from str1.
solve(str2, out2, v);
}
}
}
void alphacode(string str)
{
string out;
vector<string> v; //<-- To store all the Decodings
solve(str, out, v);
cout << "Total decoding:: " << v.size() << ":: ";
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
cout << endl;
}
}
int main()
{
string str = "25114";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "1111111111";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "3333333333";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "202";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "2010";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "1111111111111111111111111111111"; //<-- takes too much time! How to solve this?
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
return 0;
}
You can memoize each substring that you are currently working with, which you're forming after deleting one or two characters, depending on the case. Something like this:
#include "iostream"
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
map<string, vector<string>> dp;
namespace solution3
{
void solve(string str, string& out, vector<string>& v)
{
if (str.size() == 0)
{
v.push_back(out);
return;
}
//we have 2 choices:
//ch#1: take 1st char of str
//ch#2: take 1st and 2nd chars of str
if(dp.find(str) != dp.end()) {
vector<string> current = dp[str];
for(string s: current) {
v.push_back(s);
}
return;
}
if (str.size() >= 1)//ch#1: take 1st char of str
{
string out1 = out;
string str1 = str;
int num1 = stoi(str.substr(0, 1)); // converting string at index 0 to integer
if (num1) // we will not consider if the string at index 0 is zero.
{
out1.push_back(('#' + num1)); //<-- It will conevrt 1 into A; 2 into B; and so on.
str1 = str1.erase(0, 1);//erase the index 0 from str1.
solve(str1, out1, v);
}
}
if (str.size() >= 2)//ch#2: take 1st and 2nd chars of str
{
string out2 = out;
string str2 = str;
int num2 = stoi(str.substr(0, 2)); // converting string at index 0 and 1 to integer
// checking if num2 is a valid number for decoding.
// num2 should be - NON-ZERO, 1st char is not ZERO, is within the range of 1 and 26.
if (num2 && str[0] != '0' && num2 > 0 && num2 <= 26)
{
out2.push_back(('#' + num2));
//Erase 1st two chars from str
str2 = str2.erase(0, 1);//erase the index 0 from str1.
str2 = str2.erase(0, 1);//erase the index 0 from str1.
solve(str2, out2, v);
}
}
dp[str] = v;
}
void alphacode(string str)
{
string out;
vector<string> v; //<-- To store all the Decodings
solve(str, out, v);
cout << "Total decoding:: " << v.size() << ":: ";
// for (int i = 0; i < v.size(); i++)
// cout << v[i] << " ";
cout << endl;
}
}
int main()
{
string str = "25114";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "1111111111";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "3333333333";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "202";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "2010";
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
cout << "----------------" << endl;
str = "1111111111111111111111111111111"; //<-- takes too much time! How to solve this?
cout << "IpStr:: " << str << endl;
solution3::alphacode(str);
return 0;
}
I have made a program that is trying to read a .csv file and calculates the grades of the students.
I have made Student class and in the Main function I make Student type vector to read through the file and store the data in objects. Then I store all my objects in the vector .
The code was working fine, until I made some changes to take the filepath from the user. Now Its not working IDK why.. Kindly take a look into the code.
Student.h
#include <iostream>
#include <string>
using namespace std;
class student {
public:
string CMSID, firstname, lastname;
double quiz1, ass1, ass2, ass3, quiz2, quiz3, oht1, oht2, ESE, aggregate;
student();
student(string cmsid, string fn, string ln, double q1, double a1, double a2, double a3, double q2, double q3, double o1, double o2, double ese);
void calculateAggregate();
};
Students.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include "students.h"
using namespace std;
student::student() {}
student::student(string cmsid, string fn, string ln, double q1, double a1, double a2, double a3, double q2, double q3, double o1, double o2, double ese) {
CMSID = cmsid;
firstname = fn;
lastname = ln;
quiz1 = quiz1;
quiz2 = quiz2;
quiz3 = quiz3;
ass1 = a1;
ass2 = a2;
ass3 = a3;
oht1 = o1;
oht2 = o2;
ESE = ese;
}
void student::calculateAggregate()
{
aggregate = ((quiz1 + quiz2 + quiz3)*(10.0 / 30.0) + (ass1 + ass2 + ass3)*(10.0 / 30.0) + (oht1)*(20.0 / 50.0) + (oht2)*(20.0 / 50.0) + ESE * (40.0 / 100.0));
}
int main(int argc, char **argv) {
string CMSID, firstname, lastname, quiz1, ass1, ass2, ass3, quiz2, quiz3, oht1, oht2, ESE;
string Name,fileName;
ifstream gradesFile;
cout << "Place your file (.csv) in the program's directory." << endl;
cout << "Make sure that the first two rows of your file does not contain any student's data. " << endl;
cout << "Enter file name with extension(.csv): " ;
// taking filepath or filename input from the user
cin >> fileName;
gradesFile.open(fileName);
//declaring vectors of Type Student and type Double to store the objects of students containing their data (names, quizzes etc)
vector <double> aggregateList;
vector <student> students;
student *st;
//Ignoring the first two rows containing the titles of the columns
getline(gradesFile, Name);
getline(gradesFile, Name);
/// good() returns true if the file is readable and writeable
while (gradesFile.good()) {
try {
getline(gradesFile, CMSID, ',');
getline(gradesFile, firstname, ',');
getline(gradesFile, lastname, ',');
getline(gradesFile, quiz1, ',');
getline(gradesFile, ass1, ',');
getline(gradesFile, ass2, ',');
getline(gradesFile, ass3, ',');
getline(gradesFile, quiz2, ',');
getline(gradesFile, quiz3, ',');
getline(gradesFile, oht1, ',');
getline(gradesFile, oht2, ',');
getline(gradesFile, ESE, '\n');
if (quiz1.compare("") == 0) { // Replacing the empty colums with a 0 to manipulate the data correctly.
quiz1 = "0";
}
if (quiz2.compare("") == 0) {
quiz2 = "0";
}
if (quiz3.compare("") == 0) {
quiz3 = "0";
}
if (ass1.compare("") == 0) {
ass1 = "0";
}
if (ass2.compare("") == 0) {
ass2 = "0";
}
if (ass3.compare("") == 0) {
ass3 = "0";
}
if (oht1.compare("") == 0) {
oht1 = "0";
}
if (oht2.compare("") == 0) {
oht2 = "0";
}
if (ESE.compare("") == 0) {
ESE = "0";
}
// storing the data as student type objects and storing them in the vector <students>
st = new student(CMSID, firstname, lastname, stod(quiz1), stod(ass1), stod(ass2), stod(ass3), stod(quiz2), stod(quiz3), stod(oht1), stod(oht2), stod(ESE));
students.push_back(*st);
}
catch (invalid_argument) {}
}
// Calculating aggregates of all the student objects, and storing them in a separate aggregate list.
for (int j = 0; j < students.size(); j++) {
students[j].calculateAggregate();
aggregateList.push_back(students[j].aggregate);
}
// sorting the aggregateList vector to calculate the Grades correctly
sort(aggregateList.begin(), aggregateList.end());
//Calculating Deciles (10,20,30 percents and so on)
//d1 gives the data item that has 10 percent values below it, d2 has 20 percent values and so on...
double d1 = aggregateList[ceil(((aggregateList.size() + 1)*(0.1)))];
double d2 = aggregateList[ceil(((aggregateList.size() + 1)*(0.2)))];
double d3 = aggregateList[ceil(((aggregateList.size() + 1)*(0.3)))];
double d4 = aggregateList[ceil(((aggregateList.size() + 1)*(0.4)))];
double d5 = aggregateList[ceil(((aggregateList.size() + 1)*(0.5)))];
double d6 = aggregateList[ceil(((aggregateList.size() + 1)*(0.6)))];
double d7 = aggregateList[ceil(((aggregateList.size() + 1)*(0.7)))];
double d8 = aggregateList[ceil(((aggregateList.size() + 1)*(0.8)))];
double d9 = aggregateList[ceil(((aggregateList.size() + 1)*(0.9)))];
//Giving grades
ofstream A, Bplus, B, Cplus, C, Dplus, D, F;
A.open(fileName + "-A Grades.csv ");
Bplus.open(fileName + "-Bplus.csv");
B.open(fileName + "-B Grades.csv");
C.open(fileName + "-C Grades.csv");
Cplus.open(fileName + "-Cplus Grades.csv");
D.open(fileName + "-D Grades.csv");
Dplus.open(fileName + "-Dplus Grades.csv");
F.open(fileName + "-F Grades.csv");
for (int j = 0; j < students.size(); j++) {
if (A.is_open()) {
if (students[j].aggregate > d9) A << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (Bplus.is_open()) {
if (students[j].aggregate > d7 && students[j].aggregate <= d9) Bplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (B.is_open()) {
if (students[j].aggregate > d5 && students[j].aggregate <= d7) B << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (Cplus.is_open()) {
if (students[j].aggregate > d4 && students[j].aggregate <= d5) Cplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (C.is_open()) {
if (students[j].aggregate > d3 && students[j].aggregate <= d4) C << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (Dplus.is_open()) {
if (students[j].aggregate > d2 && students[j].aggregate <= d3) Dplus << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (D.is_open()) {
if (students[j].aggregate > d1 && students[j].aggregate <= d2) D << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
if (F.is_open()) {
if (students[j].aggregate <= d1) F << students[j].CMSID << "," << students[j].firstname << "," << students[j].lastname << "," << students[j].aggregate << endl;
}
else cout << "File coudln't be made." << endl;
}
A.close();
B.close();
Bplus.close();
C.close();
Cplus.close();
D.close();
Dplus.close();
F.close();
system("pause");
return 0;
}
I have already searched the website for relevant errors, but couldn't understand!
Check the error here.
The error is caused by creating a vector with size n, but accessing elements beyond that.
a vector x of size n has
x[0], x[1], x[2], ..., x[n-2], x[n-1]
Accessing x[n], or x[n+1] will be outside of the range and throw the error.
ceil(((aggregateList.size() + 1)*(0.9)))
Is an expression that can be as large as n for the vector, and can overrun the memory
You need to use a debugger. Fortunately since you are using Visual Studio this is much nicer experience than using gdb.
When the assertion fails click retry in the popup, that will give you the opportunity to inspect the call stack and the values of the variables.
Alternatively if this way it is easier for you you can step through your program line by line and watch the values of the variables change...
I'm relatively new programming c++. I'm implementing a tree like index for a db using unorderd_map on the implementation of the tree data structure to store the children nodes. As im working with tree like structures the construction an search methods are recursive, also i store the pointers of the nodes, so i suspect i may have a sort of not well handled memory issue. I'm getting a segmentation fault. Next is my code and the output of it.
#include <memory>
#include <sstream>
#include <unordered_map>
#include <iostream>
#include <string>
#include <sqlite3.h>
#include "aux_functions.cpp"
#include <math.h>
using namespace std;
class TreeLikeIndex
{
public:
TreeLikeIndex(string attribute, string indices, int indices_count, short int is_leaf, unordered_map<string, TreeLikeIndex*> children);
TreeLikeIndex(string indices, int indices_count);
TreeLikeIndex();
string search(unordered_map<string, string> *);
private:
string indices;
int indices_count;
short int is_leaf;
string attribute;
unordered_map<string, TreeLikeIndex*> children;
};
string TreeLikeIndex::search(unordered_map<string, string> * _tuple)
{
if((*_tuple).empty() || this->is_leaf ) return this->indices;
string att_val = (*_tuple)[this->attribute];
(*_tuple).erase(this->attribute);
TreeLikeIndex * child_with_that_value = this->children[att_val];
return (*child_with_that_value).search(_tuple);
}
class DecisionTreeLikeIndexer
{
public:
DecisionTreeLikeIndexer(string, string, string);
int rebuild_index();
TreeLikeIndex * get_index();
private:
TreeLikeIndex * build_index(unordered_set<string> attributes_list, int depth, string comma_separated_ids, int ids_list_count);
TreeLikeIndex * index;
string source_db_address;
string dest_folder_address;
time_t time_of_last_build;
unordered_set<string> columns_names;
string source_table_name;
unordered_set<string> temp_tables_names;
string id_column_name;
sqlite3 * source_db_connection;
int table_count;
};
int DecisionTreeLikeIndexer::rebuild_index()
{
this->index = this->build_index(this->columns_names, 0, "", 0);
this->time_of_last_build = time(NULL);
return 0;
}
TreeLikeIndex * DecisionTreeLikeIndexer::get_index()
{
return this->index;
}
DecisionTreeLikeIndexer::DecisionTreeLikeIndexer(string source_db_address, string table_name, string dest_folder_address)
{
this->source_db_address = source_db_address;
this->dest_folder_address = dest_folder_address;
this->columns_names = Aux::get_column_names(source_db_address, table_name);
this->source_table_name = table_name;
this->id_column_name = "rowid";
this->source_db_connection = Aux::get_db_connection(this->source_db_address);
// Getting count of this table
sqlite3_stmt* statement;
string query = "SELECT count(*) FROM " + this->source_table_name + ";";
if(sqlite3_prepare(this->source_db_connection, query.c_str(), -1, &statement, 0) == SQLITE_OK)
{
int res = sqlite3_step(statement);
const unsigned char * count_char = sqlite3_column_text(statement,0);
if(res == SQLITE_ROW)
{
stringstream _temp;
_temp << count_char;
_temp >> this->table_count;
}
sqlite3_finalize(statement);
}
else
{
cout << "Error initializating Indexer (Getting initial table count): " << sqlite3_errmsg(this->source_db_connection) << endl;
}
}
TreeLikeIndex * DecisionTreeLikeIndexer::build_index(unordered_set<string> attributes_list, int depth, string comma_separated_ids, int ids_list_count)
{
if( attributes_list.size() <=1 || (depth > 0 && ids_list_count <= 1))
{
Aux::tabs(depth);
cout << "Leaf at depth: " << depth << " Ids are: " << comma_separated_ids << " Ids count: " << ids_list_count << endl;
static TreeLikeIndex * node = new TreeLikeIndex((string)comma_separated_ids, (int)ids_list_count);
return node;
}
string source_table = this->source_table_name;
int count = this->table_count;
if(depth > 0)
{
while(1)
{
source_table = *Aux::get_random_list_of_strings(1).begin();
if(this->temp_tables_names.insert(source_table).second) break;
}
const string create_temp_table_stmnt = "CREATE TEMP TABLE " + source_table + " AS SELECT * FROM " + this->source_table_name + " WHERE " + this->id_column_name + " IN(" + comma_separated_ids + ")";
sqlite3_exec(this->source_db_connection, create_temp_table_stmnt.c_str(),Aux::sqlt_callback,0,NULL);
count = ids_list_count;
Aux::tabs(depth);
cout << "Not root node" << endl;
}
Aux::tabs(depth);
cout << "Source table is: " << source_table << " Table count is: " << count << endl;
Aux::tabs(depth);
cout << "Attributes list is: "; for_each(attributes_list.begin(), attributes_list.end(),[](string v){cout << v << " ";});
cout << endl;
const double E = log2(count) ;
Aux::tabs(depth);
cout << "Entropy of node: " << E << endl;
string best_attribute;
double best_gain;
unordered_set<string> best_attribute_values;
for(string attr: attributes_list)
{
Aux::tabs(depth+1);
cout << "Analysing attribute: " << attr << endl;
const string get_at_count_values_query = "SELECT " + attr + ", count(" + attr + ") FROM " + source_table + " GROUP BY " + attr + ";";
sqlite3_stmt * stmnt;
double weighted_entropy = 0;
unordered_set<string> this_att_values;
if(sqlite3_prepare(this->source_db_connection, get_at_count_values_query.c_str(), -1, &stmnt, 0) == SQLITE_OK)
{
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_DONE || res==SQLITE_ERROR)
{
double gAti = E - weighted_entropy;
Aux::tabs(depth+1);
cout << "Finish computing WE for att: " << attr << " Gain is: " << gAti << endl;
if(gAti > best_gain)
{
Aux::tabs(depth+1);
cout << "Found attribute with better gain." << endl;
best_gain = gAti;
best_attribute = attr;
best_attribute_values.clear();
Aux::tabs(depth+1);
for(string v:this_att_values)
{
best_attribute_values.insert(v);
}
cout << endl;
this_att_values.clear();
}
sqlite3_finalize(stmnt);
//delete &res;
break;
}
if(res == SQLITE_ROW)
{
string val = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
int vSize = sqlite3_column_int(stmnt,1);
Aux::tabs(depth+2);
this_att_values.insert(val);
double ratio = double(vSize) / double(count);
weighted_entropy += double(ratio) * double(log2(vSize));
Aux::tabs(depth+2);
cout << "Processing value: " << val << " With vSize: " << vSize << " Current WE is: " << weighted_entropy << endl;
}
}
}
}
Aux::tabs(depth);
cout << "Finish processing attributes list. Best attribute is: " << best_attribute << " Best gain is: " << best_gain << endl;
Aux::tabs(depth);
cout << "Best attribute values are: "; for_each(best_attribute_values.begin(), best_attribute_values.end(), [](string v){cout << v << ",";}); cout << endl;
unordered_map<string, TreeLikeIndex *> children;
for(string val: best_attribute_values)
{
const string get_ids_of_bestatt_val = "SELECT rowid FROM " + source_table + " WHERE " + best_attribute + " = " + val + ";";
int ids_count = 0;
sqlite3_stmt * stmnt;
string ids = "";
bool first = 1;
int next_depth = depth + 1;
unordered_set<string> next_attributes_set;
for(string attr: attributes_list) if(attr != best_attribute) next_attributes_set.insert(attr);
if(sqlite3_prepare(this->source_db_connection, get_ids_of_bestatt_val.c_str(), -1, &stmnt,0) == SQLITE_OK)
{
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_ROW)
{
string id = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
if(!first) ids += "," + id;
else ids += id;
ids_count++;
}
if(res == SQLITE_DONE || res == SQLITE_ERROR)
{
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: "; for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}
}
}
}
Aux::tabs(depth);
cout << "Finish processing node, will return." << endl;
static TreeLikeIndex * no_leaf_node = new TreeLikeIndex(best_attribute, "all", count, 0, children);
return no_leaf_node;
}
}
TreeLikeIndex::TreeLikeIndex(std::string attribute, std::string indices, int indices_count, short int is_leaf, unordered_map<std::string, TreeLikeIndex*> children)
{
this->attribute = attribute;
this->indices = indices;
this->is_leaf = is_leaf;
this->children = children;
this->children.clear();
for(pair<string, TreeLikeIndex*> p: children) this->children.insert(p);
this->indices_count = indices_count;
}
TreeLikeIndex::TreeLikeIndex(string indices, int indices_count)
{
this->indices = indices;
this->indices_count = indices_count;
this->is_leaf = 1;
}
TreeLikeIndex::TreeLikeIndex()
{
this->indices = "";
this->indices_count = 0;
this->is_leaf = 1;
}
int main()
{
string source_db_address = "my_table";
string table_name = "b";
string dest_folder_address = ".";
DecisionTreeLikeIndexer indexer(source_db_address, table_name, dest_folder_address);
indexer.rebuild_index();
}
And the output is:
Source table is: b Table count is: 9
Attributes list is: cant_n_dec cant_n_des cant_n_control
Entropy of node: 3.16993
Analysing attribute: cant_n_dec
Processing value: 1 With vSize: 1 Current WE is: 0
Processing value: 2 With vSize: 4 Current WE is: 0.888889
Processing value: 3 With vSize: 2 Current WE is: 1.11111
Processing value: 4 With vSize: 1 Current WE is: 1.11111
Processing value: 5 With vSize: 1 Current WE is: 1.11111
Finish computing WE for att: cant_n_dec Gain is: 2.05881
Found attribute with better gain.
Analysing attribute: cant_n_des
Processing value: 1 With vSize: 2 Current WE is: 0.222222
Processing value: 2 With vSize: 4 Current WE is: 1.11111
Processing value: 3 With vSize: 2 Current WE is: 1.33333
Processing value: 5 With vSize: 1 Current WE is: 1.33333
Finish computing WE for att: cant_n_des Gain is: 1.83659
Analysing attribute: cant_n_control
Processing value: 1 With vSize: 2 Current WE is: 0.222222
Processing value: 2 With vSize: 3 Current WE is: 0.750543
Processing value: 3 With vSize: 3 Current WE is: 1.27886
Processing value: 5 With vSize: 1 Current WE is: 1.27886
Finish computing WE for att: cant_n_control Gain is: 1.89106
Finish processing attributes list. Best attribute is: cant_n_dec Best gain is: 2.05881
Best attribute values are: 1,2,3,4,5,
Adding branch for val: 1
Next attributes are: cant_n_control,cant_n_des, Depth is: 1 Ids are: 3 Ids count: 1
Leaf at depth: 1 Ids are: 3 Ids count: 1
Segmentation fault
I'm not shure but....
I think the problem can be in the following cycle
for(;;)
{
int res = sqlite3_step(stmnt);
if(res == SQLITE_ROW)
{
string id = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
if(!first) ids += "," + id;
else ids += id;
ids_count++;
}
if(res == SQLITE_DONE || res == SQLITE_ERROR)
{
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: "; for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}
}
I don't understand when terminate (no exit conditions in the for(;;), no return's and no break's in the block).
And I suspect that che segmentation fault is caused by the following instruction
int res = sqlite3_step(stmnt);
when, after the SQLITE_DONE or SQLITE_ERROR case (whith a call to
sqlite3_finalize(stmnt);
), the cycle is iterated again, with a stmnt invalid.
The following can be a solution?
if ( sqlite3_prepare(this->source_db_connection, get_ids_of_bestatt_val.c_str(), -1, &stmnt,0) == SQLITE_OK)
{
while ( sqlite3_step(stmnt) == SQLITE_ROW )
{
ids += ( first ? "" : "," )
+ std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmnt,0)));
ids_count++;
}
Aux::tabs(depth+1);
cout << "Adding branch for val: " << val << endl;
Aux::tabs(depth+1);
cout << " Next attributes are: ";
for_each(next_attributes_set.begin(), next_attributes_set.end(), [](string v){cout << v << ",";});
cout << " Depth is: " << next_depth << " Ids are: " << ids << " Ids count: " << ids_count << endl;
sqlite3_finalize(stmnt);
static TreeLikeIndex * temp_child = this->build_index(next_attributes_set, next_depth, ids, ids_count);
pair<string, TreeLikeIndex*> child (val, temp_child);
children.insert(child);
}
I am new at coding , been coding for about a week and i am trying to do a script that finds the "?" and the "." in the script , then outputs their position in the script and i use those value to print the question to a text file.
Except it does not really work.
If you put the value in like this, it works.
myfile << test.substr( 18, 20 )
But like this it does not work it just print the whole script from the value of dot[0] until the end of the script.
myfile << test.substr( dot[0], interrogation[0] )
The way that i use to find the "?" position in the string is also not very accurate.
Where there is the .
if(x > 0){
I had a while loop but i replaced it for debugging reasons .
This is the whole code.
If you can help me i appreciate it.
Thanks.
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main (){
std::vector< int > interrogation ;
std::vector< int > dot;
string look = "?";
string look_again = ".";
string test = "ver. o que e isto? nao sei. ola? adeus. fghfghfhfghf";
string::size_type pos = test.find(look);
string::size_type sop = test.find(look_again);
string::size_type exc = test.find(look_again_again);
while (pos != std::string::npos)
{
int a = pos ;
int b = sop;
cout << " . found at : " << sop << std::endl;
cout << " ? found at : " << pos << std::endl;
interrogation.push_back(a);
dot.push_back(b);
string fragment = test.substr (0 , pos ); // works
//cout << fragment << endl ;
string fragment2 = test.substr (0 , sop ); // works
//cout << fragment2 << endl ;
pos = test.find(look, pos + 1);
sop = test.find(look_again, sop + 1);
}
int x = 1;
if(x > 0){
int a = 1;
int q = dot[a];
int w = interrogation[a];
// to save text
// to save text
string save = "saved_question.txt" ;
ofstream myfile;
myfile.open (save.c_str(), ios::app);
myfile << test.substr( 18, 20 ) + "\n" ;
myfile.close();
cout << "Question saved in text file" << endl;
}
}
The code is not finished yet but i got it working with help.
Thanks
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main (){
std::vector< int > interrogation ;
std::vector< int > dot;
//std::vector< int > exclamation;
string look = "?";
string look_again = ".";
string look_again_again = "!";
string test = " ver.o que e isto? nao sei. ola? adeus.";
string::size_type pos = test.find(look);
string::size_type sop = test.find(look_again);
while (pos != std::string::npos)
{
int a = pos ;
int b = sop;
cout << " . found at : " << sop << std::endl;
cout << " ? found at : " << pos << std::endl;
// cout << " ! found at : " << exc << std::endl;
interrogation.push_back(a);
dot.push_back(b);
//exclamation.push_back(c);
string fragment = test.substr (0 , pos ); // works
//cout << fragment << endl ;
string fragment2 = test.substr (0 , sop) ; // works
//cout << fragment2 << endl ;
string fragment3 = test.substr (dot.back() + 1, interrogation.back() - dot.back()); // works
cout << fragment3 << endl ;
pos = test.find(look, pos + 1);
sop = test.find(look_again, sop + 1);
}
}
You can do something like this:
void function(string str) {
string sentence = "";
for(int i=0; i < str.length(); i++) {
if(str[i] == '.' || str[i] == '!')
sentence = ""; // the sentence is not a question so clear the sentence
else if(str[i] == '?') {
sentence.push_back(str[i]);
cout << sentence << endl; // output the question - just replace cout with your ofstream
}
else
sentence.push_back(str[i]);
}
}
I think I've seen this question before though..
Working on a project where I am supposed to load a file based on user input, convert the data in that file into coordinates in the window and then use ASCII characters to draw a picture.
Files are in .art and start with the width and height of the window needed and each subsequent line is the ROW, COLUMN, CHARACTER, and COUNT that needs to be drawn. So basically the position the particular character should be started at and then how many times it should be drawn.
What I am struggling with is how to import that data into something usable so as I can draw the requested image. My initial thought is to import the data as a 4-D array but then I draw a blank as to where I should go from there.
Example lines for a .art file:
50 x 25
2, 15, *, 9
2, 48, *, 9
3, 6, *, 15
UPDATE: Given up on trying to load the files since I just can't wrap my head around that so I've changed to just drawing the art by hand and calling a string but I'm even having issues with that. With my code below, if I select option 1 the output is 001FFA80 rather than outputting the ASCII art that is in the string.
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
int main ()
{
string shapeCupid[]=
{" ",
" .. ",
" $. ,o$$$o. ",
" $. $$$$$$$o. .. ",
" .$. $' $$$$$$ ,o'' ",
" .$' $ '$$$$$,o'.,' .oo ' ",
" .$' $. $$$$' ,, .o'. ",
" .$' '$o. 'O$ .. ooo''',oo ' ",
" .$' .o$' '$$'' ,,o' ",
" .%$,,,,,ooO' ' ,,o'' ",
" .$o. ,o' $o ..oo' ",
" ''O'''''''''',' $'$. .o' "};
string shapeFly = "Fly";
string shapeHeart = "Heart";
string shapeImpossible = "Impossible";
string shapeSeuss = "Seuss";
string shapeWorry = "Worry";
int UserInput;
cout << "What do you want to draw?\n";
cout << "1. Cupid\n2. Fly\n3. Heart\n4. Impossible\n5. Seuss\n6. Worry\nNumber: ";
cin >> UserInput;
if (UserInput == 1){
cout << shapeCupid;}
else if (UserInput == 2){
cout << shapeFly;}
else if (UserInput == 3){
cout << shapeHeart;}
else if (UserInput == 4){
cout << shapeImpossible;}
else if (UserInput == 5){
cout << shapeSeuss;}
else if (UserInput == 6){
cout << shapeWorry;}
else if (UserInput != 1 || 2 || 3 || 4 || 5 || 6)
cout << "Please select proper value.\n";
system("pause");
return 0;
}
Here's a quick and dirty version that might help. I didn't add a ton of error checking, but it works for the 2 examples I used. If you do plan to embed the data as string literals you'll want to be sure to escape any special characters like backslash and double quotes. The Boop example has both.
For the embedded string literal data the first line must be padded to be as long as the longest line since it is used to write the width. An enhancement would be to iterate through all lines to get the max width and use that.
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
using StringVec = std::vector<std::string>;
StringVec shapeCupid =
{
" ",
" .. ",
" $. ,o$$$o. ",
" $. $$$$$$$o. .. ",
" .$. $' $$$$$$ ,o'' ",
" .$' $ '$$$$$,o'.,' .oo ' ",
" .$' $. $$$$' ,, .o'. ",
" .$' '$o. 'O$ .. ooo''',oo ' ",
" .$' .o$' '$$'' ,,o' ",
" .%$,,,,,ooO' ' ,,o'' ",
" .$o. ,o' $o ..oo' ",
" ''O'''''''''',' $'$. .o' "
};
//Borrowed from http://www.chris.com/ascii/index.php?art=cartoons/betty%20boop
StringVec boop =
{
" _(,__ __), ",
" (_,d888888888b,d888888888b",
" d888888888888/888888888888b_)",
" (_8888888P'\"\"'`Y8Y`'\"\"'\"Y88888b",
" Y8888P.-' ` '-.Y8888b_)",
" ,_Y88P (_(_( )_)_) d88Y_,",
" Y88b, (o ) (o ) d8888P",
" `Y888 '-' '-' `88Y`",
" ,d/O\\ c /O\\b,",
" \\_/'.,______w______,.'\\_/",
" .-` `-.",
" / , d88b d88b_ \\",
" / / 88888bd88888`\\ \\",
" / / \\ Y88888888Y \\ \\",
" \\ \\ \\ 88888888 / /",
" `\\ `. \\d8888888b, /\\\\/",
" `.//.d8888888888b; |",
" |/d888888888888b/",
" d8888888888888888b",
" ,_d88p\"\"q88888p\"\"q888b,",
" `\"\"'`\\ \"`| /`'\"\"`",
" `. |===/",
" > | |",
" / | |",
" | | |",
" | Y /",
" \\ / /",
" jgs | /| /",
" / / / |",
" /=/ |=/"
};
void Write(const std::string& filename, StringVec& data)
{
if(data.empty())
{
return;
}
std::ofstream out(filename);
if(out)
{
out << data[0].size() << " x " << data.size() << "\n";
for(size_t row = 0; row < data.size(); ++row)
{
const std::string& line = data[row];
size_t col_start = 0;
size_t col_end = 0;
char col_char = line[0];
for(size_t col = 0; col < line.size(); ++col)
{
//If we hit a new character write the previous run to the file
if(col_char != line[col])
{
//but only if it wasn't a run of spaces.
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
col_char = line[col];
col_start = col;
col_end = col;
}
col_end = col;
}
//write the last run
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
}
}
}
StringVec Read(const std::string& filename)
{
StringVec data;
std::ifstream in(filename);
if(in)
{
char dummy;
size_t width;
size_t height;
if(in >> width >> dummy >> height)
{
data.resize(height, std::string(width, ' '));
}
if(!data.empty())
{
size_t row;
size_t col;
char ch;
size_t len;
while(in >> row >> dummy >> col >> dummy >> ch >> dummy >> len)
{
for(size_t i = col; i < col + len; ++i)
{
data[row][i] = ch;
}
}
}
}
return data;
}
void Print(const StringVec& data)
{
for(const std::string& s : data)
{
std::cout << s << "\n";
}
std::cout << "\n";
}
int main()
{
Write("cupid.art", shapeCupid);
Print(Read("cupid.art"));
Write("boop.art", boop);
Print(Read("boop.art"));
return 0;
}