I basically want to create strings that consist of three operation symbols (eg: +-* or ++/ or +++). Each one of these strings should be pushed into vector <string> opPermutations
This is my code so far:
// Set up permutations for operators
string operatorBank[4] = {"+","-","*","/"};
do {
string currentPerm = operatorBank[0] + operatorBank[1] + operatorBank[2] + operatorBank[3];
this -> opPermutations.push_back(currentPerm);
} while ( std::next_permutation(operatorBank, operatorBank + 4) );
The permutations that are pushed into the vector (as strings) are:
+-*/
+-/*
+/*-
+/-*
-*+/
-*/+
-+*/
-+/*
-/*+
-/+*
/*+-
/*-+
/+*-
/+-*
/-*+
/-+*
What I want however is to have my permutations exist like this:
Each should be three characters in length
Every possible permutation, including the ones in which a character is repeated more than one time, must be present.
I want it to be organized as such:
+++
---
***
///
/*/
+-+
++*
**/
etc...
How can I achieve this?
Using the recursion to print what you asked. Adapting it to store permutation string in vectors should be trivial. I am not a c++ programmer,so there may be better way to do it in C++. but the main idea here is to use recursion.
#include <iostream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void displayPermutation(string permutation[], int length){
int i;
for (i=0;i<length;i++){
cout<<permutation[i];
}
cout << endl;
}
void getPermutations(string operatorBank[], int operatorCount,
string permutation[],int permutationLength, int curIndex){
int i;
//stop recursion condition
if(curIndex == permutationLength){
displayPermutation(permutation,permutationLength);
}
else{
for(i = 0; i < operatorCount; i++){
permutation[curIndex] = operatorBank[i];
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex+1);
}
}
}
int main ()
{
int operatorCount = 4;
int permutationLength = 3;
string operatorBank[] = {"+","-","*","/"};
string permutation[] = {"","","",""}; //empty string
int curIndex = 0;
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex);
return 0;
}
output:
+++
++-
++*
++/
+-+
+--
+-*
+-/
+*+
+*-
+**
+*/
+/+
+/-
+/*
+//
.
.
and so on.
Strings with repeated elements are not possible permutations, because a permutation is an ordering.
You can do this with 3 nested for loops as wlyles said.
Edited to add:
This will print the strings I think you want. You can replace the cout statement with opPermutations.push_back(operatorBank[i]+operatorBank[j]+operatorBank[k]) to add to the vector.
#include <iostream>
#include <string>
int main(){
std::string operatorBank[4] = {"+","-","*","/"};
for (int i=0; i<4; ++i){
for (int j=0; j<4; ++j){
for (int k=0; k<4; ++k){
std::cout << operatorBank[i] << operatorBank[j] << operatorBank[k] << std::endl;
}
}
}
return 0;
}
I think maybe the confusion is over the term "permutation." You could get the same strings as 3-permutations of the set {"+","+","+","-","-","-","*","*","*","/","/","/"} but using loops seems simpler to me.
Easiest way to generate permutations is Set Product ..
list<string> setProduct (list<string> a, list<string> b)
{
list<string> L;
list<string>::iterator i, j;
for(i = a.begin(); i != a.end(); ++i)
for(j = b.begin(); j != b.end(); ++j)
L.push_front(*i + *j);
return L;
}
list<string> permute (list<string> a, int len)
{
list<string> L;
while (len --> 0) L.splice(a.end(), setProduct(L,a));
return L;
}
Related
I need to output a group of letters that are that are out of order with respect to the number of inversions of each other.
For example, the sequence “AACEDGG” has only 1 inversion (E and D) while the sequence “ZWQM” has 6 inversions. I don't actually have to sort it out but I have to output them based on the number of inversions they have.
Ex:
Input: AACATGAAGG TTTTGGCCAA TTTGGCCAAA GATCAGATTT CCCGGGGGGA ATCGATGCAT
Output: CCCGGGGGGA AACATGAAGG GATCAGATTT ATCGATGCAT TTTTGGCCAA TTTGGCCAAA
I am trying to use insertion sort as a template as required by my teacher.
void inversionChecker(string dna[], int n)
{
int j,k,m;
int tempCount;
for(int i=0; i < n; i++){
int count=0;
for(j=0;j < n; j++){
for(k=j+1; k <= n; k++){
if(dna[i][j] > dna[i][k]){
count++;
tempCount = count;
}
}
}
if(i != 0 && tempCount > count)
dna[i].swap(dna[i-1]);
}
}
I am having issues because I am not too familiar using 2D arrays to compare the letters in each string. When I try to output the array it ends up being blank, seg faults, or errors resulting from my use trying to swap the positions of the strings in the array.
Any help would be appreciated
Here you access the dna array out-of-bounds:
for(j=0;j < n; j++){
for(k=j+1; k <= n; k++){ // when k == n you have undefined behavior
if(dna[i][j] > dna[i][k])
it should be:
for(j=0;j < n-1; j++){
for(k=j+1; k < n; k++){
if(dna[i][j] > dna[i][k])
An alternative approach using misc. standard classes and algorithms, like std::vector and std::sort.
#include <algorithm> // copy, sort
#include <cstddef> // size_t
#include <iterator> // istream_iterator, back_inserter
#include <sstream> // istringstream
#include <string> // string
#include <tuple> // tie
#include <utility> // swap
#include <vector> // vector
#include <iostream>
// count inversions in a sequence
unsigned count_inversions(std::string sequence) {
unsigned res = 0;
// assuming "inversions" are defined as the number of swaps needed in bubblesort
for(size_t i = 0; i < sequence.size() - 1; ++i) {
for(size_t j = i + 1; j < sequence.size(); ++j) {
if(sequence[j] < sequence[i]) {
std::swap(sequence[i], sequence[j]);
++res;
}
}
}
return res;
}
// a class to store a sequence and its inversion count
struct sequence_t {
sequence_t() = default;
explicit sequence_t(const std::string& Seq) :
seq(Seq), inversions(count_inversions(seq)) {}
// "less than" operator to compare two "sequence_t"s (used in std::sort)
bool operator<(const sequence_t& rhs) const {
// assuming lexicographical order if inversions are equal
return std::tie(inversions, seq) < std::tie(rhs.inversions, rhs.seq);
}
std::string seq;
unsigned inversions;
};
// read one sequence_t from an istream
std::istream& operator>>(std::istream& is, sequence_t& s) {
std::string tmp;
if(is >> tmp) s = sequence_t(tmp);
return is;
}
// read "sequence_t"s from an istream and put in a vector<sequence_t>
auto read_sequences(std::istream& is) {
std::vector<sequence_t> rv;
std::copy(std::istream_iterator<sequence_t>(is),
std::istream_iterator<sequence_t>{}, std::back_inserter(rv));
return rv;
}
int main() {
std::istringstream input(
"AACATGAAGG TTTTGGCCAA TTTGGCCAAA GATCAGATTT CCCGGGGGGA ATCGATGCAT");
auto sequences = read_sequences(input);
std::sort(sequences.begin(), sequences.end());
// print result
for(const auto& [seq, inversions] : sequences) {
std::cout << seq << '(' << inversions << ')' << ' ';
}
std::cout << '\n';
}
Output (including the inversions):
CCCGGGGGGA(2) AACATGAAGG(10) GATCAGATTT(10) ATCGATGCAT(11) TTTTGGCCAA(12) TTTGGCCAAA(15)
EDIT: Thank you so much everyone, songyuanyao Answered my question, and you guys did lol but i didnt know some codes u put and im sure soon i will learn them :) thanks again.
i really have a question about removing duplicated Names in a string, note that im fairly new to c++, anyways i'll get to the point.
what im trying to do is removing duplicated names in an array, the code below is working fine but here's what im facing.
For example i entered 4 names: (Hana, Alex, Hana, Alex) the results that i want to get is just : ( Hana and Alex) while the other 2 names should be removed yet what im getting is ( Hana , Alex, Alex).
im really confused about what should i do to fix this and i want it to check every name in the list, Thanks in advance :).
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
string nurse[4];
int i, n=3, j, k, num;
int main()
{
cout << "Please Enter names to add to the list --->";
for (i = 0; i <= n; i++)
{
cin >> nurse[i];
}
for (int i = 0; i < n; i++)
{
for (j = i + 1; j < n;)
if (nurse[j] == nurse[i])
{
for (k = j; k < n; k++)
{
nurse[k] = nurse[k + 1];
}
n--;
}
else
{
j++;
}
}
cout << "Printing list after removing duplicated names" << endl;
for (i = 0; i <= n; i++)
cout << " "<<nurse[i] << endl;
system("pause");
return 0;
}
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// ...
vector<string> nurses;
nurses.push_back("Hana");
nurses.push_back("Alex");
nurses.push_back("Hana");
nurses.push_back("Alex");
sort(nurses.begin(), nurses.end());
const vector<string>::iterator it = unique(nurses.begin(), nurses.end());
nurses.erase(it, nurses.end());
Say you start with
vector<string> v{"alex", "emma", "alex"};
Define an unordered_set with these items:
unordered_set<string> h;
Now use the erase-remove idiom using
[&h](const string &s){return !h.insert(s).second;};
This will do the job in (expected) linear time.
Full example:
#include <string>
#include<vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
int main()
{
vector<string> v{"alex", "emma", "alex"};
unordered_set<string> h;
auto r = [&h](const string &s){return !h.insert(s).second;};
v.erase(remove_if(begin(v), end(v), r), end(v));
}
You condition in for is one less than the count of the elements, so the last element won't be checked at all.
for (int i = 0; i <= n; i++)
~
{
for (j = i + 1; j <= n;)
~
if (nurse[j] == nurse[i])
{
for (k = j; k <= n; k++)
~
{
nurse[k] = nurse[k + 1];
}
n--;
}
else
{
j++;
}
}
You are effectively not removing names from your array. You are just shifting them in case same name comes!
You could actually use a std::set which will automatically do this for you!
std::set< std::string > nurses;
std::string nurse;
for (i = 0; i <= n; i++)
{
std::cin >> nurse;
nurses.insert( nurse );
}
Do not forget to include <set> in your code.
I'm trying to delete all elements of an array that match a particular case.
for example..
if(ar[i]==0)
delete all elements which are 0 in the array
print out the number of elements of the remaining array after deletion
what i tried:
if (ar[i]==0)
{
x++;
}
b=N-x;
cout<<b<<endl;
this works only if i want to delete a single element every time and i can't figure out how to delete in my required case.
Im assuming that i need to traverse the array and select All instances of the element found and delete All instances of occurrences.
Instead of incrementing the 'x' variable only once for one occurence, is it possible to increment it a certain number of times for a certain number of occurrences?
edit(someone requested that i paste all of my code):
int N;
cin>>N;
int ar[N];
int i=0;
while (i<N) {
cin>>ar[i];
i++;
}//array was created and we looped through the array, inputting each element.
int a=0;
int b=N;
cout<<b; //this is for the first case (no element is deleted)
int x=0;
i=0; //now we need to subtract every other element from the array from this selected element.
while (i<N) {
if (a>ar[i]) { //we selected the smallest element.
a=ar[i];
}
i=0;
while (i<N) {
ar[i]=ar[i]-a;
i++;
//this is applied to every single element.
}
if (ar[i]==0) //in this particular case, we need to delete the ith element. fix this step.
{
x++;
}
b=N-x;
cout<<b<<endl;
i++;
}
return 0; }
the entire question is found here:
Cut-the-sticks
You could use the std::remove function.
I was going to write out an example to go with the link, but the example form the link is pretty much verbatim what I was going to post, so here's the example from the link:
// remove algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::remove
int main () {
int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20
// bounds of range:
int* pbegin = myints; // ^
int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^
pend = std::remove (pbegin, pend, 20); // 10 30 30 10 10 ? ? ?
// ^ ^
std::cout << "range contains:";
for (int* p=pbegin; p!=pend; ++p)
std::cout << ' ' << *p;
std::cout << '\n';
return 0;
}
Strictly speaking, the posted example code could be optimized to not need the pointers (especially if you're using any standard container types like a std::vector), and there's also the std::remove_if function which allows for additional parameters to be passed for more complex predicate logic.
To that however, you made mention of the Cut the sticks challenge, which I don't believe you actually need to make use of any remove functions (beyond normal container/array remove functionality). Instead, you could use something like the following code to 'cut' and 'remove' according to the conditions set in the challenge (i.e. cut X from stick, then remove if < 0 and print how many cuts made on each pass):
#include <iostream>
#include <vector>
int main () {
// this is just here to push some numbers on the vector (non-C++11)
int arr[] = {10,20,30,30,20,10,10,20}; // 8 entries
int arsz = sizeof(arr) / sizeof(int);
std::vector<int> vals;
for (int i = 0; i < arsz; ++i) { vals.push_back(arr[i]); }
std::vector<int>::iterator beg = vals.begin();
unsigned int cut_len = 2;
unsigned int cut = 0;
std::cout << cut_len << std::endl;
while (vals.size() > 0) {
cut = 0;
beg = vals.begin();
while (beg != vals.end()) {
*beg -= cut_len;
if (*beg <= 0) {
vals.erase(beg--);
++cut;
}
++beg;
}
std::cout << cut << std::endl;
}
return 0;
}
Hope that can help.
If you have no space bound try something like that,
lets array is A and number is number.
create a new array B
traverse full A and add element A[i] to B[j] only if A[i] != number
assign B to A
Now A have no number element and valid size is j.
Check this:
#define N 5
int main()
{
int ar[N] = {0,1,2,1,0};
int tar[N];
int keyEle = 0;
int newN = 0;
for(int i=0;i<N;i++){
if (ar[i] != keyEle) {
tar[newN] = ar[i];
newN++;
}
}
cout<<"Elements after deleteing key element 0: ";
for(int i=0;i<newN;i++){
ar[i] = tar[i];
cout << ar[i]<<"\t" ;
}
}
Unless there is a need to use ordinary int arrays, I'd suggest using either a std::vector or std::array, then using std::remove_if. See similar.
untested example (with c++11 lambda):
#include <algorithm>
#include <vector>
// ...
std::vector<int> arr;
// populate array somehow
arr.erase(
std::remove_if(arr.begin(), arr.end()
,[](int x){ return (x == 0); } )
, arr.end());
Solution to Cut the sticks problem:
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
// Cuts the sticks by size of stick with minimum length.
void cut(vector<int> &arr) {
// Calculate length of smallest stick.
int min_length = INT_MAX;
for (size_t i = 0; i < arr.size(); i++)
{
if (min_length > arr[i])
min_length = arr[i];
}
// source_i: Index of stick in existing vector.
// target_i: Index of same stick in new vector.
size_t target_i = 0;
for (size_t source_i = 0; source_i < arr.size(); source_i++)
{
arr[source_i] -= min_length;
if (arr[source_i] > 0)
arr[target_i++] = arr[source_i];
}
// Remove superfluous elements from the vector.
arr.resize(target_i);
}
int main() {
// Read the input.
int n;
cin >> n;
vector<int> arr(n);
for (int arr_i = 0; arr_i < n; arr_i++) {
cin >> arr[arr_i];
}
// Loop until vector is non-empty.
do {
cout << arr.size() << endl;
cut(arr);
} while (!arr.empty());
return 0;
}
With a single loop:
if(condition)
{
for(loop through array)
{
if(array[i] == 0)
{
array[i] = array[i+1]; // Check if array[i+1] is not 0
print (array[i]);
}
else
{
print (array[i]);
}
}
}
My problem looks like this:
At the beginning u have to insert an amount of numbers.
Next program counts the sum of digits of the number that u inserted in step one.
All scores are inserted in vector called vec
The problem is this: At the end of the program all numbers that You inserted in steps 1, must be sorted depends of theirs sums of digits(Sorting in increasing order).
And ATTENTION please! For example if two of numbers(e.g. 123 and 12300) have the same sum of digits you have to sort them by the lexicographic order.
I don't want to create function build by myself but I would like to use “sort” function from library but I have problem with that..Is it possible to use sort function also to sorting by the lexicographic order? Can someone can help me?
Example input:
6
13
36
27
12
4
123
Expected output:
12
13
4
123
27
36
My code:
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<sstream>
#include<algorithm>
using namespace std;
int main()
{
vector<vector<int> > vec;
int num;
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> num;
vector<int> row;
row.push_back(num);
//conversion int to string:
ostringstream ss;
ss << num;
string str = ss.str();
int sum = 0;
for (int g = 0; g < str.length(); g++){
int pom = str[g] - '0';
sum += pom;
}
row.push_back(sum);
vec.push_back(row);
row.clear();
}
//sort(vec[0][0], vec[vec.size()][0]);
for (int i = 0; i < vec.size(); i++){
for (int j = 0; j < 2; j++){
//cout << vec[i][j] << " ";
}
cout << vec[i][0] << endl;
}
system("pause");
return 0;
}
You could store each number as a string, but also pre-compute its digit-sum and keep both in a pair<int,string>, then put them into a vector<pair<int,string> and sort it. No need for a custom comparator, the one for std::pair does exactly what you want.
// note: std::pair<std::string,int> would not work
typedef std::pair<int,std::string> number;
std::vector<number> numbers;
// fill numbers such that number::first holds the digit sum
// and number::second the number as string.
// this is similar to your code
std::sort(numbers.begin(), numbers.end());
// now numbers are ordered as you want them
Just pass a suitable comparison function (or functor, e.g. a lambda would be natural) to std::sort.
Since you want to compare on sum of digits first and then lexicographically to break ties, it will be convenient to convert your input numbers to strings.
From there you can define a custom comparator to achieve the desired behavior:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int sumDigits(string s)
{
int sum = 0;
for (unsigned int i=0; i<s.length(); ++i)
{
sum += s[i] - '0';
}
return sum;
}
bool digitSumComparator(int i, int j)
{
int iSum = sumDigits(to_string(i));
int jSum = sumDigits(to_string(j));
if (iSum == jSum)
{
return iStr < jStr;
}
else
{
return iSum < jSum;
}
}
int main()
{
vector<int> v {6,13,36,27,12,4,123};
sort(v.begin(), v.end(), digitSumComparator);
for (vector<int>::iterator it=v.begin(); it!=v.end(); ++it)
{
cout << *it << ' ';
}
cout << '\n';
return 0;
}
Output:
$ g++ -std=c++11 digitsumsort.cpp
$ ./a.out
12 13 4 123 6 27 36
I need to generate all permutation of a string with selecting some of the elements. Like if my string is "abc" output would be { a,b,c,ab,ba,ac,ca,bc,cb,abc,acb,bac,bca,cab,cba }.
I thought a basic algorithm in which I generate all possible combination of "abc" which are {a,b,c,ab,ac,bc,abc} and then permute all of them.
So is there any efficient permutation algorithm by which I can generate all possible permutation with varying size.
The code I wrote for this is :
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
using namespace std;
int permuteCount = 1;
int compare (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b);
}
void permute(char *str, int start, int end)
{
// cout<<"before sort : "<<str;
// cout<<"after sort : "<<str;
do
{
cout<<permuteCount<<")"<<str<<endl;
permuteCount++;
}while( next_permutation(str+start,str+end) );
}
void generateAllCombinations( char* str)
{
int n, k, i, j, c;
n = strlen(str);
map<string,int> combinationMap;
for( k =1; k<=n; k++)
{
char tempStr[20];
int index =0;
for (i=0; i<(1<<n); i++) {
index =0;
for (j=0,c=0; j<32; j++) if (i & (1<<j)) c++;
if (c == k) {
for (j=0;j<32; j++)
if (i & (1<<j))
tempStr[ index++] = str[j];
tempStr[index] = '\0';
qsort (tempStr, index, sizeof(char), compare);
if( combinationMap.find(tempStr) == combinationMap.end() )
{
// cout<<"comb : "<<tempStr<<endl;
//cout<<"unique comb : \n";
combinationMap[tempStr] = 1;
permute(tempStr,0,k);
} /*
else
{
cout<<"duplicated comb : "<<tempStr<<endl;
}*/
}
}
}
}
int main () {
char str[20];
cin>>str;
generateAllCombinations(str);
cin>>str;
}
I need to use a hash for avoiding same combination, so please let me know how can I make this algorithm better.
Thanks,
GG
#include <algorithm>
#include <iostream>
#include <string>
int main() {
using namespace std;
string s = "abc";
do {
cout << s << '\n';
} while (next_permutation(s.begin(), s.end()));
return 0;
}
Next_permutation uses a constant size, but you can add a loop to deal with varying size. Or just store in a set to eliminate the extra dupes for you:
#include <set>
int main() {
using namespace std;
string s = "abc";
set<string> results;
do {
for (int n = 1; n <= s.size(); ++n) {
results.insert(s.substr(0, n));
}
} while (next_permutation(s.begin(), s.end()));
for (set<string>::const_iterator x = results.begin(); x != results.end(); ++x) {
cout << *x << '\n';
}
return 0;
}
I don't think you can write much faster program than you have already. The main problem is the output size: it has order of n!*2^n (number of subsets * average number of permutations for one subset), which is already > 10^9 for a string of 10 different characters.
Since STL's next_permutation adds very limited complexity for such small strings, your program's time complexity is already nearly O(output size).
But you can make your program a bit simpler. In particular, for( k =1; k<=n; k++) loop seems unnecessary: you already calculate size of subset in variable c inside. So, just have int k = c instead of if (c == k). (You'll also need to consider case of empty subset: i == 0)
edit
Actually, there's only 9864100 outputs for n == 10 (not ~ 10^9). Still, my point remains the same: your program already wastes only "O(next_permutation)" time for each output, which is very, very little.