So I am having trouble with my code and cant figure out exactly what the problem is. I am supposed to take in a text file, where the first line shows the number of vertices, and the second line shows the number of edges.From this text file I am trying to take in the values shown then build a graph and determine whether or not it contains a cycle. Then display nodes which have no incoming edges.
t1.txt
3
2
1,2,
2,3
I am not sure exactly where I am going wrong here.
t2.txt
5
5
3,4,
4,5,
2,3,
1,3,
3,5
//
#include <iostream>
#include <fstream>
#include <sstream>
#include<string>
#include<list>
#include <limits.h>
#include <stack>
#include<stdlib.h>
#include <cstdlib>
using namespace std;
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
bool isCyclicUtil(int v, bool visited[], bool *rs); // used by isCyclic()
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // to add an edge to graph
bool isCyclic(); // returns true if there is a cycle in this graph
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack)
{
if(visited[v] == false)
{
// Mark the current node as visited and part of recursion stack
visited[v] = true;
recStack[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i)
{
if ( !visited[*i] && isCyclicUtil(*i, visited, recStack) )
return true;
else if (recStack[*i])
return true;
}
}
recStack[v] = false; // remove the vertex from recursion stack
return false;
}
// Returns true if the graph contains a cycle, else false.
bool Graph::isCyclic()
{
// Mark all the vertices as not visited and not part of recursion
// stack
bool *visited = new bool[V];
bool *recStack = new bool[V];
for(int i = 0; i < V; i++)
{
visited[i] = false;
recStack[i] = false;
}
// Call the recursive helper function to detect cycle in different
// DFS trees
for(int i = 0; i < V; i++)
if (isCyclicUtil(i, visited, recStack))
return true;
return false;
}
int main()
{
float n ,n2;
string filename,line;
cout << "Enter filename: ";
cin >> filename;
fstream file;
file.open(filename.c_str());
file >> n;
file >> n2;
int num = n;
cout << num << " ";
int num2 = n2;
cout << num2 << " ";
string matrix[num2][2];
//int ** mat = new int*[num2];
int mat[num2][2];
Graph g(num);
while(!file.eof())
{
for(int i = 0; i < num2; i++)
{
//mat[i] = new int[num];
for(int j = 0; j < 2; j++)
{
if(getline(file,line,','))
{
matrix[i][j] = line; // read file into string matrix
istringstream(line) >> mat[i][j]; //convert to int and store in dynamic 2d array
}
}
}
}
cout << endl << "TEST " << mat[0][0] << " " << mat[0][1] << " " << mat[1][0]<< " " << mat[1][1];
for(int i = 0; i <num2-1; i++)
{
int temp1,temp2;
temp1 = mat[i][0];
temp2 = mat[i][1];
g.addEdge(temp1,temp2);
}
if(g.isCyclic())//Here is where the program crashes for input t2.txt
cout << "Graph is not DAG";
else
cout << "Graph is DAG";
return 0;
}
Related
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include<iomanip>
using namespace std;
typedef pair<int, int> intPair;// rename intPair
typedef vector<double> doubleVector; //rename doubleVetcor
typedef vector<intPair> intPairVector; // rename intPairVector
// Union-Find Disjoint Sets Library written in OOP manner, using both path compression and union by rank heuristics
class UnionFind { // OOP style
private:
doubleVector p, rank, setSize; // remember: vi is vector<double>
int numSets;
public:
UnionFind(int N) {
setSize.assign(N, 1);
numSets = N;
rank.assign(N, 0);
p.assign(N, 0);
for (int i = 0; i < N; i++)
p[i] = i;
}
int findSet(int i) {
return (p[i] == i) ? i : (p[i] = findSet(p[i]));
}
bool isSameSet(int i, int j) {
return findSet(i) == findSet(j);
}
void unionSet(int i, int j) {
if (!isSameSet(i, j)) {
numSets--;
int x = findSet(i), y = findSet(j);
// rank is used to keep the tree short
if (rank[x] > rank[y]) {
p[y] = x;
setSize[x] += setSize[y];
}
else{
p[x] = y;
setSize[y] += setSize[x];
if (rank[x] == rank[y])
rank[y]++;
}
}
}
int numDisjointSets() {
return numSets;
}
int sizeOfSet(int i) {
return setSize[findSet(i)];
}
};
vector<intPairVector> AdjList;
int main() {
int num_verts=0;
cin >> num_verts;
//Pre-allocate a vector of num_verts rows, each of which is a vector
//of num_verts copies of 0.0
vector<vector<double>> matrix(num_verts, vector<double>(num_verts,0.0));
//Requires c++11 or higher
for(int row = 0; row<num_verts;++row) {
for(int col = 0; col<num_verts; ++col){
cin >> matrix[row][col];
}
}
//print out the matrix we just read
for(int row = 0; row<num_verts; ++row) {
for(int col=0; col<num_verts;++col){
cout << setprecision(2) << fixed << matrix[row][col] << "\t";
}
cout << "\n";
}
// Kruskal's algorithm merged
AdjList.assign(num_verts, intPairVector());
vector< pair<double, intPair> > EdgeList; // (weight, two vertices) of the edge
for (int row = 0; row<num_verts; ++row) {
for(int col=0; col<num_verts;++col){
EdgeList.push_back(make_pair(matrix[row][col], intPair(row,col)));
AdjList[row].push_back(intPair(row,matrix[row][col]));
AdjList[col].push_back(intPair(col,matrix[row][col]));
}
}
sort(EdgeList.begin(), EdgeList.end()); // sort by edge weight O(E log E)
// note: pair object has built-in comparison function
double mst_cost = 0.0;
UnionFind UF(num_verts); // all V are disjoint sets initially
for (int i = 0; i < num_verts*num_verts; i++) { // for each edge, O(E)
pair<double,intPair> front = EdgeList[i];
if (!UF.isSameSet(front.second.first, front.second.second)) { // check
mst_cost += front.first; // add the weight of e to MST
UF.unionSet(front.second.first, front.second.second); // link them
}
} // note: the runtime cost of UFDS is very light
//display the weight of the MST
cout << setprecision(2) << fixed << mst_cost << endl;
return 0;
}
I am trying to display the minimum spanning tree from this code, I cannot figure out how to get this code to display the modified matrix. The code is working correctly, by that I mean it is compiling and calculating the correct weight for the graph. However, I am unsure how to display the minimum spanning tree from using Kruskals algorithm. Thanks for any help
Whenever you add the weight of an edge to the weight of the MST, you should also add that edge to a list to keep track of the MST edges.
I have a problem with my C++ code. I need to make the sum of the vectors component by component. For example, if I have A(2,1) and B(3,3) the result should be (5,4). I tried to do something but apparently I have a problem and I don't know what to do. The error is: ,,No member called push in std::_1vector" My code is:
#include <iostream>
#include "stack_base.h"
#include <vector>
using namespace std;
template<typename T>
class App {
public:
Stack<T> * stack;
App(Stack<T> &stack) {
this->stack = &stack;
}
T sum(){
Stack<T> *tempStack = stack;
T sum=0;
int size = stack->getTopLevel();
for(int i=0; i<=size; i++) {
sum+=tempStack->peek();
tempStack->pop();
}
return sum;
}
T substract(){
Stack<T> tempStack = *stack;
T substr=0;
for(int i=0; i<=stack->getTopLevel(); i++) {
substr-=tempStack.peek();
tempStack.pop();
}
return substr;
}
};
void display(vector<int> &v)
{
for(int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << "\n" << endl;
}
int main(){
using namespace std;
Stack<int> myStack;
App<int> a(myStack);
unsigned int i = 0;
std::vector<int> v1;
std::vector<int> v2;
// Populate v1 and v2 here
// Check that v1 and v2 have the same length
if (v1.size() != v2.size())
{
// error here
}
std::vector<int> v3; // This will hold the resulting vector
// Preallocate the necessary memory if you like here, but it
// isn't necessary and doesn't gain you much.
for (auto i = 0ul; i < v1.size(); ++i)
{
v3.push_back(v1[i] + v2[i]);
}
int x;
cout << "Enter five integer values for v1" << endl;
for(int i; i<5; i++)
{
cin >> x;
v1.push_back(x);
}
cout << "Enter five integer values for v2" << endl;
for(int i; i<5; i++)
{
cin >> x;
v2.push_back(x);
}
cout << "Size of Vector= " << v2.size() << endl;
display(v3);
return 0;
}
This is Stack:
#include <iostream>
using namespace std;
#define NMAX 30 // pre-processing directive
template<typename T>
class Stack {
private:
// an array of NMAX dimension
T stackArray[NMAX];
/* the top of the stack, representing the INDEX of last element of the
stackArray:0, 1, 2,....*/
int topLevel;
public:
void push(T x) {
//puts an element in the stack array
//check if the stack array has the maximum dimension
if (topLevel >= NMAX - 1)
{
cout<<"The stack is full: we have already NMAX elements!\n";
//exit the function without making anything
return;
}
/*add an element=> the index of the last element of the stack Array
increases and put the value of the new element in the stack array*/
stackArray[++topLevel] = x;
}
int isEmpty() {
//returns 1, if topLevel>=0, meaning the stack array has elements
// returns 0, otherwise
return (topLevel < 0);
}
T pop() {
// extracts and element from the stack array and returns the new top
if (isEmpty()) {
// the extraction is made only if the array is not empty
cout<<"The stack is empty! \n";
T x;
return x;
}
// the topLevel decreases and the new top is changed
return stackArray[--topLevel];
}
T peek() {
// returns the top of the stack
if (isEmpty()) {
// the extraction is made only if the array is not empty
cout<<"The stack is empty! \n";
T x;
return x;
}
return stackArray[topLevel];
}
void display(){
for(int i=0;i<=topLevel;i++)
cout<<stackArray[i];
}
bool search(T num){
for(int i=0; i<=topLevel;i++)
if(num==stackArray[i])
return true;
return false;
}
int getTopLevel(){
return topLevel;
}
Stack() { // constructor
topLevel = -1; // the stack is empty in the beginning
}
void sort(T s){
if (!isEmpty()) {
T x = Pop(s);
sort(s);
push(s, x);
}
}
~Stack() { // destructor
}
};
You are never adding any elements to your vector. In the preceding three lines, you attempt to access elements that do not exist, but the vectors only do bounds checking if you call the 'at' method instead of using the bracket notation. What are you trying to accomplish in that for-loop?
To add two vectors of the same length pair-wise, which is what I think you want, you can do this:
std::vector<int> v1;
std::vector<int> v2;
// Populate v1 and v2 here
// Check that v1 and v2 have the same length
if (v1.size() != v2.size())
{
// error here
}
std::vector<int> v3; // This will hold the resulting vector
// Preallocate the necessary memory if you like here, but it
// isn't necessary and doesn't gain you much.
for (auto i = 0ul; i < v1.size(); ++i)
{
v3.push_back(v1[i] + v2[i]);
// Debugging statement
std::cout << "Added " << v1[i] << " and " << v2[i] << " to get " << v3[i] << " for index " << i << std::endl;
}
Using codeblocks, I have written a code that displays an adjacency matrix, BFS and DFS search order, and whether or not graph is bipartite.
The graph is passed as a program argument through main as a .txt file.
I have two identical .txt files with different names and drastically different outputs. I have absolutely no idea why.
for graph0.txt
I have this output
For graphNull.txt
I have this output
With the exception of the file name, the files are identical. I even typed them the exact same way just to make sure. Why is this happening?
#include <iostream>
using namespace std;
#include "Graph.h"
int main(int argc, char *argv[])
{
Graph g;
g.load(argv[1]);
cout << endl << "Adjacency Matrix" << endl;
g.display();
g.displayDFS(0);
g.displayBFS(0);
cout << "Bipartite: ";
if (g.isBipartite())
cout << "TRUE";
else
cout << "FALSE";
cout << endl;
return 0;
}
Graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include "QueueInt.h"
#include "StackInt.h"
class Graph {
public:
Graph(); // constructor
~Graph(); // destructor
// Load the graph from a file
void load(char *filename);
// Display the adjacency matrix
void display() const;
// Display the depth first search from the given vertex
void displayDFS(int vertex) const;
// Display the breadth first search from the given vertex
void displayBFS(int vertex) const;
// Determine whether the graph is bipartite or not
bool isBipartite() const;
private:
string fName;
int numVert;
int** mat;
int* visited;
int* dfs;
void helperDFS(int vertex, int &counter, int* visited, int* dfs) const;
};
#endif
Graph.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
#include "Graph.h"
#include "QueueInt.h"
#include "StackInt.h"
// Constructor
Graph::Graph()
{
fName = "";
numVert = 0;
}
// Destructor
Graph::~Graph()
{
delete mat;
delete visited;
delete dfs;
}
// Load the graph from a file
void Graph::load(char* filename)
{
int numStore;
fName = filename;
fstream fin;
fin.open(filename);
fin >> numStore;
numVert = numStore;
mat = new int *[numVert];
int a;
int b;
for (int i = 0; i < numVert ; i++){
//matrix is created
mat[i] = new int[numVert];
for (int j = 0; j < numVert; j++){
mat[i][j] = 0;
}
}
while (fin >> a >> b){
mat[a][b] = 1;
mat[b][a] = 1;
}
}
// Display the adjacency matrix
void Graph::display() const
{
for (int i = 0; i < numVert; i++){
for (int j = 0; j < numVert; j++){
cout << mat[i][j] << " ";
}
cout << "\n";
}
}
// Displays the depth first search starting at the given vertex
void Graph::helperDFS(int vertex, int &counter, int* visited, int* dfs) const {
visited[vertex] = 1;
dfs[counter] = vertex;
counter++;
for (int j = 0; j < numVert; j++){
if (mat[vertex][j] == 1 && visited[j] != 1){
helperDFS(j, counter, visited, dfs);
}
}
}
void Graph::displayDFS(int vertex) const
{
int counter = 0;
int* visited = new int [numVert];
for(int i = 0; i < numVert; i++){
visited[i] = 0;
}
int* dfs = new int [numVert];
helperDFS(vertex, counter, visited, dfs);
cout << "DFS at vertex " << vertex << ": ";
for (int i = 0; i < numVert; i++){
cout << dfs[i] << " ";
}
}
// Perform breadth first search starting at the given vertex
void Graph::displayBFS(int vertex) const
{
int v = vertex;
int vert;
int bfs[numVert];
int counter = 0;
int* visited = new int [numVert];
QueueInt q; //empty q
//create visited array initizalized to false for each vertex
for (int i = 0; i < numVert; i++){
visited[i] = 0;
}
cout << endl;
//mark v as visited
visited[vertex] = 1;
//add v to queue
q.enqueue(vertex);
//process v to array for output
bfs[counter] = vertex;
counter ++;
while(!q.isEmpty()){
vert = q.dequeue();
for (int j = 0; j < numVert; j++){
if (mat[vert][j] == 1 && visited[j]!=1){
visited[j] = 1;
q.enqueue(j);
bfs[counter] = j;
counter ++;
}
}
}
cout << "BFS at vertex " << v << ": ";
for (int i = 0; i < numVert; i++){
cout << bfs[i] << " ";
}
cout << "\n";
}
// Determine whether the graph is bipartite or not
bool Graph::isBipartite() const
{
bool flag = true;
int color[numVert];
//ASSIGN COLOR ELEMENTS TO 0
for (int i = 0; i < numVert; i++){
color[i] = 0;
}
//ASSIGN CURRENT ELEMENT COLOR 1
for (int i =0; i < numVert; i++){
if (color[i] == 0){
color[i] = 1;
}
//ASSIGN ADJACENT ELEMENTS COLOR 2
for (int j = 0; j < numVert; j++){
if (mat[i][j] == 1){
color[j] = 2;
}
}
//FOR ELEMENTS WITH COLOR TWO, CHECK FOR ADJACENCY
for (int j = 0; j < numVert; j++){
if (color[j] == 2){
for (int k = 0; k < numVert; k++){ //will have a self check, but thats not a problem given no self loops
if (color[k] == 2){
if (mat[j][k] == 1){
flag = false;
return flag;
}
}
}
}
}
//RESET COLORS, RUN AGAIN
for (int h = 0; h < numVert; h++){
color[h] = 0;
}
}
return flag;
}
QueueInt.h
#ifndef QUEUEINT_H
#define QUEUEINT_H
#include <queue>
using namespace std;
class QueueInt
{
public:
// Add an integer to the back of the queue.
void enqueue(int val);
// Removes and returns an integer from the front of the queue. Aborts the
// program is the queue is empty.
int dequeue();
// Returns but does not remove the integer at the front of the queue. Aborts the
// program is the queue is empty.
int front() const;
// Returns true if the queue is empty.
bool isEmpty() const;
private:
queue<int> queueObj; // underyling STL queue object
};
#endif // QUEUE_H
QueueInt.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
#include "QueueInt.h"
// Add an integer to the back of the queue.
void QueueInt::enqueue(int val)
{
queueObj.push(val);
}
// Removes and returns an integer from the front of the queue. Aborts the
// program is the queue is empty.
int QueueInt::dequeue()
{
int val = front();
queueObj.pop();
return val;
}
// Returns but does not remove the integer at the front of the queue. Aborts the
// program is the queue is empty.
int QueueInt::front() const
{
if (isEmpty()) {
cerr << "Tried to access empty queue --> aborting program" << endl;
exit(-1);
}
return queueObj.front();
}
// Returns true if the queue is empty.
bool QueueInt::isEmpty() const
{
return queueObj.empty();
}
I want to print the number of nodes which are reachable from a particular node. I read graph and stored in adjacency list and performed bfs.i had tried the following code.it works with certain graph.can you traced out what's wrong with this?
#include <vector>
#include <iostream>
#include <list>
#include<queue>
using namespace std;
int BFS(int s)
{
const int V=100;
int r=0;
vector<list<int> > a(V);
int visited[V]={0};
queue<int> Q;
visited[s]=1;
Q.push(s);
++r;
while(!Q.empty())
{
int x=Q.front();
Q.pop(); // pop here. we have x now
++r;
vector<list<int> >::iterator it1=a.begin()+x;
list<int> it2=*it1;
list<int>::iterator iter=it2.begin();
while(iter!=it2.end())
{
if(visited[*iter]==0)
{
visited[*iter]=1;
Q.push(*iter);
}
++iter;
}
visited[x]=2; // set visited here.
}
return r;
}
void printAsGrid(int V)
{
// Create a local 2D projection grid
int size = V.size();
double *grid = new double[size*size];
memset(grid, 0.0, size*size*sizeof(double));
// Get the edge connection and weight
int index;
for (index = 0; index < size; index++) {
list<Edge>::const_iterator eit;
for (eit = V[index].edges.begin();
eit != V[index].edges.end(); eit++) {
int to = (*eit).to;
double w = (*eit).weight;
// record weight in the projection grid
grid[(index*size)+to] = w;
}
}
// print header
out << " |";
for (index = 0; index < size; index++)
out << " " << index;
out << endl;
out << "---+";
for (index = 0; index < size; index++)
out << "-----";
out << endl;
// print content
out.setf(ios::fixed);
out.setf(ios::showpoint);
for (index = 0; index < size; index++) {
out << " " << index << " |";
for (int j = 0; j < size; ++j)
out << setw(5) << setprecision(1) << grid[(index*size)+j];
out << endl;
}
// delete grid before exit
delete [] grid;
}
int main()
{
int s;
int V,total_neighbors, id, weight;
//number of vertices
cout<<"enter the no.of vertices:";
cin>>V;
vector< list< int > > graph(V + 1);
for(int i= 0; i<V;i++) {
cout<<"Enter no.of neighbours of"<<i<<":";
cin>>total_neighbors;
cout<<"Enter the neighbours of"<<i<<":";
for(int j = 0; j <total_neighbors; j++) {
cin>>id;
graph[i].push_back(id);
}
}
vector<list<int> >::iterator i;
int c=0;
for (vector<std::list<int> >::iterator i=graph.begin(); i !=graph.end(); ++i){
cout<<"vertices connected to node "<<c <<" are ";
//cout<<*i;
std::list<int> li = *i;
for(std::list<int>::iterator iter = li.begin(); iter!= li.end(); ++iter){
cout<<*iter<<" ";
}
cout<<endl;
c++;
}
int f;
cin>>f;
s=BFS(f);
cout<<s<<" ";
return 0;
}
adjacencyList 0 -> 1 -> 2
adjacencyList 1 -> 2 -> 4
adjacencyList 2 -> 4
adjacencyList 3 -> 5
adjacencyList 4
adjacencyList 5 -> 3
returns 2 but actual answer is 3
You are doing r++ two times. You can do it only when you are pushing the node or when just popping the node. Otherwise for the source node, it will count twice. Also initialise r to 0. Also initialise the visited array manually to be on safe side.
Also you have taken vector<list<int> >::iterator it1=a.begin()+x; whereas a is empty. vector<list<int> > a(V); just initialises the vector of list but doesn't put values inside it. And hence the list which you are trying to traverse is empty. You are getting 2 because you are making r++ two times . One when source is inserted and other when source is removed which gives you 2.
See this code :
#include <vector>
#include <iostream>
#include <list>
#include<queue>
using namespace std;
int BFS(vector<list<int> > graph, int s)
{
const int V=100;
int r=0;
int visited[V]={0};
for(int i = 0; i < V; i++) visited[i] = 0;
queue<int> Q;
visited[s]=1;
Q.push(s);
while(!Q.empty())
{
int x=Q.front();
cout << x << endl;
Q.pop(); // pop here. we have x now
++r;
vector<list<int> >::iterator it1=graph.begin()+x;
list<int> it2=*it1;
list<int>::iterator iter=it2.begin();
while(iter!=it2.end())
{
if(visited[*iter]==0)
{
visited[*iter]=1;
Q.push(*iter);
}
++iter;
}
visited[x]=2; // set visited here.
}
return r;
}
int main()
{
int s;
int V,total_neighbors, id, weight;
//number of vertices
cout<<"enter the no.of vertices:";
cin>>V;
vector< list< int > > graph(V + 1);
for(int i= 0; i<V;i++) {
cout<<"Enter no.of neighbours of"<<i<<":";
cin>>total_neighbors;
cout<<"Enter the neighbours of"<<i<<":";
for(int j = 0; j <total_neighbors; j++) {
cin>>id;
graph[i].push_back(id);
}
}
vector<list<int> >::iterator i;
int c=0;
for (vector<std::list<int> >::iterator i=graph.begin(); i !=graph.end(); ++i){
cout<<"vertices connected to node "<<c <<" are ";
//cout<<*i;
std::list<int> li = *i;
for(std::list<int>::iterator iter = li.begin(); iter!= li.end(); ++iter){
cout<<*iter<<" ";
}
cout<<endl;
c++;
}
int f;
cin>>f;
s=BFS(graph,f);
cout<<s<<" ";
return 0;
}
I have an array, and the user can insert a string.
And I have this code:
int main(){
char anagrama[13];
cin >> anagrama;
for(int j = 0; j < strlen(anagrama); j++){
cout << anagrama[j];
for(int k = 0; k < strlen(anagrama); k++){
if(j != k)
cout << anagrama[k];
}
cout << endl;
}
}
The problem is that I need all permutations of the string in sorted order.
For example if the user write: abc, the output must to be:
abc
acb
bac
bca
cab
cba
and my code doesn't show all permutations, and not sorted
Can you help me?
I need do the implementation without a function already implemented.
I think with a recursive function, but I do not know how.
This is an example:
http://www.disfrutalasmatematicas.com/combinatoria/combinaciones-permutaciones-calculadora.html without repetition and sorted
In C++ you can use std::next_permutation to go through permutations one by one. You need to sort the characters alphabetically before calling std::next_permutation for the first time:
cin>>anagrama;
int len = strlen(anagrama);
sort(anagrama, anagrama+len);
do {
cout << anagrama << endl;
} while (next_permutation(anagrama, anagrama+len));
Here is a demo on ideone.
If you must implement permutations yourself, you could borrow the source code of next_permutation, or choose a simpler way of implementing a permutation algorithm recursively.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void permute(string select, string remain){
if(remain == ""){
cout << select << endl;
return;
}
for(int i=0;remain[i];++i){
string wk(remain);
permute(select + remain[i], wk.erase(i, 1));
}
}
int main(){
string anagrama;
cout << "input character set >";
cin >> anagrama;
sort(anagrama.begin(), anagrama.end());
permute("", anagrama);
}
Another version
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
void permute(string& list, int level, vector<string>& v){
if(level == list.size()){
v.push_back(list);
return;
}
for(int i=level;list[i];++i){
swap(list[level], list[i]);
permute(list, level + 1, v);
swap(list[level], list[i]);
}
}
int main(){
string anagrama;
vector<string> v;
cout << "input character set >";
cin >> anagrama;
permute(anagrama, 0, v);
sort(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<string>(cout, "\n"));
}
#alexander the output of this programme is in exact order as requested by you:
HERE, is a simplest code for generating all combination/permutations of a given array without including some special libraries (only iostream.h and string are included) and without using some special namespaces than usual ( only namespace std is used).
void shuffle_string_algo( string ark )
{
//generating multi-dimentional array:
char** alpha = new char*[ark.length()];
for (int i = 0; i < ark.length(); i++)
alpha[i] = new char[ark.length()];
//populating given string combinations over multi-dimentional array
for (int i = 0; i < ark.length(); i++)
for (int j = 0; j < ark.length(); j++)
for (int n = 0; n < ark.length(); n++)
if( (j+n) <= 2 * (ark.length() -1) )
if( i == j-n)
alpha[i][j] = ark[n];
else if( (i-n)== j)
alpha[i][j] = ark[ ark.length() - n];
if(ark.length()>=2)
{
for(int i=0; i<ark.length() ; i++)
{
char* shuffle_this_also = new char(ark.length());
int j=0;
//storing first digit in golobal array ma
ma[v] = alpha[i][j];
//getting the remaning string
for (; j < ark.length(); j++)
if( (j+1)<ark.length())
shuffle_this_also[j] = alpha[i][j+1];
else
break;
shuffle_this_also[j]='\0';
//converting to string
string send_this(shuffle_this_also);
//checking if further combinations exist or not
if(send_this.length()>=2)
{
//review the logic to get the working idea of v++ and v--
v++;
shuffle_string_algo( send_this);
v--;
}
else
{
//if, further combinations are not possiable print these combinations
ma[v] = alpha[i][0];
ma[++v] = alpha[i][1];
ma[++v] = '\0';
v=v-2;
string disply(ma);
cout<<++permutaioning<<":\t"<<disply<<endl;
}
}
}
}
and main:
int main()
{
string a;
int ch;
do
{
system("CLS");
cout<<"PERMUNATING BY ARK's ALGORITH"<<endl;
cout<<"Enter string: ";
fflush(stdin);
getline(cin, a);
ma = new char[a.length()];
shuffle_string_algo(a);
cout<<"Do you want another Permutation?? (1/0): ";
cin>>ch;
} while (ch!=0);
return 0;
}
HOPE! it helps you! if you are having problem with understanding logic just comment below and i will edit.
/*Think of this as a tree. The depth of the tree is same as the length of string.
In this code, I am starting from root node " " with level -1. It has as many children as the characters in string. From there onwards, I am pushing all the string characters in stack.
Algo is like this:
1. Put root node in stack.
2. Loop till stack is empty
2.a If backtracking
2.a.1 loop from last of the string character to present depth or level and reconfigure datastruture.
2.b Enter the present char from stack into output char
2.c If this is leaf node, print output and continue with backtracking on.
2.d Else find all the neighbors or children of this node and put it them on stack. */
class StringEnumerator
{
char* m_string;
int m_length;
int m_nextItr;
public:
StringEnumerator(char* str, int length): m_string(new char[length + 1]), m_length(length) , m_Complete(m_length, false)
{
memcpy(m_string, str, length);
m_string[length] = 0;
}
StringEnumerator(const char* str, int length): m_string(new char[length + 1]), m_length(length) , m_Complete(m_length, false)
{
memcpy(m_string, str, length);
m_string[length] = 0;
}
~StringEnumerator()
{
delete []m_string;
}
void Enumerate();
};
const int MAX_STR_LEN = 1024;
const int BEGIN_CHAR = 0;
struct StackElem
{
char Elem;
int Level;
StackElem(): Level(0), Elem(0){}
StackElem(char elem, int level): Elem(elem), Level(level){}
};
struct CharNode
{
int Max;
int Curr;
int Itr;
CharNode(int max = 0): Max(max), Curr(0), Itr(0){}
bool IsAvailable(){return (Max > Curr);}
void Increase()
{
if(Curr < Max)
Curr++;
}
void Decrease()
{
if(Curr > 0)
Curr--;
}
void PrepareItr()
{
Itr = Curr;
}
};
void StringEnumerator::Enumerate()
{
stack<StackElem> CStack;
int count = 0;
CStack.push(StackElem(BEGIN_CHAR,-1));
char answerStr[MAX_STR_LEN];
memset(answerStr, 0, MAX_STR_LEN);
bool forwardPath = true;
typedef std::map<char, CharNode> CharMap;
typedef CharMap::iterator CharItr;
typedef std::pair<char, CharNode> CharPair;
CharMap mCharMap;
CharItr itr;
//Prepare Char Map
for(int i = 0; i < m_length; i++)
{
itr = mCharMap.find(m_string[i]);
if(itr != mCharMap.end())
{
itr->second.Max++;
}
else
{
mCharMap.insert(CharPair(m_string[i], CharNode(1)));
}
}
while(CStack.size() > 0)
{
StackElem elem = CStack.top();
CStack.pop();
if(elem.Level != -1) // No root node
{
int currl = m_length - 1;
if(!forwardPath)
{
while(currl >= elem.Level)
{
itr = mCharMap.find(answerStr[currl]);
if((itr != mCharMap.end()))
{
itr->second.Decrease();
}
currl--;
}
forwardPath = true;
}
answerStr[elem.Level] = elem.Elem;
itr = mCharMap.find(elem.Elem);
if((itr != mCharMap.end()))
{
itr->second.Increase();
}
}
//If leaf node
if(elem.Level == (m_length - 1))
{
count++;
cout<<count<<endl;
cout<<answerStr<<endl;
forwardPath = false;
continue;
}
itr = mCharMap.begin();
while(itr != mCharMap.end())
{
itr->second.PrepareItr();
itr++;
}
//Find neighbors of this elem
for(int i = 0; i < m_length; i++)
{
itr = mCharMap.find(m_string[i]);
if(/*(itr != mCharMap.end()) &&*/ (itr->second.Itr < itr->second.Max))
{
CStack.push(StackElem(m_string[i], elem.Level + 1));
itr->second.Itr++;
}
}
}
}
I wrote one without a function already implemented even any templates and containers. actually it was written in C first, but has been transform to C++.
easy to understand but poor efficiency, and its output is what you want, sorted.
#include <iostream>
#define N 4
using namespace std;
char ch[] = "abcd";
int func(int n) {
int i,j;
char temp;
if(n==0) {
for(j=N-1;j>=0;j--)
cout<<ch[j];
cout<<endl;
return 0;
}
for(i=0;i<n;i++){
temp = ch[i];
for(j=i+1;j<n;j++)
ch[j-1] = ch[j];
ch[n-1] = temp;
//shift
func(n-1);
for(j=n-1;j>i;j--)
ch[j] = ch[j-1];
ch[i] = temp;
//and shift back agian
}
return 1;
}
int main(void)
{
func(N);
return 0;
}
In case you have std::vector of strings then you can 'permute' the vector items as below.
C++14 Code
#include <iostream>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <boost/algorithm/string/join.hpp>
using namespace std;
int main() {
// your code goes here
std::vector<std::string> s;
s.push_back("abc");
s.push_back("def");
s.push_back("ghi");
std::sort(s.begin(), s.end());
do
{
std::cout << boost::algorithm::join(s,"_") << std::endl ;
} while(std::next_permutation(s.begin(), s.end()));
return 0;
}
Output:
abc_def_ghi
abc_ghi_def
def_abc_ghi
def_ghi_abc
ghi_abc_def
ghi_def_abc