I want to print all permutation of string in lexicographic order. I wrote this code:
void permute(char *a, int i, int n) {
if (i == (n-1)) printf("\"%s\"\n", a);
else {
for (int j = i; j < n; j++) {
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
Let's take for example string abc, I want to receive all permutation in lexicographic order as in the left column, but I have result as in the right column.
"abc" "abc"
"acb" "acb"
"bac" "bac"
"bca" "bca"
"cab" <
"cba" "cba"
> "cab"
Can someone help me with this? I saw some algorithms, but they look difficult. I think I can save all generated strings in an array and then sort this array, but I cannot write this (I'm a beginner in C).
In C
There's a pretty straightforward description of an algorithm (plus implementation) at geeksforgeeks:
Given a string, print all permutations of it in sorted order. For
example, if the input string is “ABC”, then output should be “ABC,
ACB, BAC, BCA, CAB, CBA”.
We have discussed a program to print all permutations in this post,
but here we must print the permutations in increasing order.
Following are the steps to print the permutations lexicographic-ally
Sort the given string in non-decreasing order and print it. The first permutation is always the string sorted in non-decreasing order.
Start generating next higher permutation. Do it until next higher permutation is not possible. If we reach a permutation where all
characters are sorted in non-increasing order, then that permutation
is the last permutation.
Steps to generate the next higher permutation:
1. Take the previously printed permutation and find the rightmost character in it, which is smaller than its next character. Let us call
this character as ‘first character’.
Now find the ceiling of the ‘first character’. Ceiling is the smallest character on right of ‘first character’, which is greater
than ‘first character’. Let us call the ceil character as ‘second
character’.
Swap the two characters found in above 2 steps.
Sort the substring (in non-decreasing order) after the original index of ‘first character’.
I've re-implemented it below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void swap(char* left, char* right)
{
char temp = *left;
*left = *right;
*right = temp;
}
int compare (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
void PrintSortedPermutations(char* inStr)
{
// Re-implementation of algorithm described here:
// http://www.geeksforgeeks.org/lexicographic-permutations-of-string/
int strSize = strlen(inStr);
// 0. Ensure input container is sorted
qsort(inStr, strSize, sizeof(char), compare);
int largerPermFound = 1;
do{
// 1. Print next permutation
printf("%s\n", inStr);
// 2. Find rightmost char that is smaller than char to its right
int i;
for (i = strSize - 2; i >= 0 && inStr[i] >= inStr[i+1]; --i){}
// if we couldn't find one, we're finished, else we can swap somewhere
if (i > -1)
{
// 3 find character at index j such that
// inStr[j] = min(inStr[k]) && inStr[k] > inStr[i] for all k > i
int j = i+1;
int k;
for(k=j;k<strSize && inStr[k];++k)
{
if (inStr[k] > inStr[i] && inStr[k] < inStr[j])
j = k;
}
// 3. Swap chars at i and j
swap(&inStr[i], &inStr[j]);
// 4. Sort string to the right of i
qsort(inStr+i+1, strSize-i-1, sizeof(char), compare);
}
else
{
largerPermFound = 0;
}
}while(largerPermFound);
}
int main(void) {
char str[] = "abc";
PrintSortedPermutations(str);
return 0;
}
Output
abc acb bac bca cab cba
Live Demo
In C++
std::next_permutation from the <algorithm> library will do this for you, just make sure you sort your container first:
Return value
true if the function could rearrange the object as a lexicographicaly
greater permutation. Otherwise, the function returns false to indicate
that the arrangement is not greater than the previous, but the lowest
possible (sorted in ascending order).
For example:
std::string myStr = "abc";
std::stable_sort(std::begin(myStr), std::end(myStr));
do {
for(auto&& element : myStr)
std::cout << element << " ";
std::cout << std::endl;
} while (std::next_permutation(std::begin(myStr), std::end(myStr)));
Output:
a b c a c b b a c b c a c a b c b a
Live Demo
I am presuming you want a recursive version.
Here are two solutions.
Solution 1)
Since you want lexicographic, all you need to do is pick the next smallest possible when you need to pick. That's it!
For example, here is a recursive version in python
def permute(done, remaining):
if not remaining:
print done
return
sorted_rem = sorted(remaining)
l = len(sorted_rem)
for i in xrange(0, l):
c = sorted_rem[i]
# Move to c to done portion.
done.append(c)
remaining.remove(c)
# Permute the remaining
permute(done, remaining)
# Put c back.
remaining.append(c)
# Remove from done.
del done[-1]
permute([], [1,2,3,4])
That's it.
Solution 2)
While Solution 1 works and is easy to understand, I suspect we might be wasting some time by sorting. This solution is closer to what you have.
Recursion is basically mathematical induction in disguise, and that way of thinking is really useful in understanding how to write recursive programs.
For example, assume your permute method always constructs the permutations in lexicographic order.
Here is a recursive version, with that assumption, please read the comments to understand what is going on.
// By induction assumption, permute(a, i, n)
// goes through all the permutations of a[i], ..., a[n-1]
// in lexicographic order, by modifying a itself.
void permute(char *a, int i, int n) {
if (i == (n-1)) {
printf("%s\n", a);
return;
}
int j;
// We pick the n-i posibilities for the position a+i, then recursively
// compute the permutations of a[i+1], ..., a[n-1]
// So first pick the smallest possible for a+i, recurse.
// Then the next possible for a+i, then recurse etc.
for (j = i; j < n; j++) {
permute(a, i+1, n);
// By our induction assumption, at this point,
// a[i+1], a[i+2], .., a[n-1]
// must be the lexicographically the largest possible!
// So now reverse that portion.
reverse(a+i+1, a+n-1);
// Now we need to pick the lexicographically next element for
// position a+i. This is nothing but the element which is just
// larger than the current a+i.
int k = i+1;
while(k < n && a[i] > a[k]) {
k++;
}
if (k >= n) {
continue;
}
// Choose the next value for a+i.
swap(a+i, a+k);
}
// Notice that the portion a[i+1], ..., a[n-1] is sorted increasing.
// when the loop exits. Also a[i] will be the largest element.
// We need to reverse so that a[i], .., a[n-1] is the lexicographically
// largest permutation to maintain the induction (recursion) assumption.
reverse(a+i+1, a+n-1);
}
Notice the similarity between this, and the iterative version (specified by the others and section below), where you reverse a chunk at the end, and swap two elements.
btw, the common iterative algorithm for generating permutations in lexicographic order is Narayana Pandita's algorithm, mentioned by other, but not by name.
See this link: http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
This is what std::next of C++ and a host of other libraries use.
This algorithm even works when there are repeated elements, and can in fact be used to generate combinations! (Initialize your array with zeroes and ones).
IMHO, it would be simpler to first sort the characters of the string because the number of permutations (n!) is always greater (or equal for n = 1 or 2) than the number of characters.
And you were not far from the solution but you must rotate instead of swap. Here is a slight variation that returns an array of dynamically allocated strings that are printed in the main :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int char_compare(const void *a, const void *b) {
return (*((char *) a)) - (*((char *) b));
}
int fact(int n) {
int f = 1;
while (n > 0) {
f *= n--;
if (f < 0) return 0;
}
return f;
}
void rotateback(char *a, int i, int j) {
int k;
char tmp;
tmp = a[i];
for(k=i; k<j; k++) {
a[k] = a[k+1];
}
a[j] = tmp;
}
void rotate(char *a, int i, int j) {
int k;
char tmp;
tmp = a[j];
for(k=j; k>i; k--) {
a[k] = a[k-1];
}
a[i] = tmp;
}
void permute(char *a, int i, int n, char ***permuts) {
int j;
if (i == (n-1)) {
**permuts = strdup(a); // store a copy of the string
*permuts += 1; // and point to next location
}
else {
for (j = i; j < n; j++) {
rotate(a, i, j);
permute(a, i+1, n, permuts);
rotateback(a, i, j);
}
}
}
char ** permutations(const char *str_orig) {
int i, j;
size_t n = strlen(str_orig);
size_t fact_n = fact(n);
char ** permuts, **work;
char * str = strdup(str_orig); // get a local copy
qsort(str, n, 1, char_compare); // and sort it
permuts = work = calloc(fact_n, sizeof(char *)); // allocate n! pointers
permute(str, 0, n, &work);
return permuts;
}
int main() {
char str[] = "cab";
int i;
char **permuts = permutations(str);
for (i=0; i<fact(strlen(str)); i++) {
printf("\"%s\"\n", permuts[i]);
free(permuts[i]);
}
free(permuts);
return 0;
}
Output is correctly :
"abc"
"acb"
"bac"
"bca"
"cab"
"cba"
Another twist on the lexical string permutations is to store the permutation in a dynamically allocated array of pointers-to-string and pass the array to qsort to provide output in lexical order. Since permutations grow exponentially, checks for memory exhaustion after each allocation are especially important. The string size below is limited to 16 characters, which may still result in memory exhaustion depending on the amount of memory available.
Updated passing the address of the array to hold the string permutations was required for reallocation to work in the recursive function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXS 128
#define MAXC 16
size_t maxs;
void swap (char *x, char *y);
int cmp_pa (const void * a, const void * b);
char **realloc_char (char **sp, size_t *n);
void permute_pa (char ***pa, size_t *idx, char *a, int i, int n);
int main (int argc, char **argv)
{
size_t i = 0;
size_t idx = 0;
size_t len = 0;
char a[MAXC] = {0};
char **pa = NULL;
maxs = MAXS; /* initialize realloc counter */
if (argc > 1) /* set string to permute */
strcpy (a, argv[1]);
else
strcpy (a, "abc");
len = strlen (a); /* lenght to permute or MAXC */
if (len > MAXC) len = MAXC;
if (!(pa = calloc (MAXS, sizeof *pa))) /* allocate MAXS pointers */
return 1;
permute_pa (&pa, &idx, a, 0, len - 1); /* call permute function */
printf ("\n no of permutations : %zu\n\n", idx);
printf (" unsorted permutations of %s\n\n", a);
for (i = 0; i < idx; i++)
printf (" %s\n", pa[i]);
qsort (pa, idx, sizeof *pa, cmp_pa); /* sort array of permutations */
printf ("\n sorted permutations of %s\n\n", a);
for (i = 0; i < idx; i++)
printf (" %s\n", pa[i]);
for (i = 0; i < idx; i++) /* free all allocated memory */
free (pa[i]);
free (pa);
return 0;
}
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* qsort compare function */
int cmp_pa (const void * a, const void * b)
{ return strcmp (*(char**)a, *(char**)b); }
/* realloc an array of pointers to strings setting memory to 0. */
char **realloc_char (char **sp, size_t *n)
{
char **tmp = realloc (sp, 2 * *n * sizeof *sp);
if (!tmp) {
fprintf (stderr, "Error: struct reallocation failure.\n");
// return NULL;
exit (EXIT_FAILURE);
}
sp = tmp;
memset (sp + *n, 0, *n * sizeof *sp); /* memset new ptrs 0 */
*n *= 2;
return sp;
}
/* Function to store permutations of string in array of pointers-to-string
This function takes five parameters:
1. allocated array of pointers-to-string
2. pointer to array index
3. string to permute
4. starting index of the string (zero based)
5. ending index of the string. (zero based)
*/
void permute_pa (char ***pa, size_t *idx, char *a, int i, int n)
{
int j;
if (i == n) {
(*pa)[*idx] = strdup (a);
if (!(*pa)[*idx]) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}
(*idx)++;
if (*idx == maxs)
*pa = realloc_char (*pa, &maxs);
}
else {
for (j = i; j <= n; j++) {
swap ((a+i), (a+j));
permute_pa (pa, idx, a, i+1, n);
swap ((a+i), (a+j));
}
}
}
Output
$ ./bin/str_permute_lex
no of permutations : 6
unsorted permutations of abc
abc
acb
bac
bca
cba
cab
sorted permutations of abc
abc
acb
bac
bca
cab
cba
Memory Error Check
$ valgrind ./bin/str_permute_lex
==29709== Memcheck, a memory error detector
==29709== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29709== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29709== Command: ./bin/str_permute_lex
==29709==
no of permutations : 6
<snip>
==29709==
==29709== HEAP SUMMARY:
==29709== in use at exit: 0 bytes in 0 blocks
==29709== total heap usage: 7 allocs, 7 frees, 1,048 bytes allocated
==29709==
==29709== All heap blocks were freed -- no leaks are possible
==29709==
==29709== For counts of detected and suppressed errors, rerun with: -v
==29709== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
The basic idea is to start with our main string as "" and remaining string as "abc" (or any you want).
Now to the main string append character by character. Such a way that it don't repeat the used characters (for all possible characters).
Repeat the same until you get length n ( length of main string ).
Okay, the explanation isn't clear but watch out the code. It will make everything clear.
#include<iostream>
void perm(std::string sub, std::string rem, int n)
{
if(n==0)
//print if n is zero i.e length achieved
std::cout<<sub<<"\n";
for(int i=0; i<n; i++)
//append a character and pass remaining to rem string
perm(sub + rem[i] , rem.substr(0,i) + rem.substr(i+1,n-1), n-1);
}
int main()
{
perm("", "abc", 3);
}
Output
abc
acb
bac
bca
cab
cba
This is voluntarily an answer that does not answer this question.
This other question was marked as a duplicate to this one. This answer would be acceptable for the other question even if it is non sense here.
This could be a simple recursive C implementation to get all permutations in lexicographic order. It is not optimized but easy to understand and to implement:
get an array for the elements to permute
at any step, iterate through the elements that have not been used until here
add one of the iterated elements to the array of used elements
recurse
when the array of used element is full print it.
Concrete implementation:
#include <stdio.h>
#define SIZE 4
void disp(int *fullarr, int n, int * begin, int pos) {
int i, j;
int found;
if (pos == n) {
for(i=0; i< n; i++) {
printf("%2d", begin[i]);
}
printf("\n");
return;
}
for (i=0; i<n; i++) {
found = 0;
for (j=0; j<pos; j++) {
if (fullarr[i] == begin[j]) {
found = 1;
break;
}
}
if (! found) {
begin[pos] = fullarr[i];
disp(fullarr, n, begin, pos+1);
}
}
}
int main() {
int i;
int fullarr[SIZE], begin[SIZE];
for (i=0; i<SIZE; i++) {
fullarr[i] = i;
}
disp(fullarr, SIZE, begin, 0);
return 0;
}
OK, here is how to do it in any programming language. I will illustrate it with writing down all the permutations of S4 but one can see easily how in generalizes. One needs to know about special permutations called cycles. The cycle (132) is the permutation that sends 1 to 3, 3 to 2 and 2 back to 1. Think of a numbered circle and one rotates the circle. The cycles (321) and (213) represent the same cycle and permutation. A "two cycle" (13) is a transposition, simply interchanging 1 and 3 and leaving all the other members the same. A "one cycle" (2) sends 2 to 2 and leaves everything else the same, i.e., it does nothing to any element. However, I will write one cycles below to make it look "pretty".
With that intro, let us start with the set {[1,2,3,4]}. We act on this set by the following sets of cycles:
The set {(4)}. This does nothing leaving us with
{[1,2,3,4]}.
We act on this set with the pair of cycles, {(3),(43)}. This gives us
{ [1,2,3,4], [1,2,4,3] },
a set with two elements. We act on this second set with the cycles:
{(2),(32),(432)}. We have
(2) { [1,2,3,4], [1,2,4,3] } = { [1,2,3,4], [1,2,4,3] }
(32) { [1,2,3,4], [1,2,4,3] } = { [1,3,2,4], [1,3,4,2] }
(432) { [1,2,3,4], [1,2,4,3] } = { [1,4,2,3], [1,4,3,2] }
Writing these out, we have a set of 6 tuples:
{ [1,2,3,4], [1,2,4,3], [1,3,2,4], [1,3,4,2 [1,4,2,3], [1,4,3,2] }
Lastly we hit this set with the cycles {(1),(21),(321),(4321)}. This will give us 24 tuples which are the 4x6 = 24 permutations of S4 - all in lexicographic order!
void permute(string str,int index)
{
if(index == str.size())
{
cout<<str<<" ";
return;
}
else
{
for(int j=index;j<str.size();j++)
{
if(str[index] <= str[j]) // swap only in sorted order
swap(str[j],str[index]);
permute(str,index+1);
if(str[index] <= str[j]) // swap only in sorted order
swap(str[j],str[index]);
}
}
}
int main()
{
int t;
string str;
scanf("%d",&t);
while(t--){
// scanf("%d",&n);
cin>>str;
sort(str.begin(),str.end());
permute(str,0);
cout<<endl;
}
return 0;
}
from itertools import combinations
S,k = input().split()
for i in list(range(int(k)+1))[1:]:
for e in combinations(sorted(S),i ):
print(''.join(e))
Related
C language
I want to compare an array with it's reversed form and check to see if it's the same.
For example, arr1 = 5 5 8 8 5 5
Reversed arr1 = 5 5 8 8 5 5
Then output would be: Array is the same in reverse.
For some reason when I try to compare my two arrays, it ALWAYS says it is the same even if it is not.
For example : 7 8 9 is entered. The reverse is 9 8 7, which is not the same as what was entered. However, my code says it is.
How can I fix my comparison so that the results are accurate? Please advise, thank you!
I tried using goto to display results. This is my code (function):
void function(int *arr)
{
int j, c, temp, size;
size = sizeof(arr);
int old[size];
int new[size];
/*Prints original array from user input*/
printf("Input Array: ");
for(j=0; j<size; j++)
{
printf("%d ", arr[j]);
old[j] = arr[j];
}
printf("\n");
/* Reversing the array */
c = j - 1;
j = 0;
while (j < c)
{
temp = arr[j];
arr[j] = arr[c];
arr[c] = temp;
j++;
c--;
}
/* Print Reversed Array */
int i;
for(i=0; i<size; i++)
{
printf("%d ", arr[i]);
/*saved to new for possible comparison*/
new[i] = arr[i];
}
printf("\n");
/* Compare original array with reversed array */
if(temp = arr[j])
{
goto same;
} else {
goto notsame;
}
same:
printf("Array is the same in reverse\n");
return 0;
notsame:
printf("Array is not the same in reverse\n");
return 0;
}
You can't get the size of the array with sizeof. You should print out size and see what that value is giving you, it won't be the size of the array.
The reason you are always getting the "same" is that you aren't actually comparing values. You are assigning arr[j] to temp. if(temp = arr[j]) should be if(temp == arr[j]). I think you will find that it won't go to same anymore.
An easier way to solve this problem would be:
void checkReverse(int* arr, int arrSize)
{
// Loop through the array until you have hit the middle
for (int i = 0; i < (arrSize - i); i++)
{
// Check the element to the element in the same place counting from the back
if (arr[i] != arr[arrSize - i - 1])
{
// If we find any that don't match, we know it's not the same and can return
printf("Array is NOT the same in reverse.\n");
return;
}
}
// If we made it this far, they are the same
printf("Array is the same in reverse.\n");
return;
}
You need to modify your code with the following two points:
In your code, size means the number of elements in the array correct? so to calculate it correctly replace
size = sizeof(arr)/sizeof(int);
sizeof gives you the memory size occupied by the array, so for the array of three integers, it gives 3*int size. To count the elements of an array you need to use sizeof(array) and divide it with the size of the data type.
You need to traverse in the loop and compare each element of the original array and reversed array to confirm is it the same not.
So you need to replace your comparison logic with :
/* Compare original array with reversed array */
for(i=0;i < size;i++)
{
if(new[i] != old[i]){
printf("Array is not the same in reverse\n");
return;
}
}
printf("Array is the same in reverse\n");
return;
If you want to use recursion to solve this problem.
#include <stdio.h>
int compare(int *arr, int p, int q)
{
/* base case, if we are at or pass the middle point */
if (p >= q)
return 1;
if (arr[p] != arr[q]) {
return 0;
} else {
return compare(arr, p + 1, q - 1);
}
}
int main(int argc, char *argv[])
{
int arr1[] = {5, 5, 8, 8, 5, 5};
size_t array_size = sizeof(arr1) / sizeof(int);
int first = 0;
int last = array_size - 1;
if (compare(arr1, first, last)) {
printf("Array is same in reverse\n");
} else {
printf("Array is not same in reverse\n");
}
return 0;
}
Best solution to this question during an interview IMO: Use a stack:
step 1)
racecar -> push into stack -> STACK
step 2)
STACK-> pop from stack -> racecar
The input and output strings are the same, therefore the word is a palindrome.
As opposed to:
step 1) something -> push into stack -> STACK
step 2) STACK-> pop from stack -> gnihtemos
The input and output strings are NOT the same, therefore the word is NOT a palindrome.
I have this code so far. It works and does what I want it to. I'm wondering if I could make it better. I do not really care for user input or any other "finish touches," just want to make the code more efficient and maybe more useful for future projects.
Excessive comments are for my personal use, I find it easier to read when I go back to old projects for references and what not.
Thanks!
#include<stdio.h>
#include<stdlib.h>
void fabonacci(int * fibArr,int numberOfSeries){
int n;
//allocate memory size
fibArr = malloc (sizeof(int) * numberOfSeries);
//first val, fib = 0
*fibArr = 0;//100
fibArr++;
//second val, fib = 1
*fibArr = 1;//104
fibArr++;
//printing first two fib values 0 and 1
printf("%i\n%i\n", *(fibArr- 2),*(fibArr- 1));
//loop for fib arr
for(n=0;n<numberOfSeries -2;n++,fibArr++){
//108 looking back at 104 looking back at 100
//112 looking back at 108 looking back at 104
*fibArr = *(fibArr-1) + *(fibArr -2);
//printing fib arr
printf("%i\n", *fibArr);
}
}
int main(){
//can implm user input if want
int n = 10;
int *fib;
//calling
fabonacci(fib,n);
}
Your code is halfway between two possible interpretations and I can't tell which one you meant. If you want fibonacci(n) to just give the nth number and not have any external side effects, you should write it as follows:
int fibonacci(int n) {
int lo, hi;
lo = 0;
hi = 1;
while(n-- > 0) {
int tmp = hi;
lo = hi;
hi = lo + tmp;
}
return lo;
}
You need no mallocs or frees because this takes constant, stack-allocated space.
If you want, instead, to store the entire sequence in memory as you compute it, you may as well require that the memory already be allocated, because this allows the caller to control where the numbers go.
// n < 0 => undefined behavior
// not enough space allocated for (n + 1) ints in res => undefined behavior
void fibonacci(int *res, int n) {
res[0] = 0;
if(n == 0) { return; }
res[1] = 1;
if(n == 1) { return; }
for(int i = 2; i <= n; i++) {
res[i] = res[i-1] + res[i-2];
}
}
It is now the caller's job to allocate memory:
int main(){
int fib[10]; // room for F_0 to F_9
fibonacci(fib, 9); // fill up to F_9
int n = ...; // some unknown number
int *fib2 = malloc(sizeof(int) * (n + 2)); // room for (n + 2) values
if(fib2 == NULL) { /* error handling */ }
fibonacci(fib2 + 1, n); // leave 1 space at the start for other purposes.
// e.g. you may want to store the length into the first element
fib2[0] = n + 1;
// this fibonacci is more flexible than before
// remember to free it
free(fib2);
}
And you can wrap this to allocate space itself while still leaving the more flexible version around:
int *fibonacci_alloc(int n) {
int *fib = malloc(sizeof(int) * (n + 1));
if(fib == NULL) { return NULL; }
fibonacci(fib, n);
return fib;
}
One way to improve the code is to let the caller create the array, and pass the array to the fibonacci function. That eliminates the need for fibonacci to allocate memory. Note that the caller can allocate/free if desired, or the caller can just declare an array.
The other improvement is to use array notation inside of the fibonacci function. You may be thinking that the pointer solution has better performance. It doesn't matter. The maximum value for n is 47 before you overflow a 32-bit int, so n is not nearly big enough for performance to be a consideration.
Finally, the fibonacci function should protect itself from bad values of n. For example, if n is 1, then the function should put a 0 in the first array entry, and not touch any other entries.
#include <stdio.h>
void fibonacci(int *array, int length)
{
if (length > 0)
array[0] = 0;
if (length > 1)
array[1] = 1;
for (int i = 2; i < length; i++)
array[i] = array[i-1] + array[i-2];
}
int main(void)
{
int fib[47];
int n = sizeof(fib) / sizeof(fib[0]);
fibonacci(fib, n);
for (int i = 0; i < n; i++)
printf("fib[%d] = %d\n", i, fib[i]);
}
The program finds the average length of words in a given input and prints the words greater than the average. Here's the program
#define STRING_LEN 80
#define ARRAY_LEN 3
void *emalloc(size_t s) {
void *result = malloc(s);
if (NULL == result) {
fprintf(stderr, "Memory allocation failed!\n");
exit(EXIT_FAILURE);
}
return result;
}
void numbers_greater(char **wordlist, int average, int n){
if(n < ARRAY_LEN){
int a = strlen(wordlist[n]);
if(a>average){
printf("%s", wordlist[n]);
}
numbers_greater(wordlist+1, average, n+1);
}
}
int main(void) {
char word[STRING_LEN];
char *wordlist[ARRAY_LEN];
int num_words;
double average;
int i;
while (num_words < ARRAY_LEN && 1 == scanf("%79s", word)) {
wordlist[num_words] = emalloc((strlen(word) + 1) * sizeof wordlist[0][0]);
strcpy(wordlist[num_words], word);
num_words++;
}
average = 0.0;
for (i = 0; i < num_words; i++) {
average += strlen(wordlist[i]);
}
average = average / num_words;
printf("%f\n", average);
numbers_greater(wordlist, average, 0);
for (i = 0; i < num_words; i++) {
free(wordlist[i]);
}
return EXIT_SUCCESS;
}
The program works up until the "numbers_greater" method, giving a segmentation fault error. I'm new to C so I'm a little bit confused, the recursive method runs without an error without the strlen statement, but with the strlen statement (even if I set it to a static number like 2) it bombs out of the code. Am I traversing through the array incorrectly?
This line
numbers_greater(wordlist+1, average, n+1);
will increment both the wordlist pointer and the integer n. What you are doing, in effect is incrementing the value you are checking by 2 instead of by one, as you would like to do.
To eliminate the segfault, change this line to the following:
numbers_greater(wordlist, average, n + 1);
As a note, this could be done much easier using a simple for loop. Also, I did not read the rest of the code and there may be some other error that I missed, but this should eliminate the segmentation fault in this function.
Lets walk through
void numbers_greater(char **wordlist, int average, int n){
if(n < ARRAY_LEN){
int a = strlen(wordlist[n]);
if(a>average){
printf("%s", wordlist[n]);
}
numbers_greater(wordlist+1, average, n+1);
}
}
I have an array of strings that can hold 3 things, and I put n = 1. It works the first time... but now we get to
numbers_greater(wordlist+1, average, n+1);
so now we have an array of strings that can hold 2 things because of the wordlist+1 . n = 2 now , so n < ARRAY_LEN is true, but wordlist[n] will result in reading the 3rd element inside an array that should only hold 2.
To fix this try
numbers_greater(wordlist, average, n+1);
I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.
I have been working on an algorithm to find all permutations of the elements of a char array for a few days now and well it just doesn't seem to work.
The char array is an **array, which I iterate through based on the number entered by the user and I then malloc space for each word(40 chars each). The number entered by the user is the length of the array, and it is the number they expect to enter. This part works as expected.
What I am having trouble with is iterating through the char array and calculating the permutation of the entire set(**array). I then want to have another char array consisting of all permutations of the set. Now just permutations of the unit indices's of **array, not each indices's individual characters.
Does anybody have any tips on how to successfully do this, regardless of the size of the initial set? I assume it would be much easier if the set size where static.
My starting array looks like this as an example
char *array[] = {
"Hello",
"Calculator",
"Pencil",
"School Bus"
};
Which would be held in **array, with "Hello" in array[0] and "School Bus" in array[3], with '\0' at the end of each.
I want the permutation to be on the indices, not the characters.
So
"Hello"
.
.
.
"School BusSchool BusSchool BusSchool Bus"
Here's a dumb permutation generator (up to N=32... or 64).
#include <stdio.h>
const int N = 5;
int x[N];
int main( void ) {
int i,j;
x[0]=-1;
unsigned mask = -1; // unused numbers
for( i=0;; ) {
for( j=x[i]+1; j<N; j++ ) { // check remaining numbers
if( (mask>>j)&1 ) { // bit j is 1 -> not used yet
x[i] = j; // store the number
mask ^= (1<<x[i]); // mask used
// try going further, or print the permutation
if( ++i>=N ) { for( j=0; j<N; j++ ) printf( "%3i", x[j] ); printf( "\n" ); }
else x[i]=-1; // start next cell from 0
break;
}
}
// go back if there's no more numbers or cells
if( (j>=N) || (i>=N) ) {
if( --i<0 ) break;
mask ^= (1<<x[i]);
}
}
}
By your edit, I am taking that you have an array of four elements. Your desired output is a combination of these elements and is the concatenation of between one and four elements. The output may contain an input element more than once. Is this a correct summary?
If so, think of your output in four cases: for output generated from one, two, three, or four elements. For output generated from n elements, you have n^n possibilities. For all four of these cases combined, this gives you 1^1 + 2^2 + 3^3 + 4^4 = 288 possible outputs.
Your 1-element output permutations are simply: 0, 1, 2, 3
Your 2-element output permutations can be generated by the pseudo-code:
for i = 0 to 3 {
for j = 0 to 3 {
next_permutation = {i, j}
}
}
For 3- and 4-element output, permutations can be generated using three and four nested loops, respectively. For some arbitrary number of input elements x, you can generate permutations using the same technique with x number of nested loops. Be warned that the number of loops requires grows exponentially with the number of input elements, so this can get ugly fairly fast.
You can use the numbers from these permutations as indices into your initial array in order to generate the output as strings (as in your sample).
Update: Here's a recursive pseudo-code function that can generate these pseudo-permutations:
int output_array[dimension] = {0};
generate_combinations (unsigned dimension, int index) {
for i = 0 to (dimension-1) {
output_array[index] = i;
if index == 0
next_permutation = output_array
else
generate_combinations(dimension, index-1)
endif
}
}
You would use this with dimension set to the number of elements in your input array and index = dimension - 1. Hopefully, your input dimensionality won't be so large that this will recurse too deeply for your CPU to handle.
Here's one solution. Remember that the time complexity is factorial, and that if you're storing all the permutations then the space required is also factorial. You're not going to be able to do very many strings.
void CalculatePermutations(unsigned long permSize, const char** candidates, const char** currentPerm, unsigned long currentPermIdx, const char** ouputBuffer, unsigned long* nextOutputIdx)
{
//base case (found a single permutation)
if(currentPermIdx >= permSize){
unsigned long i = 0;
for(i = 0; i < permSize; ++i){
ouputBuffer[*nextOutputIdx] = currentPerm[i];
(*nextOutputIdx)++;
}
return;
}
//recursive case
unsigned long i = 0;
for(i = 0; i < permSize; ++i){
if(candidates[i]){
currentPerm[currentPermIdx] = candidates[i]; //choose this candidate
candidates[i] = NULL; //mark as no longer a candidate
CalculatePermutations(permSize, candidates, currentPerm, currentPermIdx + 1, ouputBuffer, nextOutputIdx);
candidates[i] = currentPerm[currentPermIdx]; //restore this as a possible candidate
}
}
}
int main(int argc, char** argv)
{
const char* allStrings[8] = {"0", "1", "2", "3", "4", "5", "6", "7"};
static const char* allPermutations[322560]; // = fact(8) * 8
const char* permBuffer[8];
unsigned long nextOutputIdx = 0;
CalculatePermutations(8, allStrings, permBuffer, 0, allPermutations, &nextOutputIdx);
for(unsigned long i = 0; i < 322560; ++i){
printf("%s", allPermutations[i]);
if(i % 8 == 7){
printf("\n");
} else {
printf(", ");
}
}
return 0;
}
here my code that give us the r-permutation of a n! possible permutations. Code works with all kind of size (I only check with 3!, 4!, 5! and 8! and always works correct, so I suppouse that works right):
#include <stdio.h>
#include <stdint.h>
enum { NPER = 4, };
static const char *DukeQuote[NPER] = {
"Shake it, baby!",
"You wanna dance?",
"Suck it down!",
"Let's rock!",
};
void fill(const uint32_t, uint32_t * const);
void fact(const uint32_t, uint32_t * const);
void perm(uint32_t, const uint32_t, const uint32_t * const, uint32_t * const);
int main(void)
{
uint32_t f[NPER+1];
uint32_t p[NPER];
uint32_t r, s;
/* Generate look-up table for NPER! factorial */
fact(NPER, f);
/* Show all string permutations */
for(r = 0; r < f[NPER]; r++)
{
perm(r, NPER, f, p);
for(s = 0; s < NPER; s++)
printf("%s, ", DukeQuote[p[s]]);
printf("\n");
}
return 0;
}
/* Generate look-up table for n! factorial.
That's a trick to improve execution */
void fact(const uint32_t n, uint32_t * const f)
{
uint32_t k;
for(f[0] = 1, k = 1; k <= n; k++)
f[k] = f[k-1] * k;
}
/* Fill the vector starting to 0 up to n-1 */
void fill(const uint32_t n, uint32_t * const p)
{
uint32_t i;
for(i = 0; i < n; i++)
p[i] = i;
}
/* Give us the r-permutation of n! possible permutations.
r-permutation will be inside p vector */
void perm(uint32_t r, const uint32_t n, const uint32_t * const f, uint32_t * const p)
{
uint32_t i, j;
fill(n, p);
for(i = n-1; i > 0; i--)
{
uint32_t s;
j = r / f[i];
r %= f[i];
s = p[j];
for(; j < i; j++)
p[j] = p[j+1];
p[i] = s;
}
}
For instance, if you want the first permutation of 4! possibles then:
perm(0, 4, f, p)
where p will have:
p = [3, 2, 1, 0]
Take care, 0 is 1th, 1 is 2th, and so on.
You can use p[i] like indices in your string array, how I've used in DukeQuote array.
PD1: This code implements the correct definition of a permutation (A r-permutation is a bijection. The cardinal of the set of all bijections N_n to N_n is exactly n!)
PD2: I hope that my mistakes in my poor English doesn't influence in the goal of my explanation.