binary search string 2d arrays - c++

My question is to find the string in 2d array and if it match display binary no.
Pience of my cide
string inst[37][3]={{"ld","00001","C2"},{"st","00011","C2"},{"la","00101","C2"},{"ldr","00010","C1"},
{"lar","00110","C1"},{"str","00100","C1"},{"add","01100"," "},{"addi","01101","C2"},
{"sub","01110"," "},{"neg","01111"," "},{"or","10110"," "},{"ori","10111","C2"},
{"and","10100"," "},{"andi","10101","C2"},{"not","11000"," "},{"shr","11010","C3"},
{"shra","11011","C3"},{"shl","11100","C3"},{"shc","11101","C3"},{"br","01000","C3"},
{"brl","01001","C3"},{"brlnv","01001"," "},{"brzr","01000"," "},{"brlzr","01001"," "},
{"not","11000"," "},{"brnz","01000"," "},{"brlnz","01001"," "},{"brpl","01000"," "},
{"brmi","01000"," "},{"brlmi","01001"," "},{"nop","00000"," "},{"stop","11111"," "},
{"een","01010"," "},{"edi","01011"," "},{"rfi","11110"," "},{"svi","10000"," "},
{"ri","10001"," "}};
int last=36, initial=0 , mid, index;
for(int i = 0; i < icount-1; i++)
{
//display arrays
for(int j = 0; j < 4;j++)
{
cout << input[i][j] << " ";
// this is for check first column that consist inst and then convert to binary code
if(j==0)
{
while(last>=initial)
{
mid=(last+initial)/2;
if(input[i][0]==inst[mid][0])
{ index=mid;
}
else if(input[i][0]>inst[mid][0])
{ initial=mid+1;
}
else
last=mid-1;
}
cout<<" "<<inst[index][1]<<" ";
}
}
it's like output not display the correct binary code. Any kind of help I'm really appreciated.
Thanks you.
* I don't want to use return mid and create another function

Your search would be soooo much simpler if you reorganized your data:
struct Data_Record
{
string command;
string value;
string other;
// Here's what makes the search work better:
bool operator==(const Data_Record& dr)
{
bool is_equal = false;
if (command == dr.command)
{
if (value == dr.value)
{
if (other == dr.other)
{
is_equal = true;
}
}
}
}
bool operator<(const Data_Record& dr)
{
return command < dr.command;
}
};
const Data_Record inst[37] = { /* ... */};
Data_Record const * p_item_found = NULL;
Data_Record key = {"and", "", ""};
p_item_found = std::binary_search(&inst[0], &inst[38], key);
if (p_item != &instr[38])
{
cout << "Found it\n";
}
else
{
cout << "Item not found.\n";
}
You can do other cool stuff like overloading operator<< and operator>> for custom output and input.
Edit 1: OOP hierarchy
Many instruction sets have groups that share commonality. For example, jump or branch instructions all have a destination address. Math instructions may have the same operands.
I recommend having a hierarchy of classes (or structures). Research "C++ Factory Design Pattern".
class Instruction
{
public:
virtual void Print_Annotated(std::ostream& output) = 0;
virtual void Instruction_Counter Execute(void) = 0;
protected:
std::string opcode;
std::string instruction_value;
};
class Jump_Instr_Category : public Instruction
{
protected:
unsigned int destination_address;
};
class Math_Instr_Category : public Instruction
{
protected:
std::string parameter1;
std::string parameter2;
};
You use the Factory Pattern to return a pointer to the Instruction base class.
The User's program would be a simple as:
std::vector<Instruction *> program;

Related

Setter not changing the data from a vector within a class

In my program, I have a class that holds a vector of type integer. It is used to store distances. I have a function, that when called, should set values in the vector to 0's. (used for initializing). But when I go to check the size of the vector, it still says the vector is empty.
I have created multiple functions that check whether the vector is adding any elements, and it is not. I have a function, that within main, I call to see if the vector is empty, and it returns 0 (the vector has 0 elements in it).
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
The input file is a csv file with each line consisting of:
stadium1,stadium2,distance
so sample input file is:
AT&T Park,Safeco Field,680
AT&T Park,Oakland–Alameda County Coliseum,50
Angel Stadium,Petco Park,110
Angel Stadium,Dodger Stadium,50
Busch Stadium,Minute Maid Park,680
Busch Stadium,Great American Ball Park,310
Busch Stadium,Target Field,465
Busch Stadium,Kauffman Stadium,235
etc...
I am using qt, and this is where I am calling the functions themselves. All information is stored into a map, and the other getters work perfectly fine. Sorry for making this a lot more confusing than the problem really is, any help is greatly appreciated.
// key and value, key is the team name, value is the MLB stadium information
struct entry
{
string key;
MLB value;
};
class Map
{
public:
//Public default constructor
Map();
//Public default destructor
~Map();
// returns entry of the map
entry atIndex(int index);
// Inserts a key and its value using linear algorithm
void insert(const string& theKey, const MLB& value);
private:
vector<entry> thisTable;
int currentSize; //Integer variable for current size
};
functions for Map:
Map::Map()
{
currentSize = 0;
}
Map::~Map()
{
}
void Map::insert(const string& theKey, const MLB& value)
{
entry thisEntry;
thisEntry.key = theKey;
thisEntry.value = value;
thisTable.push_back(thisEntry);
currentSize+=1;
}
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
//mainwindow constructor
mainWindow::mainWindow()
{
//Reads in input from first csv file, all works fine all data stored and can access it
string iStadium1;
string iStadium2;
string iDistance;
string previous;
int distance;
int index1;
int index2;
bool found;
ifstream csvFile2;
csvFile2.open("inputDistance.csv");
getline(csvFile2, iStadium1, ',');
while(!csvFile2.eof())
{
index1 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index1).value.getStadiumName() == iStadium1)
{
thisMap.atIndex(index1).value.setInitialDistances(thisMap.mapSize());
cout << "Distance Size Test 1: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
found = true;
}
else
{
index1++;
}
}
previous = iStadium1;
while(iStadium1 == previous)
{
getline(csvFile2, iStadium2, ',');
getline(csvFile2, iDistance, '\n');
distance = stoi(iDistance);
index2 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index2).value.getStadiumName() == iStadium2)
{
found = true;
cout << "Distance Size Test 2: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
// crashes here. Index out of bounds, size is 0 for some reason
thisMap.atIndex(index1).value.setDistance(index2, distance);
}
else
{
index2++;
}
}
getline(csvFile2, iStadium1, ',');
}
}
csvFile2.close();
}
I expect the vector to hold 30 slots (assuming the desired size passed into the function is 30) of value 0, rather than having an empty vector.
The code in your question works as expected after adding constructor and destructor (doing both nothing) :
#include <iostream>
#include <vector>
using namespace std;
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
MLB::MLB() {
}
MLB::~MLB() {
}
int main()
{
MLB mlb;
mlb.setInitialDistances(30);
cout << mlb.getDistanceSize() << endl;
}
pi#raspberrypi:/tmp $ g++ d.cc
pi#raspberrypi:/tmp $ ./a.out
30
the vector is not empty but contains 30 times 0
if thisMap.atIndex(index1).value.setDistance(index2, distance); does nothing this is probably because atIndex(index1) returns a copy rather than a reference, so you modify a copy and the original is unchanged
For instance :
#include <iostream>
#include <vector>
using namespace std;
class C {
public:
vector<int> getv() { return v; } // return a copy
vector<int> & getvref() { return v; } // return the ref to the vector, not a copy
int len() { return v.size(); }
private:
vector<int> v;
};
int main()
{
C c;
c.getv().push_back(0); // modify a copy of v
cout << c.len() << endl;
c.getvref().push_back(0); // modify v
cout << c.len() << endl;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ vv.cc
pi#raspberrypi:/tmp $ ./a.out
0
1
you edited you question and this is what I supposed :
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
return a copy, must be
entry & Map::atIndex(int index)
{
return thisTable.at(index);
}

Using Member Functions to Print Object

I have a class that contains a tree structure implemented by a vector< vector< Node > > where Node contains a bunch of attributes exposed via getters/setters.
class Tree
{
vector< vector< Node > > mGrid;
printTree(std::ostream& output = std::cout);
};
class Node
{
double property1 { return mProp1; }
double property2 { return mProp2; }
};
printTree() is currently hardwired to use property tstep:
void Tree::printTree( ostream& output )
{
...
for (unsigned t = 0; t < mGrid.size(); ++t)
{
toPrint = "";
for (unsigned state = 0; state < mGrid[t].size(); ++state)
{
toPrint += to_string_with_precision( mGrid[t][state].tstep(), 1 );
...
Is there some slick / convenient / object-oriented way of generalizing this function so that it can print out any of Node's properties (rather than only spitting out the hardwired tstep() property or essentially doing the same thing via if/then statements).
I've done things like this in C using function pointers, but this is C++ and the C++ FAQ says not to mess with pointers to member functions.
You might want template function:
class Tree
{
vector< vector< Node > > mGrid;
public:
template <typename F>
void ForEachNode(F&& f) {
int i = 0;
for (auto& v : mGrid) {
int j = 0;
for (auto& node : v) {
f(node, i, j);
++j;
}
++i;
}
}
};
Then you may do
void printTreeProp1(Tree& tree) {
tree.ForEachNode([](const Node& node, int i, int j) {
if (i != 0 && j == 0) {
std::cout << std::endl;
}
std::cout << node.property1() << " ";
});
}
1st op all you loops are ignoring the first element. vector is zero based and you are using ++t and ++state which increases the values on top of the loop. That means you are never accessing the 0th element (mGrid[0] and mGrid[t][0]).2nd, you did noy include the definition of tstep(), so we don't know what you are getting back. Assuming you want to print each dimension of your 2 dimension array, I think you have to break it to peaces. Something like this:
class Node
{
protected:
double mProp1;
double mProp2;
public:
double GetProp1(void) {return mProp1;}
double GetProp2(void) {return mProp2;}
String tStep(void) {return L"";} // add your code here
};
class NodeRow : public std::vector<Node>
{
public:
void Print(std::ostream& output)
{
iterator i;
String tStr;
for(i = begin(); i != end(); i++)
tStr += /*to_string_with_precision(*/i->tStep()/*, 1)*/;
output << tStr.c_str() << L"\r\n";
}
};
class Node2D : public std::vector<NodeRow>
{
public:
void Print(std::ostream& output = std::cout)
{
iterator i;
for(i = begin(); i != end(); i++)
i->Print(output);
}
};

C++ Indexing structs

I'm wondering if there is a way to index structs in order to run through the member variables in a for-loop. I'm asking repeatingly for stuff and get input via cin>>:
struct Fruits {
string name;
int weight, diameter, prize;
string colour, smell, taste;
}apple;
cout << "Apple Name?"; cin >> apple.name;
cout << "Apple weight?"; cin >> apple.weight;
.
.
you get the idea. I want sth like
vector<string> questions {"Apple Name?", "Apple weight?", ... };
for (int j = 0; j < "StructureSize of Fruits"; j++)
{
cout << questions[j]; cin >> apple.j; //apple.j is the key point I want to know
}
thank you very much!
you can't.
Arrays access works on the following way.
int A[4];
A[0] = 5;
A[1] = 7;
A[3] = 8;
You know a int (in some archytectures) use 4 bytes. So, the first element of A is in the address A, the next element of A is in the address A+4 what is equal to say A+sizeof(int)
When you do the first assignment A[0] the code is really something like A+sizeof(int)*0, in the next A[1] is something like A+sizeof(int)*1 If you see, any adjacent space of the array sums 4 bytes ( or sizeof(int) ) and goes on. If you see, you know that A have integers inside of it and you know the pattern to access each element the general pattern in a for loop would be A+sizeof(int)*j in your struct you don't know what is inside, you can't do A+sizeof(X)*j becouse X isn't fixed, so, if you want to do that you must implement it yourself, but It would be a pain becouse you have mixed datatypes.
If your struct is fixed, the strings for the user should also be fixed, then why you try to print them from a loop?, The vector need to allocate and that use spaces and gpu, I think is better if you just print each option and then read the user input.
You can.
But not without overkilling it.
#include <string>
#include <iostream>
#include <memory>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
struct Fruit {
std::string name;
int weight, diameter, price;
std::string colour, smell, taste;
};
BOOST_FUSION_ADAPT_STRUCT(
Fruit,
(std::string, name)
(int, weight)
(int, diameter)
(int, price)
(std::string, colour)
(std::string, smell)
(std::string, taste)
)
std::array<char const *const, 7> questions = {
"Name ?",
"Weight ?",
"Diameter ?",
"Price ?",
"Colour ?",
"Smell ?",
"Taste ?"
};
int main() {
Fruit apple;
auto input = [i = std::size_t{0u}](auto &field) mutable {
do {
std::cout << questions[i] << ' ';
} while(!(std::cin >> field));
++i;
};
boost::fusion::for_each(apple, std::ref(input));
std::cout << "----------\n";
auto output = [i = std::size_t{0u}](auto const &field) mutable {
std::cout << questions[i] << ' ' << field << '\n';
++i;
};
boost::fusion::for_each(apple, std::ref(output));
}
I just learned that boost::fusion::for_each can't accept a mutable functor, hence the weird and a bit dangerous use of std::ref()... It's a shame, really.
Output :
Name ? Apple
Weight ? 150
Diameter ? 8
Price ? 1
Colour ? red
Smell ? good
Taste ? sweet
----------
Name ? Apple
Weight ? 150
Diameter ? 8
Price ? 1
Colour ? red
Smell ? good
Taste ? sweet
enum FruitValueProperty { weight=0, diameter, prize, lastValueProperty };
enum FruitStringProperty { name=0, colour, smell, taste, lastStringProperty };
struct Fruit {
int ValueProperty[3];
string StringProperty[4];
int Weight() { return ValueProperty[weight]; }
int Diameter() { return ValueProperty[diameter]; }
int Prize() { return ValueProperty[prize]; }
string Name() { return StringProperty[name]; }
string Colour() { return StringProperty[colour]; }
string Smell() { return StringProperty[smell]; }
string Taste () { return StringProperty[taste ]; }
};
Fruit fruit;
vector<string> questions {"Fruit weight?", ... "Fruit name?", ... };
for (int i=0; i<lastValueProperty; i++) {
cout << questions[j];
cin >> fruit.ValueProperty[i];
}
for (int j=0; i<lastStringProperty; i++) {
cout << questions[lastValueProperty+j];
cin >> fruit.StringProperty[j];
}
int dim = fruit.Diameter();
string sm = fruit.Smell();
If you used enums for the string properties (limiting the scope of what the values could be i.e an enum for names, enum for colors etc) then you could get your result by condensing the two loops down to one.
Alternatively you could have set property for the int values that takes a string and parses it to int and go that route but I honestly thing the above is the simplest and clearest means to almost achieve what you want.
This is my take on the matter using just vanilla c++ and evil macros and casts. Still definitely overkill though.
The basic plan is to provide an operator[] to return a variant-type proxy class which in turn handles the io streams.
This interface allows you the ability to expose the class members as you choose and in the order you want.
In order not to repeat myself and to avoid having the burden of keeping things in sync I declare the fields I want in a separate header and include the header twice but changing the macro between includes. If I now add a new field or remove one then I only have to change one place.
fruit_fields.h
//NO Header Guards desired since we want to include multiple times
DECLARE_FIELD(std::string, Fruit, name)
DECLARE_FIELD(int, Fruit, weight)
DECLARE_FIELD(int, Fruit, diameter)
DECLARE_FIELD(int, Fruit, prize)
DECLARE_FIELD(std::string, Fruit, colour)
DECLARE_FIELD(std::string, Fruit, smell)
DECLARE_FIELD(std::string, Fruit, taste)
Utility Classes
#include <iostream>
#include <string>
#include <assert.h>
#include <vector>
#include <array>
#include <typeinfo>
//TypeId info
namespace FieldType
{
static const size_t String = typeid(std::string).hash_code();
static const size_t Integer = typeid(int).hash_code();
};
/*
Field Proxy is a simple variant class
If you want to support more field types then more code is needed
*/
class FieldProxy
{
public:
FieldProxy(int* value)
: m_typeHash( typeid(int).hash_code() )
, m_intValue(value)
{}
FieldProxy(std::string* value)
: m_typeHash(typeid(std::string).hash_code())
, m_stringValue(value)
{}
operator int() const
{
assert(m_typeHash == typeid(int).hash_code());
return *m_intValue;
}
operator std::string() const
{
assert(m_typeHash == typeid(std::string).hash_code());
return *m_stringValue;
}
friend std::ostream& operator<<(std::ostream& os, const FieldProxy& field);
friend std::istream& operator>>(std::istream& os, FieldProxy& field);
private:
size_t m_typeHash;
union
{
int* m_intValue;
std::string* m_stringValue;
};
};
std::ostream& operator<<(std::ostream& os, const FieldProxy& field)
{
if (field.m_typeHash == FieldType::Integer)
{
os << *(field.m_intValue);
}
else if (field.m_typeHash == FieldType::String)
{
os << *(field.m_stringValue);
}
return os;
}
std::istream& operator>>(std::istream& is, FieldProxy& field)
{
if (field.m_typeHash == FieldType::Integer)
{
is >> *(field.m_intValue);
}
else if (field.m_typeHash == FieldType::String)
{
is >> *(field.m_stringValue);
}
return is;
}
//data to obtain pointer to given field
struct FieldInfo
{
size_t fieldType;
size_t offset;
};
Fruit Class
//The struct we actually care about
struct Fruit
{
public:
static size_t getNumberFields()
{
return m_numberFields;
}
FieldProxy operator[](size_t index);
private:
//First include just declares the class members as you might expect
// string name;
// int weight; etc
#define DECLARE_FIELD(t, c, f) t f;
#include "fruit_fields.h"
#undef DECLARE_FIELD
static FieldInfo m_fields[];
static const size_t m_numberFields;
};
//Work out where the fields are positioned in the class
FieldInfo Fruit::m_fields[] =
{
//second time around - define the macro to generate the data
//needed to build the FieldProxy
#define DECLARE_FIELD( t, c, f) {typeid(t).hash_code(), offsetof(c,f)},
#include "fruit_fields.h"
#undef DECLARE_FIELD
};
//calculate how many fields there are
const size_t Fruit::m_numberFields = sizeof(Fruit::m_fields) / sizeof(Fruit::m_fields[0]);
//Index to a FieldInfo object and use it to create a FieldProxy variant
FieldProxy Fruit::operator[](size_t index)
{
assert(index < m_numberFields);
auto& fieldInfo = m_fields[index];
if (fieldInfo.fieldType == FieldType::Integer)
{
return FieldProxy(reinterpret_cast<int*> (reinterpret_cast<char*>(this) + fieldInfo.offset));
}
else if (fieldInfo.fieldType == FieldType::String)
{
return FieldProxy(reinterpret_cast<std::string*> (reinterpret_cast<char*>(this) + fieldInfo.offset));
}
else
{
assert(false);
return FieldProxy((int*)nullptr);
}
}
Main
You can now index in to the fruit class quite simply:
int main()
{
Fruit apple;
std::array<std::string, 7> questions = {
"Name ?",
"Weight ?",
"Diameter ?",
"Price ?",
"Colour ?",
"Smell ?",
"Taste ?"
};
assert(questions.size() == Fruit::getNumberFields());
for (size_t index = 0; index < Fruit::getNumberFields(); ++index)
{
bool succeeded = false;
do {
std::cout << questions[index] << ' ';
if (!(std::cin >> apple[index]))
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<int>::max(), '\n');
}
else
{
succeeded = true;
}
} while (!succeeded);
}
std::cout << "----------" << std::endl;
for (size_t index = 0; index < Fruit::getNumberFields(); ++index)
{
std::cout << questions[index] << ' ' << apple[index] << std::endl;
}
return 0;
}
OK it is long since the thread was started.
For indexing a Struct with values of same type I have written this code:
struct DataValues
{
int Value1;
int Value2;
int Value3;
int Value4;
int Value5;
int Value6;
int Value7;
int Value8;
// the operator
// return the reference to make it settable.
int& operator[](int n)
{
// the idea, get the pointer of the first element
// and treat it as an array
return (&Value1)[n];
}
};
usage:
int main()
{
DataValues values;
values.Value4 = 6;
values[1] = 3;
values[0] = sizeof(DataValues);
return 0;
}
The downside is that you have to check the input parameter to avoid accessing memory which does not belong to the struct.
Chears

STXXL Dealing with strings

i am dealing with large dataset. May i ask you how it is possible to store strings in the classes i want to use with stxxl? I have read several discussions and everywhere was said that string is not POD type therefore it cannot be stored in the stxxl::vector, but i am not sure,because i tried it and i checked the data and everything seems to be fine. i have also saw an approach here https://github.com/Project-OSRM/osrm-backend/blob/725b93a961625a7b04d54806d7e0f80252a6bcd0/extractor/extraction_containers.hpp and they use stxxl::vector, so maybe the library got updated to support std::string?
class HighWay
{
private:
uint64_t id;
string name;
int speed;
string attributes; //additional attributes of way
string edges; //written uint64_t from,uint64_t to, int distance written as string
string nodes; //vector<uint64_t> written as string
public:
HighWay() = default;
void setId(uint64_t _id) {
id = boost::lexical_cast<string>(_id);
}
void setName(string _name) {
name = _name;
}
void setSpeed(int _speed) {
speed = _speed;
}
void setAttributes(string _attributes) {
attributes = _attributes;
}
void setEdges(string _edges) {
edges = _edges;
}
void setNodes(vector<uint64_t>refs) {
stringstream s;
uint64_t i = 0;
for (; i < refs.size()-1;i++) {
s << boost::lexical_cast<uint64_t>(refs[i]) << " ";
}
s << boost::lexical_cast<uint64_t>(refs[i]);
nodes = s.str();
}
uint64_t getId() {
return id;
}
string getName() {
return name;
}
int getSpeed() {
return speed;
}
string getAttributes() {
return attributes;
}
string getEdges() {
return edges;
}
std::vector<int64_t> getNodes() {
stringstream s(nodes);
uint64_t node;
std::vector<int64_t> result;
while (s >> node) {
result.push_back(static_cast<int64_t>(node));
}
return result;
}
};
I have also created code which stores the strings as POD,storing the string in vector of char and in map remembering lower and upper bound index in the array. But this approach leads to many std::maps used in the application.
//class to store in map
struct TypeName{
uint64_t start;
uint64_t end;
};
std::istream& operator >> (std::istream& i, TypeName& entry)
{
i >> entry.start;
i >> entry.end;
return i;
}
std::ostream& operator << (std::ostream& i, const TypeName& entry)
{
i << entry.start << " ";
i << entry.end;
return i;
}
struct PoiCategories{
uint64_t start;
uint64_t end;
};
std::istream& operator >> (std::istream& i,PoiCategories& entry)
{
i >> entry.start;
i >> entry.end;
return i;
}
std::ostream& operator << (std::ostream& i, const PoiCategories& entry)
{
i << entry.start << " ";
i << entry.end;
return i;
}
//object i want to store
struct Poi {
Poi() = default;
uint64_t id;
char type;
uint64_t id_in_pois; //id in vector pois
void addCategories(
vector<int> &kats, //categories to insert
stxxl::vector<uint64_t> &categories, //vector to store category
std::unordered_map <uint64_t, PoiCategories> &idPoi_categories //index to vector categories to retrieve all categories for Poi
)
{
size_t start = categories.size();
for (auto & kat : kats) {
categories.push_back(kat);
}
size_t end = categories.size() - 1;
idPoi_categories.insert(make_pair(id, PoiCategories{start, end }));
}
vector<int> getCategories(
stxxl::vector<uint64_t> &categories,
std::unordered_map <uint64_t, PoiKategorie> &idPoi_categories
)
{
std::vector<int> result;
PoiCategories bounds = idPoi_categories.find(id)->second;
for (size_t i = bounds.start; i <= bounds.end; i++) {
result.push_back(categories[i]);
}
return result;
}
};
Problem in my application is that i am storing a few string data, which are mainly names of streets and POIs. Maybe i am using wrong library. If so,can you recommend me a better approach to store data while preprocessing?
It's indeed banned, but the symptoms of violating the no-POD rule are generally unpredictable. It may very well appear to work as long as the strings all fit in memory, but in that case you didn't need the STXXL anyway.

Outputting a vector of of lists in C++

I'm having trouble outputting my vector of lists:
class index_table {
public:
index_table() { table.resize(128);}
void insert(string &, int );
private:
class entry
{
public:
string word;
vector <int> line;
};
vector< list <entry> > table;
};
I've got it so that it will fill up:
int main ()
{
index_table table;
string word,
int num = 5; //this is going to a random number. 5 is a temp. place holder.
while (cin >> word)
table.insert(word, num);
}
but how to output it? I've tried many different approaches, but a lot of them are giving me errors.
Do I have to overload the operator? I'm not entirely sure how I will be able to do it.
Assuming you really have a good reason to use std::vector< std::list<entry> >, then based on the given structure, printing of words might look like this:
class index_table {
public:
void print() {
for (size_t i = 0; i < table.size(); ++i) {
std::list<entry>::iterator li;
for (li = table[i].begin(); li != table[i].end(); ++li)
std::cout << li->word << " ";
}
}
...
private:
std::vector< std::list<entry> > table;
...
};
If your compiler supports C++11, you can use two range based nested for loops. Look in the function void index_table::dump().
// Output function
void index_table::dump() {
for (list<entry> &le : table) {
for (entry &e : le) {
e.dump();
}
}
}
I also created a function dump() in the entry class, which outputs the contents of two variables, which is now made private.
class index_table {
public:
index_table() {
table.resize(128);
}
void insert (int,string&,int);
void dump();
private:
class entry {
private:
string word;
int value;
public:
entry (string word, int value) {
this->word = word;
this->value = value;
}
void dump() {
cout << "Word/value is: " << word << "/" << value << endl;
}
};
vector< list <entry> > table;
};
void index_table::insert(int c, string &key, int value) {
//void index_table::insert(string &key, int value) {
entry obj(key, value);
table[c].push_back(obj);
}
// Output function
void index_table::dump() {
for (list<entry> &le : table) {
for (entry &e : le) {
e.dump();
}
}
}
int main (int argc, char **argv) {
index_table mytable;
string a = "String 0-A";
string b = "String 0-B";
string c = "String 1-A";
string d = "String 1-B";
string e = "String 6-A";
string f = "String 6-B";
mytable.insert(0, a, 1);
mytable.insert(0, b, 2);
mytable.insert(1, c, 3);
mytable.insert(1, d, 4);
mytable.insert(6, e, 3);
mytable.insert(6, f, 4);
mytable.dump();
}
Program outputs:
Word/value is: String 0-A/1
Word/value is: String 0-B/2
Word/value is: String 1-A/3
Word/value is: String 1-B/4
Word/value is: String 6-A/3
Word/value is: String 6-B/4
PS: I also changed your code a bit to make it run more easily for my test.
//This is the simple solution for outputting vector of lists.
#include <bits/stdc++.h>
using namespace std;
main()
{
vector<list<int>> my_vector; //creating vector of lists;
list<int> my_list;
for(int i = 0; i < 5; i++)
my_list.push_back(i);
my_vector.push_back(my_list); // pushing a list y to a vector
for (vector<list<int>>::iterator it = my_vector.begin(); it != my_vector.end(); ++it)
for (list<int>::iterator it2 = it->begin(); it2 != it->end(); ++it2)
cout << *it2 << ", ";
}