Unknown Type Name when using threads - c++

I am trying to find the minimum vertex cover by giving the vertex and edge input in specific format from the user using threads. Here is my code:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cctype>
#include <list>
#include <set>
#include <vector>
#include <climits>
#include <memory>
#include <algorithm>
#include <pthread.h>
#include <unistd.h>
#include "minisat/core/Solver.h"
using namespace std;
static void *AVC2_Vertex_Cover(void *);
void min_vertex_cover_algorithm(Graph &graph_builder){
int ret;
pthread_t AVC2_thread;
ret = pthread_create(&AVC2_thread, NULL, AVC2_Vertex_Cover, &graph_builder);
if(ret)
exit(1);
pthread_join(AVC2_thread, NULL);
pthread_exit(NULL);
}
struct Edge{
unsigned v1,v2;
};
typedef std::vector<unsigned> Vertex_vector;
typedef std::list<unsigned > Vertex_Adjacency_list;
typedef std::vector<Vertex_Adjacency_list> Adjacency_Traversal_list;
struct Graph{
std::size_t no_of_edges;
Adjacency_Traversal_list adjacency_list;
void initialize_graph(unsigned vertices_number);
void construct_edge(Edge edge);
void clear(unsigned vertex);
};
void Graph::initialize_graph(unsigned num){
adjacency_list.clear();
no_of_edges = 0;
adjacency_list.resize(num,{});
}
void Graph::construct_edge(Edge edge) {
auto &literal_1 = adjacency_list[edge.v1];
auto &literal_2 = adjacency_list[edge.v2];
literal_1.push_back(edge.v2);
literal_2.push_back(edge.v1);
no_of_edges ++;
}
void *AVC2_Vertex_Cover(void *input)
{
Graph g = *(const Graph *)input;
unsigned int V = g.adjacency_list.size();
bool visited[V];
for (int i=0; i<V; i++)
visited[i] = false;
for (int u=0; u<V; u++)
{
if (visited[u] == false)
{
for(int x : g.adjacency_list[u])
{
int v = x;
if (visited[v] == false)
{
visited[v] = true;
visited[u] = true;
break;
}
}
}
}
// Print the vertex cover
std::cout << "APPROX-VC-2: ";
for (int i=0; i<V; i++){
if (visited[i])
if(i == V-1)
cout << i << std::endl;
else
cout << i << ",";
}
}
void *IO_thread(void *)
{
Graph &graph_builder = *new Graph();
char character_input;
string my_input;
unsigned int no_of_vertices = 0;
string edge_stream;
char prev_choice = ' ';
while (getline(cin, my_input))
{
istringstream stream_string(my_input);
while (stream_string >> character_input)
{
character_input=(toupper(character_input));
try
{
switch (character_input)
{
case 'V' :
if (prev_choice == 'V')
{
cerr << "Error: V must be followed by E only.\n";
break;
}
else
{
stream_string >> no_of_vertices;
if(no_of_vertices <= 0)
{
throw "Invalid number of vertices";
}
graph_builder.initialize_graph(no_of_vertices);
prev_choice = 'V';
break;
}
case 'E' :
{
unsigned int flag_Entry = 0;
if ( prev_choice == 'E')
{
cerr << "Error: V and E always occur together.\n ";
break;
}
else
{
stream_string >> edge_stream;
istringstream edge_stream_character(edge_stream);
char edg_char;
unsigned int temp = 0;
unsigned int v1;
unsigned int v2;
edge_stream_character >> edg_char;
while (edg_char != '}')
{
edge_stream_character >> edg_char;
if (edg_char == '}')
{
flag_Entry = 1;
break;
}
else
{
edge_stream_character >> temp;
v1 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> temp;
v2 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> edg_char;
if (v1 >= no_of_vertices || v2 >= no_of_vertices)
{
cerr << "Error: Vertex out of range.\n";
graph_builder.adjacency_list.clear();
break;
}
graph_builder.construct_edge({v1,v2});
}
}
if(flag_Entry == 1)
{
prev_choice = 'E';
break;
}
min_vertex_cover_algorithm(graph_builder);
prev_choice = 'E';
break;
}
}
}
}
catch (const char* err)
{
cerr << "Error:" << err << endl;
}
}
}
return 0;
}
int main(int argc, char **argv){
int ret;
pthread_t IO_thread;
ret = pthread_create(&IO_thread, NULL, IO_thread,NULL);
if(ret)
return 1;
pthread_join(IO_thread,NULL);
pthread_exit(NULL);
}
I am getting an error:
unknown type name 'Graph'
void min_vertex_cover_algorithm(Graph &graph_builder){
I am not able to find why this error is occuring. It will be very helpful if I get some solutions.

Just like you, the compiler will read from top to bottom. When it reaches the line:
void min_vertex_cover_algorithm(Graph &graph_builder){
It has to go, ok, lets use a Graph reference. It will look for the declaration of a Graph, which it cannot find, because you have declared (and defined) it below. To solve this, give the compiler a hint. Declare the Graph above the function with:
struct Graph;
void min_vertex_cover_algorithm(Graph &graph_builder){
Or simply move the whole struct definition above the function.

Related

Struct doesn't print with cout

I'm trying to print the structure in an array whose int prejetih member is highest.
#include <iostream>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(Tekma tekme[]) {
int maksi = 0, index = 0;
for (int i = 0;i < 2;i++) {
if (maksi < tekme[i].prejetih) {
index = i;
maksi = tekme[i].prejetih;
}
}
return tekme[index];
}
void vpis(Tekma tekme[]) {
for (int i = 0;i < 2;i++)
cin >> tekme[i].prejetih;
}
int main() {
Tekma tekme[2];
vpis(tekme);
cout << najvec_kosev(tekme);
}
The compiler reports
C++ no operator matches these operands
operand types are: std::ostream << Tekma
over cout << najvec_kosev(tekme);
Here using a solution with std::vector and fixing your cout problem:
#include <iostream>
#include <vector>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(vector<Tekma>& tekme) {
Tekma lowest = tekme[0]
for(auto& t : tekme) {
if(lowest.prejetih < t.prejetih) {
lowest = t;
}
}
return lowest ;
}
void vpis(vector<Tekma>& tekme) {
int input;
while(true) {
cin >> input;
// Check if the input is valid else quit the loop.
if(input == valid) {
Tekma newStruct = {input};
tekme.push(newStruct);
}
else {
// Stop the loop
break;
}
}
}
int main() {
vector<Tekma> tekme;
vpis(tekme);
cout << najvec_kosev(tekme).prejetih; // This fixes your error.
}

How do I find if two strings is isomorphic of not?

#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
vector<int> diff_arr(26, -40);//Initialise with some random value.
for(int i = 0 ; i < input1.length(); i++){
if(diff_arr[input1[i]-'a'] == -40)
diff_arr[input1[i]-'a'] = input1[i] - input2[i];
else{
if(diff_arr[input1[i]-'a'] != input1[i] - input2[i])
return false;
}
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
My logic is that if characaters could be replaced with exact same characters in the second string then the character-wise difference has to be the same throughout.
The logic is failing in the above case.
You also need to check if two characters from input1 do not map to same character in input2.
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
set<char> usedLetters;
map<char, char> transformations;
for(int i = 0 ; i < input1.length(); i++) {
auto iter = transformations.find(input1[i]);
if (iter != transformations.end()) {
if (iter->second == input2[i]) continue;
else return false;
}
if (usedLetters.count(input2[i])) return false;
usedLetters.insert(input2[i]);
transformations[input1[i]] = input2[i];
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
You need 2 arrays, one to know which character of input2 correspond to a given character of input1, and a second to check if a character of input2 is not already affected to a character of input1.
#include <iostream>
#include <string>
using namespace std;
bool is_isomorphic(const string& input1, const string& input2)
{
if (input1.length() != input2.length()) {
return false;
}
char map[256]{};
bool used[256]{};
for (size_t i = 0; i < input1.length(); i++) {
unsigned char val1 = input1[i];
if (!map[val1]) {
unsigned char val2 = input2[i];
if (used[val2]) {
return false;
}
map[val1] = input2[i];
used[val2] = true;
} else
if (map[val1] != input2[i]) {
return false;
}
}
return true;
}
int main() {
cout << is_isomorphic("abcd", "aabb") << endl;
cout << is_isomorphic("abcdb", "zerte") << endl;
return 0;
}

How to make sure that two strings only have certain alphabets in c++

Aim is to make sure that the user entered input for string 1 and string 2 contains only characters A,T,G or C in any order. If either string contains another other character then error should be displayed. Example:
Input contains error
Error in String #1: aacgttcOgMa
Error in String #2: ggataccaSat
This is my attempt at LCS.cpp file code:
#include "LCS.h"
#include <string>
using namespace std;
bool validate(string strX, string strY)
{
string x = strX;
string y = strY;
char searchItem = 'A';
char searchItem = 'C';
char searchItem = 'G';
char searchItem = 'T';
int numOfChar = 0;
int m = strX.length();
int n = strY.length();
for (int i = 0; i < m; i++)
{
if (x[i] == searchItem)
{
numOfChar++;
}
for (int i = 0; i < n; i++)
{
if (y[i] == searchItem)
{
numOfChar++;
}
}
}
This is my LCS.h file code:
#pragma once
#ifndef LCS_H
#define LCS_H
#include <string>
using namespace std;
bool validate(string strX, string strY);
#endif
And my driver file "Driver6.cpp" has this code:
#include "LCS.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string strX, strY;
cout << "String #1: ";
cin >> strX;
cout << "String #2: ";
cin >> strY;
//validate the input two strings
if (validate(strX, strY) == false)
{
return 0;
}
int m = strX.length();
int n = strY.length();
}
Didn't really want to do this but it seems like the best bet rather than going round the houses in the comments:
#include <string>
#include <iostream>
bool validate( const std::string & s ) {
for ( auto c : s ) {
if ( c != 'A' && c != 'T' && c != 'C' && c != 'G' ) {
return false;
}
}
return true;
}
int main() {
std::string s1 = "ATGCCCG";
std::string s2 = "ATGfooCCCG";
if ( validate( s1 ) ) {
std::cout << "s1 is valid\n";
}
else {
std::cout << "s1 is not valid\n";
}
if ( validate( s2 ) ) {
std::cout << "s2 is valid\n";
}
else {
std::cout << "s2 is not valid\n";
}
}
Another technique:
bool validate(const std::string& s)
{
const static std::string valid_letters("ATCGatcg");
for (auto c: s)
{
std::string::size_type position = valid_letters.find_first_of(c);
if (position == std::string::npos)
{
return false;
}
}
return true;
}
The above code searches a container of valid letters.

Check if a string is a base 16 number

I've been trying to solve this task, but I had no positive results.
So, my task is to check if a string is a base 16 number.
example : s="1AB", it will show YES 427
Here is my code.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if(b==1) return a;
else return a*power(a,b-1);
}
void conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(strchr("0123456789ABCDEF",s[i])) k++;
}
if(k==0) cout<<"not in base 16";
else{
conv(s,n); cout<<s;}
return 0;
}
If you want almost clean solution, you can check mine:
#include <iostream>
using namespace std;
bool IsHex(string& in) {
for (char d : in) {
if (!isxdigit(d)) return false;
}
return true;
}
int Convert(string& in) {
int val = 0;
for (char d : in) {
val = val * 16 + (isdigit(d)? d - '0' : 10 + (isupper(d)? d - 'A' : d - 'a'));
}
return val;
}
int main() {
string in;
cin >> in;
if (!IsHex(in)) cout << "Not a correct hex number" << endl;
else cout << "YES " << Convert(in) << endl;
return 0;
}
And I have made some changes in your code to make it work. You can easily find out changes.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if (b == 0) return 1;
if(b==1) return a;
else return a*power(a,b-1);
}
int conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
return S;
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(!strchr("0123456789ABCDEF",s[i])) break;
}
if(i < n) cout<<"not in base 16";
else{
cout << conv(s,n) << endl;}
return 0;
}
You can just use std::isxdigit, for example:
#include <cctype>
#include <string>
#include <iostream>
bool IsThisStringAHexNumber(std::string const &str)
{
for (size_t i = 0, n = str.length(); i < n; ++i)
if (!std::isxdigit(str[i]))
return false;
return true;
}
int main()
{
std::cout << std::boolalpha << IsThisStringAHexNumber("298722h2jjh") << std::endl;
std::cout << std::boolalpha << IsThisStringAHexNumber("2abc66f") << std::endl;
return 0;
}
Prints:
false
true

Printing from Trie

I have built a trie in C++ designed to hold words of sentences. Each sentence will have a weight which determines the order in which they should be output. I have several recursive functions that call other recursive functions, and the dilemma I am facing is that I want to print my list only once.
Basically my get function calls the printFromNode function which creates the vector of pairs p that I want to sort and print. If someone could point me in the right direction in how to do that it would be much appreciated.
Code:
Trie.cpp:
//#include "Trie.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <sstream>
#include <stack>
using namespace std;
class Node
{
private:
string word = "";
bool endOfSentence = false;
int weight = -1;
public:
vector<Node> children = {};
Node() {
this->setWord("");
}
Node(string s){
this->setWord(s);
}
string getWord(){
return this->word;
}
void setWord(string s) {
this->word = s;
}
void setEOS(){
this->endOfSentence = true;
}
void setWeight(int weight){
this->weight = weight;
}
int getWeight() {
return this->weight;
}
};
class Trie
{
public:
Node root;
void add(vector<string> phrase, int weight, Node* n){
Node* current = n;
int w = weight;
int found = -1;
for (int i = 0; i < current->children.size(); i++) {
if (phrase[0] == current->children[i].getWord()) {
found = i;
}
}
if (found > -1) {
current = &current->children[found];
phrase.erase(phrase.begin());
add(phrase, w, current);
}
else {
addPhrase(phrase, w, current);
}
}
void addPhrase(vector<string> phrase, int weight, Node* n) {
Node* current = n;
for (int i = 0; i < phrase.size(); i++) {
Node temp = *new Node(phrase[i]);
current->children.push_back(temp);
current = &current->children.back();
if (i == phrase.size() - 1) {
current->setEOS();
current->setWeight(weight);
}
}
}
void get(vector<string> search) {
Node* current = &this->root;
get(search, current);
}
void get(vector<string> search, Node* n) {
Node* current = n;
int found = -1;
//test search size
if (search.size() == 0) {
cout << "Please enter a valid search" << endl;
}
for (int i = 0; i < current->children.size(); i++) {
if (search[0] == current->children[i].getWord()) {
found = i;
}
}
if (found > -1 && search.size() == 1) {
current = &current->children[found];
printFromNode(*current);
maxNode(*current);
}
else if (found > -1 && search.size() != 1) {
current = &current->children[found];
search.erase(search.begin());
get(search, current);
}
else {
cout << "Not Found" << endl;
}
}
void printOutput(vector<pair<int,string>> p){
sort(p.begin(), p.end());
cout << p.size() << endl;
for (int i = 0; i < p.size(); i++) {
cout << p[i].second << " " << endl;
}
}
void printFromNode(Node n) {
vector<string> phrase = {};
vector <pair < int, string>> final = {};
printFromNode(n,phrase,final);
}
void printFromNode(Node n, vector<string> &v, vector<pair<int,string>> &p) {
string output;
if (n.getWord() == "") {
return;
}
for (int i = 0; i < n.children.size(); i++) {
if (n.children[i].getWeight() > 0) {
for (int i = 0; i < v.size(); i++)
{
output.append(v[i] + " ");
}
output.append(n.children[i].getWord());
p.push_back(make_pair(n.children[i].getWeight(), output));
}
v.push_back(n.children[i].getWord());
printFromNode(n.children[i], v, p);
v.pop_back();
sort(p.begin(), p.end());
}
return;
}
void maxNode(Node n) {
int max = 0;
int index = 0;
int temp = 0;
for (int i = 0; i < n.children.size(); i++) {
temp = n.children[i].children.size();
if (temp > max) {
max = temp;
index = i;
}
}
cout << n.children[index].getWord() << " " << max << endl;
}
};
Main.cpp:
#include "Trie.cpp"
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[]) {
// Initialize trie up here
Trie myTrie = *new Trie();
// parse input lines until I find newline
for(string line; getline(cin, line) && line.compare(""); ) {
stringstream ss(line);
string string_weight;
ss >> string_weight;
int weight = stoi(string_weight);
// I am just going to put these words into a vector
// you probably want to put them in your trie
vector<string> phrase = {};
for(string word; ss >> word;) {
phrase.push_back(word);
}
myTrie.add(phrase, weight, &myTrie.root);
vector<string> ans = {};
}
// parse query line
string query;
getline(cin, query);
stringstream ss(query);
vector<string> search = {};
for (string query; ss >> query;) {
search.push_back(query);
}
myTrie.get(search);
return 0;
}
You can remove recursive methods, and doing something like the following:
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
class Node
{
public:
bool endOfSentence = false;
std::set<int> weights;
std::map<std::string, Node> children;
Node() = default;
const Node* get(const std::string& word) const
{
auto it = children.find(word);
if (it == children.end()) {
return nullptr;
}
return &it->second;
}
auto find_by_weight(int weight) const
{
return std::find_if(children.begin(),
children.end(),
[=](const auto& p){ return p.second.weights.count(weight);});
}
};
class Trie
{
Node root;
public:
void add(int weight, const std::vector<std::string>& phrase)
{
Node* node = &root;
for (const auto& word : phrase) {
node->weights.insert(weight);
node = &node->children[word];
}
node->weights.insert(weight);
node->endOfSentence = true;
}
bool contains(const std::vector<std::string>& phrase) const
{
const Node* node = &root;
for (const auto& word : phrase) {
node = node->get(word);
if (node == nullptr) {
return false;
}
}
return node->endOfSentence;
}
void print(int weight) const
{
const Node* node = &root;
const char* sep = "";
while (node) {
const auto it = node->find_by_weight(weight);
if (it == node->children.end()) {
break;
}
std::cout << sep << it->first;
sep = " ";
node = &it->second;
}
std::cout << std::endl;
}
void print_all() const
{
for (int i : root.weights) {
print(i);
}
}
};
And usage/Test:
int main(int argc, char* argv[]) {
const std::vector<std::vector<std::string>> sentences = {
{"My", "name", "is", "John"},
{"My", "house", "is", "small"},
{"Hello", "world"},
{"Hello", "world", "!"}
};
Trie trie;
int i = 0;
for (const auto& sentence : sentences) {
trie.add(i, sentence);
++i;
}
const std::vector<std::vector<std::string>> queries = {
{"My", "name", "is", "John"},
{"My", "house"},
{"Hello", "world"}
};
for (const auto& query : queries) {
std::cout << trie.contains(query) << std::endl;
}
trie.print_all();
}
Demo