All Strings of {A,C,T,G} - c++

I'm currently working on a problem of solving the combination of the different length of {A,C,T,G}, from 1 letter to 6 letters.
For example:
------#=1------
1:A
2:C
3:G
4:T
------#=2------
1:AA
2:AC
3:AG
4:AT
5:CA
6:CC
7:CG
8:CT
9:GA
10:GC
11:GG
12:GT
13:TA
14:TC
15:TG
16:TT
------#=3------
1:AAA
2:AAC
3:AAG
4:AAT
5:ACA
.
.
.
Now I can only solve the combinations from 1 to 4 letters, and I have no idea how to solve the combination of {A,C,T,G} of 5 letters and 6 letters, which the length of the combination(5 and 6) is greater than the length of all the strings(4)....
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
void combinationUtil(char arr[], char data[], int start, int end, int index, int r);
void printCombination(char arr[], int n, int r)
{
char data[100];
combinationUtil(arr, data, 0, n-1, 0, r);
}
void combinationUtil(char arr[], char data[], int start, int end, int index, int r)
{
if (index == r) {
for (int j=0; j<r; j++)
cout << data[j];
cout << endl;
return;
}
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
int main()
{
char arr[] = {'A','T','C','G'};
int n = sizeof(arr)/sizeof(arr[0]);
printCombination(arr, n, 1);
printCombination(arr, n, 2);
printCombination(arr, n, 3);
printCombination(arr, n, 4);
printCombination(arr, n, 5);
system("pause");
}

At least assuming I understand what you want, this is pretty easy to solve by treating it as counting from 0 to some limit in base 4, with the "digits" displayed as "A", "C", "G" and "T".
#include <string>
#include <iostream>
std::string cvt(unsigned input, unsigned len) {
std::string ret;
static const char letters[] = "ACGT";
for (int i=0; i<len; i++) {
ret.push_back(letters[input%4]);
input /= 4;
}
return ret;
}
int main() {
unsigned limit = 1;
unsigned length = 4;
for (int i=0; i<4; i++)
limit *= 4;
for (int i=0; i<limit; i++)
std::cout << cvt(i, length) << "\n";
}

Your code assumes each letter can only be used once. That's why you are getting no results for both sequences of length 5 and 6. Rewrite your function as the following and do not pass as start or end value to it:
void combinationUtil(char arr[], char data[], int index, int r)
{
if (index == r)
{
for (int j=0; j<r; ++j)
cout << data[j];
cout << endl;
return;
}
for (int i=0; i<r; ++i)
{
data[index] = arr[i];
combinationUtil(arr, data, index+1, r);
}
}

Related

fopen() gives me malloc(): corrupted top size

I am trying to write the contents of an array, to a binary file, but it gives the following errors when I run the file.
malloc(): corrupted top size
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
Here is my code
#include <iostream>
#include <time.h>
#include <fstream>
#include <iostream>
using namespace std;
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
#define FIVE 5
#define SIX 6
#define SEVEN 7
int getArrayLength();
void initializeArray(int *array, int length);
void printArray(int *array, int length);
void menu(int *array, int length);
void userChoice(int userInput, int *array, int length);
void serialSearch(int *array, int length, int givenNumber);
void quickSort(int *array, int start, int end);
int partition(int *array, int start, int end);
void substitute(int *firstElement, int *secondElement);
int binarySearch(int *array, int start, int end, int userChoice);
void arrayConcatenation(int *firstArray, int *secondArray, int *concatenatedArray, int length, int doubleLength);
int main() {
int arrayLength = getArrayLength();
int *randomNumbersArray = (int *) malloc(arrayLength * sizeof (int));
initializeArray(randomNumbersArray, arrayLength);
printArray(randomNumbersArray, arrayLength);
menu(randomNumbersArray, arrayLength);
return 0;
}
int getArrayLength()
{
int size;
cout<<"Please give the size of the array: ";
cin>>size;
return size;
}
void initializeArray(int *array, int length)
{
srand(time(nullptr));
for(int i = 0; i < length; i++)
*(array + i) = 30 + rand() % 21;
}
void printArray(int *array, int length)
{
for(int i = 0; i < length; i++)
cout<<*(array + i)<<" ";
cout<<endl;
}
void menu(int *array, int length)
{
int userInput;
cout<<" Array Functions"<<"\n"<<endl;
do {
cout<<"1. Serial Search"<<endl;
cout<<"2. Array Classification"<<endl;
cout<<"3. Binary Search (classifies the array automatically)"<<endl;
cout<<"4. Concatenation of classified arrays"<<endl;
cout<<"5. Print"<<endl;
cout<<"6. Save and read array with binary file"<<endl;
cout<<"7. Exit"<<"\n"<<endl;
cout<<"Please enter your choice: ";
cout<<endl;
cin>>userInput;
userChoice(userInput, array, length);
} while (userInput != SEVEN);
}
void userChoice(int userInput, int *array, int length)
{
FILE *myFile;
int mergedLength = 2 * length;
int *secondArray = (int *) malloc(length * sizeof (int));
int *mergedArray = (int *) malloc(length * sizeof (int));
initializeArray(secondArray, length);
initializeArray(mergedArray, mergedLength);
switch(userInput)
{
case ONE:
{
int givenNumber;
serialSearch(array, length, givenNumber);
break;
}
case TWO:
{
quickSort(array, 0, length-ONE);
cout<<"This is the sorted array."<<endl;
printArray(array, length);
break;
}
case THREE:
{
int choice, existence;
cout<<"What number you want?"<<endl;
cin>>choice;
quickSort(array, 0, length-ONE);
existence = binarySearch(array, 0, length-ONE, choice);
if (existence == -ONE)
cout<<"The chosen number is not in the array."<<endl;
else
cout<<"The number is at index "<<existence<<"."<<endl;
break;
}
case FOUR:
{
quickSort(array, 0, length-ONE);
quickSort(secondArray, 0, length-ONE);
arrayConcatenation(array, secondArray, mergedArray, length, mergedLength);
quickSort(mergedArray, 0, mergedLength - ONE);
cout<<"This is the first array in order"<<endl;
printArray(array, length);
cout<<"This is the second array in order."<<endl;
printArray(secondArray, length);
cout<<"This is the merged array in order."<<endl;
printArray(mergedArray, mergedLength);
myFile = fopen("binarydata.dat", "wb");
if(myFile == NULL)
{
cout<<"Error in file opening."<<endl;
exit(0);
}
fwrite(array, sizeof (int ), length, myFile);
fclose(myFile);
break;
}
}
free(secondArray);
free(mergedArray);
}
void serialSearch(int *array, int length, int givenNumber)
{
int flag = -ONE;
cout<<"Please give the number that you want to find in the array: ";
cin>>givenNumber;
for(int i = 0; i < length; i++)
{
if(*(array + i) == givenNumber)
{
cout<<"The number was found at position: "<<i<<"\n"<<endl;
flag = 0;
break;
}
}
if(flag == -1)
cout<<"The number is not in the array."<<"\n"<<endl;
}
void quickSort(int *array, int start, int end)
{
if (start < end)
{
int driver = partition(array, start, end);
quickSort(array, start, driver-ONE);
quickSort(array, driver+ONE, end);
}
}
int partition(int *array, int start, int end)
{
int key = *(array + end);
int i = start - ONE;
for(int j = start; j < end; j++)
{
if(*(array + j) <= key)
{
i++;
substitute((array + i), (array + j));
}
}
substitute((array +i + ONE), (array + end));
return(i + ONE);
}
void substitute(int *firstElement, int *secondElement)
{
int temp = *firstElement;
*firstElement = *secondElement;
*secondElement = temp;
}
int binarySearch(int *array, int start, int end, int userChoice)
{
if(end >= start)
{
int middle = start + (end - start)/2;
if(*(array + middle) == userChoice)
return middle;
if(*(array + middle) > userChoice)
return binarySearch(array, start, middle-1, userChoice);
return binarySearch(array, middle+1, end,userChoice);
}
return -1;
}
void arrayConcatenation(int *firstArray, int *secondArray, int *concatenatedArray, int length, int doubleLength)
{
for(int i = 0; i < length; i++)
*(concatenatedArray + i) = *(firstArray + i);
for(int i = 0; i < length; i++)
*(concatenatedArray + i + length) = *(secondArray + i);
}
The problem is in the case FOUR of the switch case part of the code.

How can I get all the anagrams of a string

Im trying to find all the possible anagrams of a string and store them in an array using only recursion.
Im stuck and this is all i have.
int main()
{
const int MAX = 10;
string a = "ABCD";
string arr[10];
permute(arr, a, 0, a.size(), 0);
return 0;
}
void permute(string arr[], string wrd, int firstLetter, int lastLetter, int it)
{
if (firstLetter == lastLetter)
*arr = wrd;
else
{
swap(wrd[firstLetter], wrd[it]);
permute(arr, wrd, firstLetter + 1, lastLetter, it++);
}
}
The order doesnt matter.
Ex: string "abc";
array should have: abc, acb, bca, bac, cab, cba
Edit: im trying to find all permutations of a word and insert them into an array without using loops.
You should use string& for the parameter as it will be more efficient. You should iterate through chars.
#include <iostream>
#include <string>
using namespace std;
void permute(string* arr, int& ind, string& wrd, int it) {
if (it == wrd.length()) {
arr[ind++] = wrd;
} else {
for (int i = it; i < wrd.length(); ++i) {
swap(wrd[i], wrd[it]);
permute(arr, ind, wrd, it + 1);
swap(wrd[i], wrd[it]);
}
}
}
int main() {
string a = "ABCD";
string arr[100]; // enough size to store all permutations
int ind = 0;
permute(arr,ind, a, 0);
for (int i = 0; i < ind; ++i) {
cout << arr[i] << endl;
}
return 0;
}
You need to store the current value before permute() calls permute() again. This is where you are losing some of your values.
The easiest way to do this would be something like this:
// Precondition locs size is the same x length and arr is the right size to handle all the permutations
void permute(string arr[], string x, int locs[], int size, int & index)
{
for(int i = 0; i<size; i++)
{
if(locs[i] < size) locs[i]++;
else locs[i] = 0;
}
arr[index] = "";
for(int i = 0; i<size; i++)
{
arr[index] += x[locs[i]];
}
index++;
}
Hope this really helps.

Trying to delete duplicates in char array/cstring? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I don't understand why my code isn't working. The commented out code would remove the wrong characters and not remove any spaces, but the current delete_repeats function is giving me an error of: `line 49: expected initializer before numeric constant.
Can anyone help me?`
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void fill_array(char a[], int size, int& number_used);
void delete_repeats(char a[], int& number_used);
void sentences_output(char a[], int& number_used);
int main()
{
char sentences[100];
int used=0;
fill_array(sentences, 100, used);
delete_repeats(sentences, used);
sentences_output(sentences, used);
return 0;
}
void fill_array(char a[], int size, int& number_used)
{
char c;
int index = 0;
cout<<"Enter your sentence or sentences and press enter. \n"
<< "The max number of characters is 100.\n";
cin.get(c);
while((c != '\n')&&(index < size))
{
a[index]=c;
cin.get(c);
index++;
}
number_used = index;
cout<<"Your original array size was "<<number_used<<endl;
return;
}
void delete_repeats(char a[], int& number_used)
48{
int counter = number_used;
for (int i = 0; i < number_used; i++)
{
for (int j = i+1; j < number_used; j++)
{
if (a[i] == a[j])
{
for (int k = j; k < number_used - 1; k++)
{
a[k]= a[k + 1];
}
// } wrong place; j-- and size-- only if a duplicate
j--;
number_used--;
} // moved brace here
cout << "size = " << number_used;
cout << endl;
}
}
return;
}
/*
void delete_repeats(char a[], int& number_used)
{
int location = 0;
int target = 0;
int change;
for(location = 0; location < number_used; location++)
{
for(target = 0; target<number_used; target++)
{
change = target;
if(a[location] == a[target])
{
a[target] = a[change+(target - location)];
}
}
}
return;
}
*/
void sentences_output(char a[], int& number_used)
{
cout<<"The new sentence is \n";
for(int i = 0; i < number_used; i++)
{
cout<<a[i]<<endl;
}
cout<<"The size of the new array is \n";
cout<<number_used<<endl;
return;
}
The commented out delete_repeats was the second one I came up with and the first delete_repeats was from an example I found, but neither is working.
Thanks everyone! Here is my corrected code:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void fill_array(char a[], int size, int& number_used);
void delete_repeats(char a[], int& number_used);
void sentences_output(char a[], int& number_used);
int main()
{
char sentences[100];
int used=0;
fill_array(sentences, 100, used);
delete_repeats(sentences, used);
sentences_output(sentences, used);
return 0;
}
void fill_array(char a[], int size, int& number_used)
{
char c;
int index = 0;
cout<<"Enter your sentence or sentences and press enter. \n"
<< "The max number of characters is 100.\n";
cin.get(c);
while((c != '\n')&&(index < size))
{
a[index]=c;
cin.get(c);
index++;
}
number_used = index;
cout<<"Your original array size was "<<number_used<<endl;
return;
}
void delete_repeats(char a[], int& number_used)
{
int counter = number_used;
for (int i = 0; i < number_used; i++)
{
for (int j = i+1; j < number_used; j++)
{
if (a[i] == a[j])
{
for (int k = j; k < number_used - 1; k++)
{
a[k]= a[k + 1];
}
j--;
number_used--;
}
}
}
return;
}
void sentences_output(char a[], int& number_used)
{
cout<<"The new sentence is \n";
for(int i = 0; i < number_used; i++)
{
cout<<a[i]<<" ";
}
cout<<"\n";
cout<<"The size of the new array is \n";
cout<<number_used<<endl;
return;
}
I removed the commented out delete_repeats function and edited the new one as well as changed the output function.
Did you include the line numbers in your actual code!? That would give the error you quote.

Count the number of component wise comparisons in quicksort algorithm.

I'm trying to count the number of comparisons my quicksort algorithm makes for an array size of 500. I know that the best case for quicksort with partition is nlogn-n+1. So for an array size of 500, the best case number of component wise comparisons would be about 3983. However, when I run my code, I'm getting 2400 comparisons or so, depending on the array the random function generates. Am I counting the number of component wise comparisons wrong? Please help.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int count_500 = 0;
int partition(int *S,int l, int u);
void swap(int &val1, int &val2);
void Quicksort(int S[],int low, int hi);
void exchange(int list[], int p, int q);
int median_of_3(int list[], int p, int r);
void Quicksort_M3(int S[], int low, int hi);
int main()
{
int S1_500[500];
int S2_500[500];
int S3_500[500];
int S1_200[200];
int S2_200[200];
int S3_200[200];
int S1_8[8];
int S2_8[8];
int S3_8[8];
srand ( time(NULL) );
for(int i=0; i<500; i++)
{
S1_500[i] = rand()%1000;
S2_500[i] = rand()%1000;
S3_500[i] = rand()%1000;
}
for(int i=0; i<200; i++)
{
S1_200[i] = rand()%500;
S2_200[i] = rand()%500;
S3_200[i] = rand()%500;
}
for(int i=0; i<8; i++)
{
S1_8[i] = rand()%100;
S2_8[i] = rand()%100;
S3_8[i] = rand()%100;
}
Quicksort(S1_500,0,499);
for(int i=0; i<500; i++)
{
cout << S1_500[i] << endl;
}
cout << "Number of component wise comparisons is: " << count_500 << endl;
}
int partition(int *S,int l, int u)
{
int x = S[l];
int j = l;
for(int i=l+1; i<=u; i++)
{
if(S[i] < x)
{
count_500++; // Count the component wise comparison
j++;
swap(S[i],S[j]);
}
}
int p = j;
swap(S[l],S[p]);
return p;
}
void swap(int &val1, int &val2)
{
int temp = val1;
val1 = val2;
val2 = temp;
}
void Quicksort(int S[],int low, int hi)
{
if (low < hi)
{
int p = partition(S,low,hi);
Quicksort(S,low,p-1);
Quicksort(S,p+1,hi);
}
}
You want the count_500++; outside the if statement. You're only counting the comparisons, where the result is true.
Change
if(S[i] < x)
{
count_500++; // Count the component wise comparison
...
}
to
count_500++; // Count the component wise comparison
if(S[i] < x)
{
...
}

Quicksort algorithm with duplicate keys

I am trying to implement Quick Sort algorithm. Following code works for unique elements but it doesn't working for arrays having duplicate elements. Please tell me where I am doing wrong. Also when I change value of pivot to some other number other than 0 , program crashes. Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
void swapme(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
// these two variables will take care of position of comparison
int lower = 0, upper = size - 1;
int pivot = 0; // assigns pivot
if (size <= 1)
return;
while (lower < upper)
{
while (arr[lower] < arr[pivot])
{
++lower;
}
}
while (arr[upper] > arr[pivot])
{
--upper;
}
if (upper > lower)
{
swapme(arr[upper], arr[lower]);
// upper--;
// lower++;
}
quicksort(arr, lower);
quicksort(&arr[lower + 1], size - 1 - lower);
}
int main()
{
int arr[30];
for(int j = 0; j < 30; j++)
{
arr[j] = 1 + rand() % 5000;
}
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
quicksort(arr, 30);
for(int j = 0; j < 30; j++)
{
cout << arr[j] << "\t";
}
cout << endl;
cin.get();
cin.get();
}
Update: I have finally managed to make it work. Here is the fixed version:
void swapme(int &a, int &b )
{
int temp = a;
a = b;
b = temp;
}
void quicksort(int *arr, int size)
{
if (size <= 1)
return;
// These two variables will take care of position of comparison.
int lower = 0;
int upper = size-1;
int pivot = arr[upper/2]; // assigns pivot
while (lower <= upper)
{
while (arr[lower] < pivot)
++lower;
while (arr[upper] > pivot)
--upper;
if (upper >= lower)
{
swapme(arr[upper],arr[lower]);
if(arr[upper] == arr[lower])
{
// Can either increment or decrement in case of duplicate entry
upper--; // lower++;
}
}
}
quicksort(arr, lower);
quicksort( &arr[lower+1], size-1-lower);
}
You are storing the index of your pivot element in the pivot variable, so swapping the elements can potentially change the choice of pivot element during the loop. Not a very good idea. I would suggest storing the actual value of the pivot element inside pivot instead.
Also, if this really isn't homework, why don't you simply use the standard library facilities?
#include <algorithm>
// ...
std::sort(arr + 0, arr + 30);
You will get heavily optimized and tested code that will outperform your handwritten Quicksort anytime.
Quick Sort that can implement any number of i/p integers. it also deal with duplicate keys
#include <conio.h>
#include <string>
using namespace std;
void InputArray(int*,int);
void QuickSort(int *,int,int);
int partition(int *,int,int);
void swap(int *,int,int);
void printArr(int *,int Siz=11);
void main(){
int siz;
cout<<"Enter Array length : "; cin>>siz;
int *a=new int[siz];
InputArray(a,siz);
QuickSort(a,0,siz-1);
int i=0,j=11;
printArr(a,siz);
system("pause");
}
void InputArray(int*a,int s){
for(int i=0; i<s; i++){
cout<<"ELement ["<<i<<"] = "; cin>>a[i];
}
}
void QuickSort(int *a,int start,int end){
if(start<end){
int pivot=partition(a,start,end);
QuickSort(a,start,pivot);
QuickSort(a,pivot+1,end);
}
}
int partition(int *a,int start,int end){
int currentPivotValue=a[start];
int i=start-1, j=end+1;
while(true){
i++;
while(i<j && a[i]<currentPivotValue){ i++; }
j--;
while(j>start && a[j]>currentPivotValue) {j--;}
if(i<j) swap(a,i,j);
else return j;
}
}
void swap(int *b,int i,int j){
int t=b[i];
b[i]=b[j];
b[j]=t;
}
void printArr(int *a,int Siz){
for(int i=0; i<Siz; i++) cout<<a[i]<<" ";
}