Bridesearch implementation with c++ - c++

std::string Breitensuche ( std::array < std::list<std::array<int, 2>>, 3> list, int von, int zu ,std::string weg)
{
std::list<int> markiert;
for ( auto &b : list.at(von) )
{
if ( b.at ( 0 ) == zu )
return
weg += std::to_string ( b.at ( 0 ) );
else
markiert.push_back ( b.at ( 0 ) );
}
for ( auto &a : markiert )
{
Breitensuche ( list, a.at ( 0 ), zu );
}
return "";
}
int main ( )
{
std::array < std::list<std::array<int, 2>>, 3> Adjazenzliste { { { { { 0, 5 } } }, { { { 0, 5 } }, { { 2, 7 } } }, { { { 1, 4 } } } } };
std::cout << Breitensuche ( Adjazenzliste, 1, 2 ,"");
system ( "Pause" );
}
I was trying to implement bridesearch of graphs with c++ with adjazenzlists.
the first part of the arrays which are hold in the list which are hold in arrays are the name of the node to which the startnode of the list has a connection and the second is the weight of the connection.
So basicly in this initalization there are 3 lists
0 -> 1
1 -> 0 -> 2
2 -> 1
In the function above a tried that first of all every element of the list gets checked and if its not the searched node it gets marked and after this the function gets called for every marked spot again and again, if its found it returns the nodename.
I am encountering problems with not getting into depthsearch cause if i do it recursive it will allways first check it deep and then do the next...
Furthemore i have problems to safe the "path" if its found and return it...
I hope you understand what i mean, sorry for my bad english

The Breadth-first search algorithm described on Wikipedia doesn't require recursiveness. The pseudocode talks about a queue q for the ordering and a set V (capital V) to make sure duplicate values get matched only once (which I have left out in the code below):
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
template<class T>
struct tree_item {
T value;
vector<tree_item<T>> children;
tree_item(T value) : value(value) {}
};
// constructs animated gif http://en.wikipedia.org/wiki/Breadth-first_search
tree_item<string> build_tree() {
tree_item<string> a("a"), b("b"), c("c"), d("d"), e("e"), f("f"), g("g"), h("h");
e.children = { h };
b.children = {d, e};
c.children = {f, g};
a.children = {b, c};
return a;
}
// implements "Algorithm" -> "Pseudocode" http://en.wikipedia.org/wiki/Breadth-first_search
template<class T>
bool find_breadth_first(const tree_item<T>& v, function<bool(const T&)> matcher, tree_item<T>& found_item) {
queue<const tree_item<T>*> q; // step 2
q.push(&v); // step 5
while(!q.empty()) { // step 6
auto t = q.front(); q.pop(); // step 7
cout << "currently visiting " << t->value << endl;
if(matcher(t->value)) { // step 8
cout << t->value << " is a match " << endl;
found_item = *t; return true; // step 9
}
for(auto& u : t->children) // step 11
q.push(&u); // step 15
}
return false; // step 19
}
int main() {
auto root = build_tree();
tree_item<string> match("no match");
auto matcher = [&](auto candidate) {
return candidate == "g";
};
auto found = find_breadth_first<string>(root, matcher, match);
if(found)
cout << "found: " << match.value << endl;
else
cout << "not found" << endl;
}
Output:
currently visiting a
currently visiting b
currently visiting c
currently visiting d
currently visiting e
currently visiting f
currently visiting g
g is a match
found: g

Related

How to encapsulate custom iterator in function using boost-range

Lately I was using boost-range to create ranges over elements satisfying certain criteria. In all cases I'm using the same kind of filtered range all the time, so that I tried to encapsulate this behaviour in an external function.
This was the point where my problems started. Consider the following example.
#include <boost/range/adaptor/filtered.hpp>
#include <iostream>
#include <vector>
auto myFilter = [](const std::vector<int>& v, int r) {
return v | boost::adaptors::filtered([&r](auto v) { return v%r == 0; });
};
int main(int argc, const char* argv[])
{
using namespace boost::adaptors;
std::vector<int> input{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto& element : input | filtered([](auto v) {return v % 2 == 0; } ))
{
std::cout << "Element = " << element << std::endl;
}
std::cout << std::endl;
for (auto& element : myFilter(input,4))
{
std::cout << "Element = " << element << std::endl;
}
return 0;
}
The first for-loop behaves as expected printing 4 and 8. The second for-loop however prints just 4. Why is that?
My second idea was to implement a class having a begin() and end() function. This should be a thin wrapper around a range object.
This was the solution, after fiddling out the type of the range iterator.
struct MyFilter {
MyFilter(const std::vector<int>& c, int r) : c(c), r(r), f([&r](auto v) { return v%r == 0; }) {
}
boost::range_detail::filtered_range<std::function<bool(int)>, std::vector<int>>::iterator begin() {
return rng.begin();
}
boost::range_detail::filtered_range<std::function<bool(int)>, std::vector<int>>::iterator end() {
return rng.end();
}
std::vector<int> c;
int r;
std::function<bool(int)> f;
boost::range_detail::filtered_range < std::function<bool(int)>, std::vector<int>> rng=c | boost::adaptors::filtered(f);
};
Usage should be something like:
for (auto& element : MyFilter(input, 4)) {
std::cout << "Element = " << element << std::endl;
}
Unfortunately, it prints again just the 4. Whichs is quite strange to me??
Now, I got the solution by myself. I have to remove the "&" in my lambda function to make it work!
In:
auto myFilter = [](const std::vector<int>& v, int r) {
return v | boost::adaptors::filtered([&r](auto v) { return v%r == 0; });
};
It returns another range adaptor while r captured by reference becomes a dangling reference. To fix it capture r by value:
auto myFilter = [](const std::vector<int>& v, int r) {
return v | boost::adaptors::filtered([r](auto v) { return v%r == 0; });
}; ^
+--- capture by value

c++ nlohmann json - how to iterate / find a nested object

I am trying to iterate over a nested json, using nlohmann::json. My json object is below:
{
"one": 1,
"two": 2
"three": {
"three.one": 3.1
},
}
I am trying to iterate and /or find nested objects. But, it seems there is no default support for it. It looks like I have to iterate over each sub-object by creating another loop, or call the fn recursively for every sub-object.
My following piece of code, and its result indicate, that only top level iteration possible.
void findNPrintKey (json src, const std::string& key) {
auto result = src.find(key);
if (result != src.end()) {
std::cout << "Entry found for : " << result.key() << std::endl;
} else {
std::cout << "Entry not found for : " << key << std::endl ;
}
}
void enumerate () {
json j = json::parse("{ \"one\" : 1 , \"two\" : 2, \"three\" : { \"three.one\" : 3.1 } } ");
//std::cout << j.dump(4) << std::endl;
// Enumerate all keys (including sub-keys -- not working)
for (auto it=j.begin(); it!=j.end(); it++) {
std::cout << "key: " << it.key() << " : " << it.value() << std::endl;
}
// find a top-level key
findNPrintKey(j, "one");
// find a nested key
findNPrintKey(j, "three.one");
}
int main(int argc, char** argv) {
enumerate();
return 0;
}
and the output:
ravindrnathsMBP:utils ravindranath$ ./a.out
key: one : 1
key: three : {"three.one":3.1}
key: two : 2
Entry found for : one
Entry not found for : three.one
So, is there a recursive iteration available, or do we have to do this ourselves, using is_object() method?
Indeed, iteration does not recurse and there is no library function for this (yet). What about:
#include "json.hpp"
#include <iostream>
using json = nlohmann::json;
template<class UnaryFunction>
void recursive_iterate(const json& j, UnaryFunction f)
{
for(auto it = j.begin(); it != j.end(); ++it)
{
if (it->is_structured())
{
recursive_iterate(*it, f);
}
else
{
f(it);
}
}
}
int main()
{
json j = {{"one", 1}, {"two", 2}, {"three", {"three.one", 3.1}}};
recursive_iterate(j, [](json::const_iterator it){
std::cout << *it << std::endl;
});
}
The output is:
1
"three.one"
3.1
2
This is a spin off from the accepted answer, which gives you the added benefit of having the parent keys (in addition to the iterator) as you "walk" the json tree.
The parent keys are provided in a list format to easily iterate over them directly. I've also provided the means to convert that list of strings into a "nested json key" (i.e. a json_pointer). That is an object you can use to directly access that k/v pair when performing assorted operations built into nlohmann::json.
Utility functions
#include <string>
#include <list>
#include "nlohmann.hpp"
using JsonIter = nlohmann::json::const_iterator;
typedef std::list<std::string> JsonKeys;
std::string toJsonStringKey( const JsonKeys &keys )
{
static const std::string JSON_KEY_DELIM( "/" );
std::string s;
for( auto k : keys ) s.append( JSON_KEY_DELIM + k );
return s;
}
nlohmann::json::json_pointer toJsonPointerKey( const JsonKeys &keys )
{ return nlohmann::json::json_pointer( toJsonStringKey( keys ) ); }
nlohmann::json::json_pointer toJsonPointerKey(
const JsonKeys &parentKeys, JsonIter it )
{
JsonKeys allKeys( parentKeys );
allKeys.push_back( it.key() );
return nlohmann::json::json_pointer( toJsonStringKey( allKeys ) );
}
typedef std::function< void( const JsonKeys &parentKeys,
nlohmann::json::const_iterator it )> WalkJsonCallBack;
void walkJson( const nlohmann::json &jsonObj, JsonKeys &parentKeys,
WalkJsonCallBack callback )
{
for( auto it( jsonObj.begin() ); it != jsonObj.end(); ++it )
{
if( it->is_structured() )
{
parentKeys.push_back( it.key() );
walkJson( *it, parentKeys, callback );
parentKeys.pop_back();
}
else callback( parentKeys, it );
}
}
Example implementation
const nlohmann::json parsed( nlohmann::json::parse( raw ) );
JsonKeys parentKeys;
walkJson( parsed, parentKeys, []( const JsonKeys &parentKeys, JsonIter it )
{
// INSERT YOUR CODE HERE
// Example of getting a pointer key..
const auto key( toJsonPointerKey( parentKeys, it ) );
// Now, do whatever with that key...
});
Sample Data
And here's the op's sample data, after adding a few more fields and nestings:
const std::string testData(
"{ \"one\" : 1 , \"two\" : 2, "
"\"three\" : { "
" \"three.one\" : 3.1, "
" \"three.two\" : { \"three.two.one\" : 3.21, \"three.two.two\" : 3.22 }, "
" \"three.three\": { \"three.three.one\" : 3.31, \"three.three.two\" : 3.32 }, "
" \"three.four\": 3.4, "
" \"three.five\": { \"three.five.one\" : 3.51, \"three.five.two\" : 3.52 } "
"}, "
"\"four\" : 4"
"} " );

Defining macros for specific functions in C++

There are 4 things that I was wondering if I could do in C++ with macros or inline functions.
(1) postfix operations in normal types (int, char, etc)
int n = 5;
printf("%d\n", n!)
output: 120
(2) infix operations in normal types (int, char, etc)
int a = 20, b = 10
if(b|a) printf("%d is divisor of %d\n", b, a);
// the symbol | means "divides", this is like (a % b == 0)
output: 10 is divisor of 20
(3) sequential operations in common types
int a = 5, b = 15, c = 20;
if(a < b < c) printf("true\n");
output: false
//doesn't matter if it's made with symbols or words
(4) for each (not using for(auto...) C++11) and
it may different for lists, vectors, etc...
vector<int> v = {1,3,5,7};
foreach(e : v) printf("%d ", e);
output: 1 3 5 7
That's it. Is it possible to make any of these macros in C++ ?
Thanks !
PS: the symbols dont need to be | or !. Since they work, they can be # or $ or anything. The idea is to be postfix (a#), infix(a#b), sequential (a#b#c) and the foreach may be different, just to be smaller than a normal for is ok
No, you could make a function like int factorial(int x) and use printf( .. factorial(... but you cannot create operators like this from a macro.
No, | is already an operator (bitwise or).
This is the case anyway,. so what are you trying to do?
Why? Just use auto?
I think you are facing the X Y problem. There is likely no reason to make any of these a macro.
If you're willing to give your operators a textual name, you can certainly do 1, 2, 3. I believe 4 is what templates are for, i.e., take std::vector with T as a template parameter. You can inline any of these functions. Note that this code will probably not pass a code review, it's just here for your experimenting.
#include <iostream>
#include <boost/optional.hpp> // change to <optional> if you have it
#define OPTIONAL_NS boost // change it to std if above is <optional>
using namespace std;
struct Factorial {};
#define FACTORIAL * Factorial() /* choose operator based on associativity and precedence */
int operator*( const int n, const Factorial& )
{
return n == 0 ? 1 : (n - 1) FACTORIAL * n;
}
template<typename T, typename U>
struct StoreOne
{
const U m_a;
StoreOne( const U& a )
: m_a( a )
{
}
operator bool() const // do this only if U can be casted to bool
{
return m_a;
}
};
struct Divides {};
#define DIVIDES * Divides() *
StoreOne<Divides, int> operator*( const int a, const Divides& )
{
return a;
}
bool operator*( const StoreOne<Divides, int> da, const int b )
{
return b % da.m_a == 0;
}
struct Gt {};
#define GT < Gt() <
StoreOne<Gt, OPTIONAL_NS::optional<int> > operator<( const OPTIONAL_NS::optional<int> a, const Gt& )
{
return OPTIONAL_NS::optional<int>( a );
}
OPTIONAL_NS::optional<int> operator<( const StoreOne<Gt, OPTIONAL_NS::optional<int> >& ga, const int b )
{
if ( ga.m_a )
{
if ( *ga.m_a < b )
{
return OPTIONAL_NS::optional<int>( b );
}
}
return OPTIONAL_NS::optional<int>();
}
template<typename T>
void printVector( const std::vector<T>& v )
{
for ( const T& t : v )
{
cout << t << endl;
}
}
int main() {
cout << endl << "Factorial: " << ( 5 FACTORIAL );
cout << endl << "Divides: " << ( 5 DIVIDES 120 ? "Success" : "Failed" );
cout << endl << "Greater-than 1: " << ( 3 GT 4 GT 5 ? "Success" : "Failed" );
cout << endl << "Greater-than 2: " << ( !( 3 GT 4 GT 3 ) ? "Success" : "Failed" );
cout << endl << "Greater-than 3: " << ( !( 5 GT 4 GT 5 ) ? "Success" : "Failed" );
cout << endl;
std::vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
v.push_back( 3 );
printVector( v );
}

Reads a file but prints integers that are not in the read file

I am having trouble getting a file to read and then print a list to another file, line by line of the number of occurrences of each.
I works, however it prints the numbers: 1, 2, 3, 4, and 5 to the output file which are not in the read file
The struct:
struct entry {
string word;
string word_uppercase;
int number_occurences;
};
//for array
entry myEntryArray[MAX_WORDS];
int addNewEntryHere=0; //next empty slot
My main calls extractTokensFromLine to read and put in an array:
void extractTokensFromLine(std::string &myString) {
const char CHAR_TO_SEARCH_FOR = ' ';
stringstream ss(myString);
string tempToken;
//Extracts characters from is and stores them into str until the delimitation character delim is found
while (getline(ss, tempToken, CHAR_TO_SEARCH_FOR)) {
processTokenArray(tempToken);
}
}
It goes through each line word by word to put in an array:
void processTokenArray(string &token) {
//temp uppercase for compare
string strUpper = token;
toUpper(strUpper);
//see if its already there
for (int i = 0; i < addNewEntryHere; ++i) {
if (strUpper == myEntryArray[i].word_uppercase) {
//yep increment count
myEntryArray[i].number_occurences++;
return;
}
}
//nope add it
myEntryArray[addNewEntryHere].word = token;
myEntryArray[addNewEntryHere].number_occurences = 1;
myEntryArray[addNewEntryHere].word_uppercase = strUpper;
//where next place to add is
addNewEntryHere++;
}
It then writes the Array to a file (each word and its number of occurrence):
bool writeArraytoFile(const std::string &OUTPUTFILENAME) {
fstream outfile;
if (!openFile(outfile,OUTPUTFILENAME,ios_base::out))
return false;
int var;
for (var = 0; var < addNewEntryHere; ++var) {
string word = myEntryArray[var].word;
if(word != " " && word != "")
outfile<<myEntryArray[var].word << " " <<IntToString(myEntryArray[var].number_occurences)<<std::endl;
}
closeFile(outfile);
return true;
}
The Read File is TestData.txt:
I think I should like a bit of butter
And If its not
too much trouble some toast as well. And while you are in the kitchen a brace of expressos for me and my man here.
My Output file (sorted using the following method):
void sortVector(sortOrder so = NUMBER_OCCURRENCES) {
bool shouldSwap = false;
for (int var = 0; var < addNewEntryHereV; ++var) {
for (int var1 = var+1; var1 < addNewEntryHereV; ++var1) {
switch (so) {
case ASCENDING:
shouldSwap =!compareAscendingV(myEntryVector, var, var1);
break;
//TODO handle the following cases appropriately
case DESCENDING:
shouldSwap =!compareDescendingV(myEntryVector, var, var1);
break;
case NUMBER_OCCURRENCES:
shouldSwap =!sortbyOccurrenceV(myEntryVector, var, var1);
break;
default:
break;
}
if (shouldSwap){
std::string tmp = myEntryVector._V.at(var);
myEntryVector._V.at(var) = myEntryVector._V.at(var1);
myEntryVector._V.at(var1) = tmp;
}
}
}
}
Actual Output:
And 3
4 2
of 2
a 2
I 2
here. 1
man 1
my 1
me 1
for 1
expressos 1
brace 1
kitchen 1
the 1
in 1
are 1
you 1
while 1
well. 1
as 1
toast 1
some 1
trouble 1
much 1
too 1
5 1
3 1
2 1
1 1
not 1
its 1
If 1
butter 1
bit 1
like 1
should 1
think 1
Any sort of suggestion would be greatly appreciated,
thanks
Your specification was not clear to me in some cases so I guessed. This should be pretty close to what you are trying to do.
gcc 4.7.3: g++ -Wall -Wextra -std=c++0x word-freq.cpp
#include <algorithm>
#include <cctype>
#include <iostream>
#include <map>
typedef std::map<std::string, int> histogram_t;
std::string to_lower(const std::string& s) {
std::string r(s);
std::transform(std::begin(r), std::end(r), std::begin(r), ::tolower);
return r; }
histogram_t word_freq(std::istream& is) {
histogram_t m;
std::string s;
while (is >> s) { ++m[to_lower(s)]; }
return m; }
void outAscWord(std::ostream& os, const histogram_t& m) {
for (const auto& e : m) {
os << e.first << " " << e.second << "\n"; } }
void outDescWord(std::ostream& os, const histogram_t& m) {
for (auto i = m.crbegin(); i != m.crend(); ++i) {
os << i->first << " " << i->second << "\n"; } }
template <class A, class B>
std::pair<B, A> flip_pair(const std::pair<A, B>& p) {
return std::pair<B, A>(p.second, p.first); }
template <class A, class B>
std::multimap<B, A> flip_map(const std::map<A, B>& m) {
std::multimap<B, A> r;
std::transform(m.begin(), m.end(), std::inserter(r, r.begin()), flip_pair<A,B>);
return r; }
void outAscCount(std::ostream& os, const histogram_t& m) {
auto mm = flip_map(m);
for (const auto& e : mm) {
os << e.first << " " << e.second << "\n"; } }
int main() {
// Can pass fstreams instead of iostreams if desired.
auto m = word_freq(std::cin);
outAscWord(std::cout, m);
outDescWord(std::cout, m);
outAscCount(std::cout, m);
}

Object values altered after return from function

PART OF A HOMEWORK PROBLEM
I have a list of objects, and my goal is to try and find if an object X is present in that list (I am interested only in the first occurrence of that object). My code seems to work fine for the most part, but I have this strange error where the value of only 1 particular object is being modified after it is returned from a function.
I added 10 objects to the list with values 0 through 3. When I search for any number except 0, (./a.out 1 OR ./a.out 2 and so on)I get the right output. But when I search for 0(./a.out 0), the findInList() prints the correct result, but the main() prints the value 18 (which is not even present in the list).
I am attaching the full source code here in case someone wants to compile it and try it out. I am also attaching the gdb step through I did.
SOURCE:
#include <iostream>
#include <string>
#include <functional>
#include <list>
using namespace std;
class Page {
public:
int pgnum; // page number
union {
int lfu_count;
int lru_clock:1; // can only be 0/1
int lru_ref8:8; // we only need 8 bits
};
public:
// Constructors
Page(int num) { pgnum = num; }
Page() {}
// Operator overloading
bool operator== (const Page &p) const {
if(p.pgnum == pgnum)
return true;
else
return false;
}
bool operator!= (const Page &p) const {
return !(p==*this);
}
};
ostream & operator<<(ostream & os, const Page &p) {
os << "Page number: " << p.pgnum;
return os;
}
// Think of this as an equivalent to equals in Java (IT IS NOT, JUST IMAGINE)
struct PageNumber: public binary_function< Page, Page, bool > {
bool operator () ( const Page &p1, const Page &p2 ) const {
return p1 == p2;
}
};
// Function to find an object in any list given an Operation
template <class Operation, class T>
T* findInList( list<T> fullList, T obj, const Operation &op ) {
T* ret = NULL;
typename list<T>::iterator it = fullList.begin();
it = find_if( it, fullList.end(), bind2nd( op, obj ) );
if( it != fullList.end() ) {
cout << "Found obj in list: " << *it << endl;
ret = &(*it); // not the same as it (which is of type iterator)
}
return ret;
}
int main( int argc, char **argv ) {
Page page_to_find;
list<Page> frames;
if( argc != 2 ) {
cout << "Please enter 1 and only 1 argument" << endl;
exit(-1);
}
page_to_find.pgnum = atoi(argv[1]);
Page *p = new Page[10];
for( int i=0; i<10; i++ ) {
p[i].pgnum = i%4;
frames.push_back(p[i]);
}
list<Page>::iterator it_frames = frames.begin();
while( it_frames != frames.end() ) {
cout << "Page in frames: " << *it_frames << endl;
it_frames++;
}
Page* pg = findInList( frames, page_to_find, PageNumber() );
if( pg != NULL )
cout << "Found page: " << *pg << endl;
delete[] p;
return 0;
}
You're returning the address of an object in a list that is pushed into the parameter list by value. Thus it is undefined behavior. Consider changing the parameter of the list in findInList to a reference.
// note reference type change in parameter list.
template <class Operation, class T>
T* findInList( list<T>& fullList, T obj, const Operation &op ) {
T* ret = NULL;
typename list<T>::iterator it = fullList.begin();
it = find_if( it, fullList.end(), bind2nd( op, obj ) );
if( it != fullList.end() ) {
cout << "Found obj in list: " << *it << endl;
ret = &(*it); // not the same as it (which is of type iterator)
}
return ret;
}