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
Related
I have two arrays and I want to count how many elements are same between two arrays.
I try many times but the output is not correct. The correct should be 6 times
but the output is 4 times in the code.
Note: if s1 is "ss" and s2 is "ss", is the result 2
Here is my code:
#include <iostream>
#include <string>
using namespace std;
int main() {
char s1[] = "FOOBART";
char s2[] = "BFORATO";
int flag=0;
for(int i=0, j=0; i < sizeof(s1) && j < sizeof(s2); ) {
if(s1[i] == s2[j]) {
flag++;
i++;
j++;
} else if(s1[i] < s2[j]) {
i++;
} else {
j++;
}
}
cout << flag;
}
All elements of s1 are present in both strings so the output will be equal to the length of s1. Here is the correct code
#include <iostream>
using namespace std;
int main() {
char s1[] = "FOOBART";
char s2[] = "BFORATO";
int count=0;
for (int i=0; i<sizeof(s1)-1; i++) {
for (int j=0; j<sizeof(s2)-1; j++) {
if (s1[i]==s2[j]) {
count++;
break;
}
}
}
cout<<count<<endl;
}
Hope this will help you
solution using stl algorithms:
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
const std::string s1 = "FOOBART";
std::string s2 = "BFORATO";
int count = 0;
auto beg = begin(s2);
for(auto& elm : s1)
{
auto x = find(beg, end(s2), elm);
if(x != end(s2))
{
*x = *beg;//get rid of elment and reduce the range of search.
++beg;
++count;
}
}
std::cout << count;
return 0;
}
I'm trying to rotate my string with 'r' places but facing some problem.The following is my code(function).Please help.
For eg: hello coding. after r=3 should become ng.hello codi.
void fnc(){
char a[100],key;
int n,r,i,t=1,total=0,count,x;
cin>>n; //no. of test cases
while(t<=n){
cin>>r; //no. of rotations
cin.get();
cin.get(a,100);
for(i=0; a[i]!= '\0'; i++){
//cout<<a[i];
total++;
}
cout<<total;
for(i=0; i<r; i++){
key = a[total-1];
cout<<"key: "<<key<<endl;
for(i=total-2; i>=0; i--){
a[i+1] = a[i];
}
a[0] = key;
}
for(i=0; a[i]!= '\0'; i++){
cout<<a[i];
}
///cout<<a<<endl;
t++;
}
}
Here is a way of doing this using only iterators:
#include <string>
#include <iostream>
using namespace std;
int mod(int a, unsigned int b) {
int ret = a % b;
return ret>=0 ? ret : b + ret;
}
string rotate(const string sentence, int rotation) {
rotation = mod(rotation, sentence.size());
string rotatedSentence;
for(auto itr=sentence.begin(); itr < sentence.end(); ++itr) {
if (distance(sentence.begin(), itr) < rotation) {
rotatedSentence.push_back(*(itr + sentence.size() - rotation));
} else {
rotatedSentence.push_back(*(itr - rotation));
}
}
return rotatedSentence;
}
int main() {
const string sentence = "hello coding.";
cout << sentence << endl;
cout << rotate(sentence, 3) << endl; //prints ng.hello codi
return 0;
}
For starters, total C++ and coding noob here, apologies in advance. I've been working on a program that creates a concordance of a text file with the number of times a word occurs and on what lines the word occurs on. Brief example of the intended output:
A occurs 9 time(s) on lines 1 3 5
AND occurs 3 time(s) on lines 2 4
I first wrote the program using only arrays, which I've got running successfully. I'm now trying to rewrite it using vectors instead of arrays, and basically I have no idea what I'm doing past declaring the vectors. I've got my vector version to compile and link without errors, but when I run it I get a "segmentation fault 11" error. From what I understand, the reason this error is occurring because I'm trying to access memory that hasn't been allocated yet. I'm pasting my entire code that I've written so far below. If someone can help me out, or point me in the right director of what I need to do to make this happen, that'd be so awesome. I know I'll need to push the push_back method, but I just have no idea where. I realize this probably rudimentary to most of you, but I'm just trying to wrap my head around all of this. Again, thanks so much -
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void copy(vector<int> fromarr, vector< vector<int> > toarr, int index)
{
for (int i = 0; i <= fromarr[0]; i++)
{
toarr[index][i] = fromarr[i];
}
}
void copy(vector< vector<int> > fromarr, vector<int> toarr, int index)
{
for (int i = 0; i <= fromarr[index][0]; i++)
{
toarr[i] = fromarr[index][i];
}
}
int search(vector<string> array, int len, string target)
{
for(int i = 0; i < len; i++)
{
if(array[i] == target) return i;
}
return -1;
}
void sort(vector<string> wordarray, vector<int> linecount, vector< vector<int> > linenumbersarray, int length)
{
int minpos = 0;
for(int i = 0; i < length; i++)
{
minpos = i;
for (int j = 0; j < length; j++)
{
if(wordarray[j] > wordarray[minpos]) minpos = j;
string tempword = wordarray[i];
int tempcount = linecount[i];
vector<int> tempnums;
copy(linenumbersarray, tempnums, i);
wordarray[i] = wordarray[minpos];
linecount[i] = linecount[minpos];
copy(linenumbersarray[minpos], linenumbersarray, i);
wordarray[minpos] = tempword;
linecount[minpos] = tempcount;
copy(tempnums, linenumbersarray, minpos);
}
}
}
int main(int argc, char* argv[])
{
vector<string> wordarray;
vector<int> linecount;
vector< vector<int> > linenumbersarray;
int arrayposition = 0;
int linenumber = 1;
int wordlength = 0;
ifstream infile;
infile.open(argv[1]);
string aline;
while (getline(infile, aline))
{
istringstream theline(aline);
string aword;
while (theline >> aword)
{
int isupdated = search(wordarray, wordlength, aword);
if (isupdated == -1)
{
wordarray[wordlength] = aword;
linecount[wordlength] = 1;
linenumbersarray[wordlength][0] = 1;
linenumbersarray[wordlength][1] = linenumber;
wordlength = wordlength + 1;
}
else
{
linecount[isupdated] = linecount[isupdated] + 1;
if (linenumbersarray[isupdated][linenumbersarray[isupdated][0]] != linenumber)
(linenumbersarray[isupdated][++linenumbersarray[isupdated][0]] = linenumber);
}
}
linenumber = linenumber + 1;
}
sort(wordarray, linecount, linenumbersarray, wordlength);
for (int i = 0; i < wordlength; i++)
{
ostringstream out;
for (int j = 1; j <= linenumbersarray[i][0]; j++)
{
out << linenumbersarray[i][j];
j != linenumbersarray[i][0] ? out << " " : out << ".";
}
cout << wordarray[i] << " occurs " << linecount[i] << " time(s) on lines " << out.str() << endl;
out.flush();
}
}
How do you populate your vectors? Use push_back function to fill them in.
vector<int> v; // an empty container
v.push_back(10); // now it has one element - an integer 10
Use size() function to access a vector size, do not pass length parameter as you do in few functions (sort, search).
Another way to iterate through an stl container (vector is a container) is to use iterators.
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{ int a = *it; /*gives you an element of the container*/ }
Using size or iterators will prevent you from accessing unallocated memory - this is your problem.
Do not use operator [] without checking vector boundary.
if (i < v.size()) {v[i]; //an element}
Here are two variants of your search function
int search(vector<string> const &array, string const &target)
{
for(int i = 0; i < array.size(); i++)
{
if(array[i] == target) return i;
}
return -1;
}
vector<string>::const_iterator search(vector<string> const &array, string const &target)
{
for(vector<string>::const_iterator it = array.begin(); it != array.end(); ++it)
{
if(*it == target) return it;
}
return array.end();
}
A better way of searching is to use std::find function, but you may leave that for later when you are more comfortable with STL. std::find does the same as second variant of search above.
vector<string>::iterator it;
it = find (myvector.begin(), myvector.end(), target);
if (it != myvector.end())
std::cout << "Element found in myvector: " << *it << '\n';
else
std::cout << "Element not found in myvector\n";
I am trying to convert this code that works for '0' - '3' strings to integer so that it will work for higher numbers
#include <string>
#include <iostream>
using namespace std;
void permutate(char[], int );
bool recurse(char[], int );
int main()
{
int strLength;
cout << "Enter your desired length: ";
cin >> strLength;
char strArray[strLength];
for (int i = 0; i<strLength; i++)
strArray[i] = '0';
permutate(strArray, sizeof(strArray));
return 0;
}
void permutate(char charArray[], int length)
{
string wait;
length--;
bool done = false;
while(!done)
{
for (int i = 0; i <= length; i++)
cout << charArray[i];
cout << endl;
if (charArray[length] == '3')
done = recurse(charArray, length);
else
charArray[length] = (char)(charArray[length]+1);
}
}
bool recurse(char charArray[], int length)
{
bool done = false;
int temp = length;
if (temp > 1)
{
charArray[temp] = '0';
if (charArray[temp-1] == '3')
{
temp--;
done = recurse(charArray, temp);
}
else
(charArray[temp-1] = (char)(charArray[temp-1] + 1));
}
else
{
charArray[temp] = '0';
if (charArray[temp-1] == '3')
done = true;
else
charArray[temp-1] = (char)(charArray[temp-1]+1);
}
return done;
}
I changed every char to int,
every '0' = 0, '3' = 3
every (charArray[temp-1] = (char)(charArray[temp-1] + 1)); to charArray[temp-1]++;
I tried to debug but I still can`t make it work :(
Manged to fix it( works for high numbers):
#include <string>
#include <iostream>
using namespace std;
void permutate(int[], int, int );
bool recurse(int[], int, int );
int main()
{
int strLength, nrElem;
cout << "Enter your desired length: ";
cin >> strLength;
cout << "Enter nr elem: ";
cin >> nrElem;
int strArray[strLength];
for (int i = 0; i<strLength; i++)
strArray[i] = 0;
permutate(strArray, strLength, nrElem );
cout << "\nSTOP";
return 0;
}
void permutate(int charArray[], int length, int nrElem)
{
// length--;
bool done = false;
while(!done)
{
for (int i = 0; i < length; i++)
cout << charArray[i] << " ";
cout << endl;
if (charArray[length - 1] == nrElem)
//done = true;
done = recurse(charArray, length, nrElem);
else
charArray[length - 1]++;
}
}
bool recurse(int charArray[], int length, int nrElem)
{
bool done = false;
int temp = length ;
if (temp > 1)
{
charArray[temp] = 0;
if (charArray[temp-1] == nrElem)
{
temp--;
done = recurse(charArray, temp, nrElem);
}
else
charArray[temp-1]++;
}
else
{
charArray[temp] = 0;
if (charArray[temp-1] == nrElem)
done = true;
else
charArray[temp-1]++;
}
return done;
}
In your permutate function, you're incrementing charArray[length] but checking to see if charArray[length - 1] is equal to nrElem, so you never end up calling recurse.
Here is a short piece of code to do the same (not an answer, however it did not look right in a comment field), not sure if you need the recursion, if you do not this code may be of interest:
#include <iostream>
#include <sstream>
using namespace std;
string output(int firstIntSize, int secondIntSize)
{
std::ostringstream oss;
for (int i = 0; i<firstIntSize; i++)
{
for (int j = 0; j< secondIntSize; j++)
{
oss << i << j << " ";
}
}
return oss.str();
}
int main()
{
cout << output(2,3);
return 0;
}
hmmm... Why not simply make a Permutations algorithm and then use a generic function to print whatever you are permutating. Here's how I would do it for strings:
#include <iostream>
#include <string>
template<class T>
void print(T * A, unsigned n){ //for printing purposes
for(unsigned i=0;i<n;i++){
std::cout<<A[i]<<" ";
}
std::cout<<std::endl;
}
void generate_permutations(unsigned k, std::string str, char *A, bool *U){
// k is the position that we need to fill, starts from 0 and goes to the end.
if(k<str.size()) //if k==str.size() then we will print it
for(unsigned i=0;i<str.size();i++){
if(U[i]==0){
A[k]=str[i]; U[i]=1;
generate_permutations(k+1, str, A,U);
U[i]=0; //after the recursion is finished and printed, we can release the letter.
}
}
else
print(A,str.size());
}
int main(){
std::string str;
std::cout<<"Enter the string to be permutated: \n";
std::cin>>str;
int n;
n = str.length(); // You don't really need to ask the user the size of the string he/she wants to enter.
bool *U; // we will keep track of the used letters with the help of this boolean vector
char *A; // we will copy the contents of str here, so that we keep the str intact
U = new bool[n];
for (int i=0;i<n;i++) U[i]=false;
A = new char[n];
for (int i=0;i<n;i++) A[i]=str[i];
generate_permutations(0,str,A,U);
return 0;
}
Now if you want to convert to numbers (ints), it's almost the same:
#include <iostream>
template<class T>
void print(T * A, int n){
for(int i=0;i<n;i++){
std::cout<<A[i]<<" ";
}
std::cout<<std::endl;
}
void generate_permutations(int k, int *A, bool *U, int n){
if(k==n)
print(A,n);
else {
for(int i=0;i<n;i++){
if(U[i]==0){
A[k]=i; U[i]=1;
generate_permutations(k+1,A,U,n);
U[i]=0;
}
}
}
}
int main(){
int n;
std::cout<<"Permutations of how many objects? \n";
std::cin>>n;
int * A;
bool *U;
A = new int[n];
U = new bool[n];
for (int i=0;i<n;i++) U[i]=false;
print(U, n);
generate_permutations(0,A,U,n);
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