permutation of an array of strings in c++ - c++

I have this code to do permutations of a string.
#include <iostream>
#include <string.h>
using namespace std;
/* Prototipo de función */
void Permutaciones(char *, int l=0);
void sort(string scadena[]);
//array global to copy all permutations and later sort
string array[900000];
int m=0;
int main() {
int casos;
cin>>casos;
char palabra[casos][13];
for(int i=0;i<casos;i++)
cin>>palabra[i];
for(int i=0;i<casos;i++){
m=0;
Permutaciones(palabra[i]);
sort(array);
}
sort(array);
system("pause");
return 0;
}
void sort(string scadena[]){
string temp;
for(int i=0;i<m;i++){
for(int j=i+1;j<m;j++){
if(scadena[i]>scadena[j]){
temp=scadena[i];
scadena[i]=scadena[j];
scadena[j]=temp;
}
}
}
for(int i=0;i<m;i++){
for(int j=1;j<m;j++){
if(scadena[i]==scadena[j] && j!=i){
for(int k=j;k <m; k++){
scadena[k]=scadena[k+1];
}
m--;
j--;
}
}
}
for(int i=0;i<m;i++){
cout<<scadena[i]<<endl;
}
}
void Permutaciones(char * cad, int l) {
char c; /* variable auxiliar para intercambio */
int i, j; /* variables para bucles */
int n = strlen(cad);
for(i = 0; i < n-l; i++) {
if(n-l > 2){
Permutaciones(cad, l+1);
}
else {
array[m]=cad;
m++;
}
/* Intercambio de posiciones */
c = cad[l];
cad[l] = cad[l+i+1];
cad[l+i+1] = c;
if(l+i == n-1) {
for(j = l; j < n; j++){
cad[j] = cad[j+1];
}
cad[n] = 0;
}
}
}
And the code generates all permutations fine, and later sorted the array and it works fine. But when i am intenting remove the repeated strings, the code show me somethings repeated, and not sorted.
Who can say me what is my error?

You could have accomplished it easier using standard library:
#include <algorithm>
using namespace std;
int main() {
int a[] = {1, 2, 5, 6, 7};
int n = 5;
do {
// print array a
} while (next_permutation(a, a + n));
}
Unless the task was to implement it on your own. And of course make sure your array is sorted before you try to permutate it in this way, otherwise you will miss some permutations.

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.

Related

generate a list of all possible combinations and randomly select a combination from the list

I found this code online on tutorials point. link https://www.tutorialspoint.com/cplusplus-program-to-generate-all-possible-combinations-out-of-a-b-c-d-e.
I tried to think of how to modify it so that it would randomly a single combination from the generated list, but I'm haven't figured it out yet.
#include<iostream>
using namespace std;
void Combi(char a[], int reqLen, int s, int currLen, bool check[], int l)
{
if(currLen > reqLen)
return;
else if (currLen == reqLen) {
cout<<"\t";
for (int i = 0; i < l; i++) {
if (check[i] == true) {
cout<<a[i]<<" ";
}
}
cout<<"\n";
return;
}
if (s == l) {
return;
}
check[s] = true;
Combi(a, reqLen, s + 1, currLen + 1, check, l);
check[s] = false;
Combi(a, reqLen, s + 1, currLen, check, l);
}
int main() {
int i,n;
bool check[n];
cout<<"Enter the number of element array have: ";
cin>>n;
char a[n];
cout<<"\n";
for(i = 0; i < n; i++) {
cout<<"Enter "<<i+1<<" element: ";
cin>>a[i];
check[i] = false;
}
for(i = 1; i <= n; i++) {
cout<<"\nThe all possible combination of length "<<i<<" for the given array set:\n";
Combi(a, i, 0, 0, check, n);
}
return 0;
}
im not a c++ specialist, but i think you should add a random number from -ArrayLenght to ArrayLenght, at least this works in python(which is written in c++)
i hope i understood your question right

spiral matrix breaks on the last "for" loop and doesn't show anything

#include<iostream>
using namespace std;
int main()
{
int n;
cout<<"Enter the size of the array :";
cin>>n;
int A[n][n];
int y=n,k=1,p=0,i;
while(k<=n*n)
{
for(i=p;i < y;i++)
{
A[y-1][i]=k++;
}
for(i=y - 2;i > p;i--)
{
A[i][y-1]=k++;
}
for(i=y - 2;i > p;i--)
{
A[p][i]=k++;
}
for(i = p + 1;i < y; i++)
{
A[i][p]=k++;
}
p++;
y--;
}
if(!n%2)
{
A[(n+1)/2][(n+1)/2]=n*n;
}
for(i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<A[i][j]<<"\t";
}
cout<<endl;
}
return 0;
I need to do a spiral matrix the way like this > enter image description here.
It breaks on the last "for" cycle and just doesn't show anything;;; Still, it shows up if I'm replacing one of the loop's statements;; I would be grateful if you point me where's my mistake!
(this code is a modified one brought from here https://www.includehelp.com/cpp-programs/print-a-spiral-matrix.aspx)
There were simply some little mistakes on the bounds of the loops (the bounds of the spiral). Here is a slightly modified programme.
PS: Note that you should avoid to use VMA int A[n][n] which is C, not C++.
#include<iostream>
//using namespace std;
int main()
{
int n;
std::cout << "Enter the size of the array :";
std::cin >> n;
int A[n][n];
int y = n, k = 1,p = 0,i;
while(k<= n*n)
{
for(i=p;i < y;i++)
{
A[y-1][i]=k++;
}
for(i=y - 2;i >= p;i--)
{
A[i][y-1]=k++;
}
for(i = y - 2;i >= p;i--)
{
A[p][i]=k++;
}
for(i = p + 1;i < y-1; i++)
{
A[i][p]=k++;
}
p++;
y--;
}
if(!n%2)
{
A[(n+1)/2][(n+1)/2]=n*n;
}
for(i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
std::cout<<A[i][j]<<"\t";
}
std::cout << "\n";
}
return 0;
}

2d pointer initializing in [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have this data member in my class:cell** rep. I want to set size of the 2d in constructor. I receive no error while compiling; but no result comes when i run it.
//main.cpp
#include <ctime>
#include <cstdlib>
#include "cell.h"
#include "world.h"
using namespace std;
int main(){
srand(time(0));
World Conway(6,6);
Conway.generateWorld();
int numAlive = 1;
do{
numAlive = Conway.print();
Conway.nextGeneration();
cout<<"\n\t\t\t*****************\n\n";
cin.get();
}while(numAlive);
cin.get();
return 0;
}
//cell.h
#ifndef CELL_H
#define CELL_H
class Cell {
private :
bool alive;
public :
Cell() ;
void setAlive(bool b);
bool isAlive();
};
#endif
//cell.cpp
#include "cell.h" // class's header file
Cell::Cell(){
alive = false;
}
void Cell::setAlive(bool b){
alive = b;
}
bool Cell::isAlive(){
return alive;
}
//world.h
#ifndef WORLD_H
#define WORLD_H
#include "Cell.h"
class World {
private :
bool ring;
int lines, columns ;
Cell** rep; //I could not write this with pointer
public :
World (int l, int c) ;
World (int l, int c, bool ring);
~World() ;
int getLines();
int getColumns();
void generateWorld();
int nbAliveNeighbor( int i, int j) ;
int nbAliveNeighborRing( int i, int j);
void nextGeneration();
int print(); //the output of this function help me to end main loop
} ;
#endif
//world.cpp
#include "world.h" // class's header file
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
World::World (int l, int c) {
lines = l;
columns = c;
ring = false;
Cell **rep = 0;
// memory allocated for elements of rows.
rep = new Cell *[l];
// memory allocated for elements of each column.
for( int i = 0 ; i < l ; i++ ) {
rep[i] = new Cell[c];
}
}
World::World(int l,int c,bool r){
lines = l;
columns = c;
ring = r;
}
int World::getLines(){
return lines;
}
int World::getColumns(){
return columns;
}
int World::nbAliveNeighborRing( int i, int j){
int n = 0; //number of alives
for(int r = i-1; r < i+2; r++){
for(int c = j-1; c < j+2; c++){
//giving ring flexibility
if(c < 0)
c + columns;
if(c >= columns)
c - columns;
if(r < 0)
r + lines;
if(r >= lines)
r - lines;
if(c==j && r ==i)
continue; //ignoring the cell itself
if(rep[r][c].isAlive())
n++;
}
}
return n;
}
int World::nbAliveNeighbor( int i, int j) {
int n = 0; //number of alives
for(int r = i-1; r < i+2; r++){
for(int c = j-1; c < j+2; c++){
//ignoring if it's out of range
if(c < 0 || c >= columns)
continue;
if(r < 0 || r >= lines)
continue;
//ignoring the cell itself
if(c==j && r ==i)
continue;
if(rep[r][c].isAlive())
n++;
}
}
return n;
}
int random(int a,int b){
return a+rand()%(b-a+1); //including a & b
}
void World::generateWorld(){
int nAlive = (lines * columns)/ 4 + 1;
//why plus 1:
// because in random some are the same so we plus it with 1 so in the average
// the alive cells will be third of deads!
int randAry[nAlive];
for(int i=0, clm=0, row=0; i < nAlive; i++){
randAry[i] = random(0,lines*columns);
clm = 0;
row = 0;
while(randAry[i] >= lines){
row ++;
randAry[i] -= lines;
}
clm = randAry[i];
rep[row][clm].setAlive(true);
}
}
void World::nextGeneration(){
if(ring){
for(int i = 0; i < lines; i++){
for(int j = 0; j < columns; j++){
if(rep[i][j].isAlive()){
if(nbAliveNeighborRing(i,j) == 3 || nbAliveNeighborRing(i,j) == 2)
continue;
else
rep[i][j].setAlive(false);
}
else{
if(nbAliveNeighborRing(i,j) == 3)
rep[i][j].setAlive(true);
}
}
}
}
else{
for(int i = 0; i < lines; i++){
for(int j = 0; j < columns; j++){
if(rep[i][j].isAlive()){
if(nbAliveNeighbor(i,j) == 3 || nbAliveNeighbor(i,j) == 2){
continue;
}
else{
rep[i][j].setAlive(false);
}
}
else{
if(nbAliveNeighbor(i,j) == 3){
rep[i][j].setAlive(true);
}
}
}
}
}
}
int World::print(){
int n = 0;
for(int i = 0; i < lines; i++){
for(int j = 0; j < columns; j++){
if(rep[i][j].isAlive()){
cout<<" * ";
n++;
}
else
cout<<" - ";
}
cout<<endl;
}
return n;
}
World::~World(){
delete rep;
}
Your Cell** rep is never created. This should be done in the constructor. Now you're making int **rep = 0;, which doesn't seem to be used anywhere.
//int **rep = 0; //scratch this
rep = new Cell *[l];
// memory allocated for elements of each column.
for( int i = 0 ; i < l ; i++ ) {
rep[i] = new Cell[c];
}
Maybe that Cell.h is capitalized in include of world.h
In class World data member rep is defined as
class World {
private :
bool ring;
int lines, columns ;
Cell** rep; //I could not write this with pointer
...
However in the constructor you use a local variable rep that have type int ** and try to initialize that local variable that will be destroyed after exiting the constructor.
World::World (int l, int c) {
lines = l;
columns = c;
ring = false;
int **rep = 0;
// memory allocated for elements of rows.
rep = new int *[l];
// memory allocated for elements of each column.
for( int i = 0 ; i < l ; i++ ) {
rep[i] = new int[c];
}

Find all possible arrays of size n constructed with all possible combinations of elements from another array in all possible orders?

For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.

C++ Replace string to char[]

I have the following c++ program that multiple 2 large numbers :
#include <iostream>
#include <string>
#define OVERFLOW 2
#define ROW b_len
#define COL a_len+b_len+OVERFLOW
using namespace std;
int getCarry(int num) {
int carry = 0;
if(num>=10) {
while(num!=0) {
carry = num %10;
num = num/10;
}
}
else carry = 0;
return carry;
}
int num(char a) {
return int(a)-48;
}
string mult(string a, string b) {
string ret;
int a_len = a.length();
int b_len = b.length();
int mat[ROW][COL];
for(int i =0; i<ROW; ++i) {
for(int j=0; j<COL; ++j) {
mat[i][j] = 0;
}
}
int carry=0, n,x=a_len-1,y=b_len-1;
for(int i=0; i<ROW; ++i) {
x=a_len-1;
carry = 0;
for(int j=(COL-1)-i; j>=0; --j) {
if((x>=0)&&(y>=0)) {
n = (num(a[x])*num(b[y]))+carry;
mat[i][j] = n%10;
carry = getCarry(n);
}
else if((x>=-1)&&(y>=-1)) mat[i][j] = carry;
x=x-1;
}
y=y-1;
}
carry = 0;
int sum_arr[COL];
for(int i =0; i<COL; ++i) sum_arr[i] = 0;
for(int i=0; i<ROW; ++i) {
for(int j=COL-1; j>=0; --j) {
sum_arr[j] += (mat[i][j]);
}
}
int temp;
for(int i=COL-1; i>=0; --i) {
sum_arr[i] += carry;
temp = sum_arr[i];
sum_arr[i] = sum_arr[i]%10;
carry = getCarry(temp);
}
for(int i=0; i<COL; ++i) {
ret.push_back(char(sum_arr[i]+48));
}
while(ret[0]=='0'){
ret = ret.substr(1,ret.length()-1);
}
return ret;
}
void printhuge(string a) {
cout<<"\n";
for(string::iterator i = a.begin(); i!=a.end(); ++i) {
cout<<*i;
}
}
int main() {
string a,b;
cin>>a>>b;
printhuge(mult(a,b));
return 0;
}
All is working fine, but I need to use char[] instead of "string" . I know it's silly but I have to use that format necessary. So - how can I convert the code to work with char[] definition ?
Any ideas is greatly appreciated, Thanks :)
Provided you don't need to modify the C string (the char array), i. e. it can be const char[] or const char *, use the c_str() method of std::string:
const char *c_string = str.c_str();
Edit: so your problem is that you should not use std::string at all. Well, in this case, this is how you can replace C++ strings with C strings:
C strings are 0-terminated arrays of char (or const char). As usually, in certain conditions, they decay into pointers.
You can get the length of a C string using the strlen() function in <string.h>.
To append strings to each other, use the strcat() or strncat() functions. Beware of buffer sizes and the extra space for the terminating NUL character!
etc.
Call std::string::c_str() on your string objects.
Just make sure the buffer isn't modifed by the functions.
Edit
Or, if you need to accept a char[], just create a string out of it.