How to count the total possibilities of permute? (in C) - c

I'm new to programming, and i'm trying to complement this code in C to permute strings, currently it shows all the words exchanged and counts how many characters the word has.
But I would like it to count the number of lines generated by the permutation too, and in this part, the code is not working. I do not know what else to do!
Example: The word "hi", generates two lines: hi, and ih. (In this case, i want the program write "generated words: 2")
the code:
#include <string.h>
#include <stdio.h>
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a + i), (a + j));
permute(a, i + 1, n);
swap((a + i), (a + j)); //backtrack
}
}
}
int main()
{
char str[21];
int len;
int cont = 1;
int fatorial = 1;
printf("\nType a word: ");
scanf("%s", str);
len = strlen(str);
permute(str, 0, len - 1);
printf("\nNumber of letters: %d\n", len);
while (cont < len)
{
fatorial = fatorial * cont;
cont++;
}
printf("\nPossibilities:%d", fatorial);
return 0;
}

You could increment a counter in permute. Something like:
#include <string.h>
#include <stdio.h>
void
swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void
permute(char *a, int i, int n, int *count)
{
int j;
if( i == n ){
printf("%s\n", a);
*count += 1;
} else {
for( j = i; j <= n; j += 1 ){
swap(a + i, a + j);
permute(a, i + 1, n, count);
swap((a + i), (a + j));
}
}
}
int
main(int argc, char **argv)
{
char buf[1024];
char *str = argc > 1 ? argv[1] : buf;
int len;
int contador = 0;
if( argc < 2 ){
printf("\nType a word: ");
scanf("%1023s", buf);
}
len = strlen(str);
permute(str, 0, len - 1, &contador);
printf("\nNumber of words: %d\n", contador);
return 0;
}

Related

function that remove an integer from an array using pointer in C

I got a question where I need to write a function that reads an integer X and an array A of type int (size N) from the keyboard and eliminates all occurrences of X in A.
for example the input is:
5
1 2 3 4 3
3
and it would return:
A : 1 2 3 4 3
New A : 1 2 4
my code so far is
#include <stdio.h>
#include<stdlib.h>
#define DIM 50
int main() {
int *A;
int N, X;
int *P1, *P2;
do{
scanf("%d", &N);
}while(N<0 || N>DIM);
A= (int*)malloc(N*sizeof(int));
for(P1=A; P1<A+N ; P1++)
scanf("%d ", P1);
printf("\n");
scanf("%d",&X);
printf("A : ");
for(P1=A; P1<A+N ; P1++)
printf("%d ", *P1);
printf("\n");
but I don't know how to continue if you could please help
What you need is to write a function that will erase elements equal to the specified value and reallocate the result array.
Here is a demonstration program where such a function is shown in action.
#include <stdio.h>
#include <stdlib.h>
size_t erase_remove( int **a, size_t n, int value )
{
size_t m = 0;
for (int *p = *a, *q = *a; p != *a + n; ++p)
{
if (*p != value)
{
if (q != p) *q = *p;
++q;
++m;
}
}
if (m != n)
{
int *tmp = realloc( *a, m * sizeof( int ) );
if (tmp != NULL)
{
*a = tmp;
}
else
{
m = -1;
}
}
return m;
}
int main( void )
{
size_t n = 5;
int *a = malloc( n * sizeof( int ) );
size_t i = 0;
a[i++] = 1, a[i++] = 2, a[i++] = 3, a[i++] = 4, a[i++] = 3;
int value = 3;
size_t m = erase_remove( &a, n, value );
if (m != -1) n = m;
for (const int *p = a; p != a + n; ++p)
{
printf( "%d ", *p );
}
putchar( '\n' );
free( a );
}
The program output is
1 2 4
If the memory reallocation for the array within the function was not successful the function returns the value (size_t)-1.
The function preserves the order of elements after removing elements equal to the target value.
If to make the function more general that can deal not only with arrays dynamically allocated then it can look very simply.
size_t erase_remove( int *a, size_t n, int value )
{
size_t m = 0;
for (int *p = a, *q = a; p != a + n; ++p)
{
if (*p != value)
{
if (q != p) *q = *p;
++q;
++m;
}
}
return m;
}
In this case the caller of the function should reallocate the result dynamically allocated array (if it is required) based on the returned value m from the function.
#define N_MAX 50
#define N_MIN 0
int main(void) {
int n;
do{
scanf("%d", &n);
}while(N<N_MIN || N>N_MAX);
int *array = (int*) malloc(sizeof(int) * n);
int i; // number of elements in array
for (i = 0; i < n; i++) {
scanf("%d", array + i);
}
int x;
scanf("%d", &x);
//remove x from arr
for (int j = 0; j <= i; j++) {
if (*(array + j) == x) {
*(array + j) = *(array + i); // replace removed value by last value in array
i--; // decremment number of elements in array
}
}
// print
for (int j = 0; j <= i; j++) {
print("%d", *(array + j));
}
free(array)
}
Try this out!
#include <stdio.h>
#include <stdlib.h>
// Required Prototypes
int *get_nums(char *, size_t *);
int *remove_num(int *, size_t *, int);
void display(char *, int *, size_t);
int main(int argc, char *argv[])
{
size_t size = 0;
int *arr = get_nums("Enter numbers (seperated by space): ", &size);
int num;
printf("Enter number to be removed: ");
scanf("%d", &num);
display("Old Array: ", arr, size);
arr = remove_num(arr, &size, num);
display("New Array: ", arr, size);
free(arr);
return 0;
}
int *get_nums(char *label, size_t *size)
{
size_t length = 0;
int *arr = NULL;
printf("%s", label);
int c, num;
do {
scanf("%d", &num);
arr = realloc(arr, (length + 1) * sizeof(int));
arr[length++] = num;
} while ( (c = getchar()) != '\n' && c != EOF);
*size = length;
return arr;
}
int *remove_num(int *arr, size_t *size, int num)
{
// Copy elements to the new array
// Return the new array
size_t new_size = 0;
int *new_arr = NULL;
for (size_t i = 0; i < *size; ++i) {
if (arr[i] != num) {
new_arr = realloc(new_arr, (new_size + 1) * sizeof(int));
new_arr[new_size++] = arr[i];
}
}
*size = new_size;
free(arr);
return new_arr;
}
void display(char *label, int *arr, size_t size)
{
printf("%s", label);
for (size_t i = 0; i < size; ++i)
printf("%d ", arr[i]);
printf("\n");
}
The main idea is you create an array of integers. Then you copy those elements to a new array which you do not want to remove. And finally you display the new array. That's all. Yes, it's that simple. ;-)
Enter numbers (seperated by space): 1 2 3 4 3
Enter number to be removed: 3
Old Array: 1 2 3 4 3
New Array: 1 2 4
As #Ahmed Masud said in comments about too many reallocations, here's my modified answer. Please do note that the code below is little bit complex but far more efficient than my previous one.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *a;
size_t length;
size_t capacity;
} Array;
// Required Prototypes
Array *init_Array(void);
void destroy(Array *);
Array *get_nums(char *);
void remove_num(Array *, int);
void display(char *, Array *);
int main(int argc, char *argv[])
{
Array *arr = get_nums("Enter Numbers (seperated by space): ");
int num;
printf("Enter number to be removed: ");
scanf("%d", &num);
display("Old Array: ", arr);
remove_num(arr, num);
display("New Array: ", arr);
destroy(arr);
return 0;
}
Array *init_Array(void)
{
Array *arr = malloc( sizeof(Array) );
arr->capacity = 1;
arr->length = 0;
arr->a = malloc( sizeof(int) );
return arr;
}
Array *get_nums(char *label)
{
printf("%s", label);
Array *arr = init_Array();
int c, num;
do {
scanf("%d", &num);
// check and reallocate
if (arr->length == arr->capacity) {
arr->a = realloc(
arr->a,
(2 * arr->capacity) * sizeof(int)
);
arr->capacity *= 2;
}
arr->a[arr->length++] = num;
} while ((c = getchar()) != '\n' && c != EOF);
return arr;
}
void remove_num(Array *arr, int num)
{
int remv_idx = -1;
int *a = arr->a;
size_t count = 0;
for (size_t i = 0; i < arr->length; ++i) {
if (a[i] == num) count++;
if (a[i] == num && remv_idx == -1)
remv_idx = i;
if (remv_idx != -1 && remv_idx < i && a[i] != num)
a[remv_idx++] = a[i];
}
arr->length -= count;
arr->capacity = arr->length;
arr->a = realloc(a, arr->capacity * sizeof(int));
}
void display(char *label, Array *arr)
{
printf("%s", label);
for (size_t i = 0; i < arr->length; ++i)
printf("%d ", arr->a[i]);
printf("\n");
}
void destroy(Array *arr)
{
free(arr->a);
free(arr);
}
Here I did not consider any new array but removed the elements in place. I'm keeping both of my solution because you might not need the 2nd one if your input space is small. One more thing, since the question did not mention about any reallocations failures so I did not check it in my code.
Here is an approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_arr(int *arr, size_t size);
size_t remove_by_value(int *arr, size_t len, int value)
{
int count = 0; // maintain how many times we see value
int k;
for(k = 0; k < len ; k++) {
if ( arr[k] == value ) {
while(arr[count+k] == value) {
count++;
} // skip over conscutive values
if ( count + k >= len )
break;
arr[k] = arr[k+count];
arr[k+count] = value;
print_arr(arr, len);
}
}
return len-count;
}
void print_arr(int *arr, size_t size)
{
for(int k = 0; k < size; k++) {
printf("%02d ", arr[k]);
}
printf("---\n");
}
int main()
{
int test_values[] = { 0, 1, 3, 2, 3, 5, 4, 7, 8 };
size_t len = sizeof(test_values)/sizeof(int);
int *arr = malloc(len*sizeof(int));
memcpy(arr, test_values, len*sizeof(int));
print_arr(arr, len);
len = remove_by_value(arr, len, 3);
print_arr(arr, len);
arr = realloc(arr, len);
print_arr(arr, sizeof(int)*len);
return 0;
}
It bubbles the value to be extracted to the end of the array and lops it off.
The nice thing is that it doesn't use any extra memory to do its work.
The second part that is that it is NOT O(n^2) I have to think a bit about the complexity of it (seems bigger than O(n))
However it's a simple solution that keeps the order of the array, removes unneeded values simply.
i've put in the print_arr function at each step of the loop so that you can see what's happening.
Hopefully the code is clear in its purpose, if you have questions please comment and I will further explanation.
Notes
I expressly did not use sizeof(*arr) because i wanted it to be a bit more clear as to what it is. In production code one would use sizeof(*arr) instead of sizeof(int) .... However I would not be able to create a consistent example (e.g. remove_by_value would have to be similarly made generic) so I didn't to keep the example simple to understand.

How can I achieve a stackframe from not getting destroyed after returning from the function?

I am trying to store elements for Fibonacci series in the array which is inside the function and after returning from function by "return arr " my stack frame is getting destroyed and I am unable to receive values in main function. I wanted to use recursion only and printing from main function these are my conditions.
#include <stdio.h>
int *fib(int *num, int *first, int *second, int i, int *arr);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int first = 0, second = 1, i = 0;
int arr[num];
int *result = fib(&num, &first, &second, i, arr);
for (int i = 0; i < num; i++)
printf("%d ", result[i]);
}
int *fib(int *num, int *first, int *second, int i, int *arr)
{
int temp;
if (*first == 0)
printf("%d ", *first);
if (*num < 0)
{
if (*second == 1)
printf("%d ", *second);
temp = *first - *second;
*first = *second;
*second = temp;
if (*second > *num && *second < -*num)
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
else
return arr;
}
else
{
temp = *first + *second;
*first = *second;
*second = temp;
if (*second >= *num + 3)
return arr;
else
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
}
printf("\n");
}
You can't.
You are trying to fight against the very definition of what a stack frame is, and you are losing.
And you will always lose!
Instead, properly structure your program to pass data around in the way you need, in accordance with the rules and specifications of the language.
You can definitely achieve what you're wanting do without protecting the information on the function stackframes, as I don't believe your error has anything to do with that. With that said, recursion with Fibonacci numbers is kind of pointless compared to the iterative approach, it just ends up spamming extra stackframes when none are needed.
I took inspiration from Jabberwocky's answer and made an example with "recursion", though it ends up just being a fancy for loop.
#include <stdio.h>
void fib(int num, int *arr, int pos);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int arr[num];
if (num > 1) {
arr[0] = 0 ;
arr[1] = 1 ;
}
int pos = 2;
fib(num, arr, pos);
for (int i = 0; i < num; i++)
printf("%d ", arr[i]);
}
void fib(int num, int *arr, int pos)
{
if (pos < num && pos > 1)
{
arr[pos] = arr[pos - 2] + arr[pos - 1];
fib(num, arr, pos + 1);
}
else {
return;
}
}
This stores all values into arr which is allocated in main, so deletion of stackframes has no effect. The fib function even when recursive does not need to return anything because it has the array pointer and can directly change the values of the array. Of course more error checking is needed but I think this is sufficient to get the idea across.
Somewhat off topic, but you probably simply want this:
#include <stdio.h>
void fib(int num, int *arr);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int arr[num] = { 0, 1 } ;
fib(num, arr);
for (int i = 0; i < num; i++)
printf("%d ", arr[i]);
}
void fib(int num, int *arr)
{
for (int i = 0; i < num; i++)
{
arr[i + 2] = arr[i] + arr[i + 1];
}
}
Using recursion is pretty pointless here.
This is untested code, there may be bugs.
#include <stdio.h>
int fib ( int *num , int *first , int *second , int count , int *arr ) ;
int main()
{
char ch;
do
{
int num = 0;
printf("Enter any number : \n");
scanf("%d", &num);
int first = 0, second = 1, count = 0,size = num;
if(num < 0)
{
size = -(num);
}
int arr[size];
count = fib(&num, &first, &second, count, arr);
for (int j = 0; j < count; j++)
{
printf("%d ", *(arr + j));
}
printf("\n");
printf("Do you want to repeat ? Y / N\n");
scanf("\n\n%c", &ch);
} while (ch == 'y' || ch == 'Y');
}
int fib(int *num, int *first, int *second, int count, int *arr)
{
int temp;
if (*first == 0)
{
printf("%d ", *first);
}
if (*num < 0)
{
if (*second == 1)
{
printf("%d ", *second);
}
temp = *first - *second;
*first = *second;
*second = temp;
if (*second >= *num && *second <= -*num)
{
*(arr + count) = *second;
return fib(num, first, second, count+1, arr);
}
}
else if(*num > 0)
{
temp = *first + *second;
*first = *second;
*second = temp;
if (*second == 1)
{
printf("%d ", *second);
}
if (*second <= *num)
{
*(arr + count) = *second;
return fib(num, first, second, count+1, arr);
}
}
return count;
}
int *fib(int *num, int *first, int *second, int i, int *arr)
{
int temp;
if (*first == 0)
printf("%d ", *first);
if (*num < 0)
{
if (*second == 1)
printf("%d ", *second);
temp = *first - *second;
*first = *second;
*second = temp;
if (*second > *num && *second < -*num)
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
else
return arr;
}
else
{
temp = *first + *second;
*first = *second;
*second = temp;

storing the permuted strings into an array

I have been trying to store the permuted strings from the following function into an array. I am getting the following error,
Error 2 error C2106: '=' : left operand must be l-value
I want to be able to store all the permuted string and retrieve them one by one.
#include<stdio.h>
#include<string.h>
const char cstr[100][100];
char* permute(const char *a, int i, int n)
{
int j;
if (i == n)
{
cstr [k] =a;
k++;
}
else
{
for (j = i; j <= n; j++)
{
swap((a + i), (a + j));
permute(a, i + 1, n);
swap((a + i), (a + j)); //backtrack
}
}
return cstr;
}
int main ()
{
char str1 [100];
printf ( "enter a string\n" );
scanf( "%d" , &str );
permute ( str1 , 0 , n-1 );
//can't decide what parameter to consider to terminate the loop
printf( "%s" , cstr[i] ); /*then print the strings returned from permute
function*/
return 0;
}
cstr[k] = a; is where your error is.
cstr[k] is a char[100], but a is a char*. These are fundamentally different and cannot be assigned to each other. You want to do a strcpy(cstr[k], a) instead (or a memcpy).
cstrk[k] refers to a character array of size 100 and arrays cannot directly be assigned to in C, therefore it is not an l-value expression.
Following is the fully working program
#include <stdio.h>
#include <string.h>
char cstr[100][100];
int k;
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* End of swap() */
/* Function to print permutations of string */
char permute(char *a, int i, int n)
{
int j;
if (i == n)
{
strcpy(cstr[k],a);
k++;
// printf("%s\n", a);
}
else {
for (j = i; j <= n; j++)
{
swap((a + i), (a + j));
permute(a, i + 1, n);
swap((a + i), (a + j)); //backtrack
}
}
return cstr;
}
/* The main() begins */
int main()
{
char a[20];
int n,x,i;
printf("Enter a string: ");
scanf("%s", a);
n = strlen(a);
printf("Permutaions:\n");
permute(a, 0, n - 1);
for(i=0;i<k;i++)
printf("%s\n",cstr[i]);
getchar();
scanf("%d",&x);
return 0;
}

QuickSort Algorithm Number of Comparisons

I have been taking a class at Coursera and we had an assignment which was to count the number of comparisons QuickSort does on a 10,000 size array a numbers.
#include <stdio.h>
#define SIZE 10000
int ComparsionCount = 0;
void swap(int a[], int i, int j) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
int partition(int a[], int l, int r){
int p = a[l];
int i = l + 1;
int j;
for (j = l + 1; j <= r; j++) {
if (a[j] < p) {
swap(a, j, i);
i++;
}
}
swap(a, l, i - 1);
return (i - 1);
}
void add(int i) {
ComparsionCount += i;
}
int QuickSort(int a[], int l, int r){
int pivot;
if (r > 1) {
add(r - 1);
pivot = partition(a, l, r);
QuickSort(a, l, pivot - 1);
QuickSort(a, pivot + 1, r);
}
return pivot;
}
int main() {
FILE *fr;
int arr[SIZE];
int i = 0;
int elapsed_seconds;
char line[80];
fr = fopen("QuickSort.txt", "r");
while (fgets(line, 80, fr) != NULL)
{
/* get a line, up to 80 chars from fr. done if NULL */
sscanf (line, "%ld", &elapsed_seconds);
/* convert the string to a int */
arr[i] = atoi(line);
i++;
}
fclose(fr); /* close the file prior to exiting the routine */
printf("%d\n",QuickSort(arr,0,SIZE-1));
}
I am getting an segmentation error. I have identified that the problem lies in two recursive calls of QuickSort.
I have no idea of how to solve this problem,your help would be appreciated a lot
Thanks in advance.
I think you should add the code in the partition function like this:
for (j = l + 1; j <= r; j++) {
count++;
if (a[j] < p) {
...
}
Note: count is a global variable initialized to 0.

How to input an array manually in a function in c?

In my code the following function exists:
int Count_border(int loc[], int search[], int search_c){
int count = 0, i, j;
for(j = -1; j < 2; j += 2){
if(In_array(BOARD[loc[0] + j][loc[1]], search, search_c) == 1) count++;
}
for(j = -1; j < 2; j += 2){
if(In_array(BOARD[loc[0]][loc[1] + j], search, search_c) == 1) count++;
}
return count;
}
In this function I am searching for values in the array search. How it is done doesn't matter for this question. My question is however, how can I input a "manual" array, like this: Count_border(con_input, {-1, 0, 1}, 3);
This syntaxis isn't allowed by the compiler. And I don't want to create an array before the function, I really want to hardcode it.
Thank you for your help!
EDIT:
Now I am getting this error:
In function 'main':
file.c:40:1: error: expected ';' before '}' token
}
^
file.c:85:1: error: expected declaration or statement at end of input
}
Where this is my whole code, PLEASE help me out.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void Put(int letter, int number);
void Set(int letter, int number, int who);
void Init_board();
int Count_border(int loc[], int search[], int search_c);
int In_array(int val, int arr[], int size);
int BOARD[9][9]; // 0 = empty, 1 = me, 2 = enemy
int STONES[2][81][9][9], STONE_COUNTER[2];
int main(void){
char input[5];
int con_input[2], t;
Init_board();
memset(STONES, 0, sizeof(STONES));
memset(STONE_COUNTER, 0, sizeof(STONE_COUNTER));
scanf("%s", input);
if(strcmp(input,"Start") == 0){
Put(4, 4);
}
scanf("%s", input); //get the first input after start
do{
con_input[0] = input[0]-'a'; /* Convert the input */
con_input[1] = input[1];
Set(con_input[0], con_input[1], 2);
t = Count_border(con_input, (int[]){-1, 0, 1}, 3);
printf("%i\n", t);
scanf("%s", input); /* Get the next input */
} while(strcmp(input, "Quit") != 0)
}
void Init_board(){
int i,j;
memset(BOARD, -1, sizeof(BOARD));
for(i = 0; i < 9; i++){
for(j = 0; j < 9; j++){
BOARD[i][j] = 0;
}
}
}
void Put(int letter, int number){
char t = letter + 'a';
printf("%c%i\n", t, number);
//fflush(stdout);
Set(letter, number, 1);
}
void Set(int letter, int number, int who){
BOARD[letter][number] = who;
}
int Count_border(int loc[], int search[], int search_c){
int count = 0, i, j;
for(j = -1; j < 2; j += 2){
if(In_array(BOARD[loc[0] + j][loc[1]], search, search_c) == 1) count++;
}
for(j = -1; j < 2; j += 2){
if(In_array(BOARD[loc[0]][loc[1] + j], search, search_c) == 1) count++;
}
return count;
}
int In_array(int val, int arr[], int size){
int i;
for (i=0; i < size; i++) {
if (arr[i] == val)
return 1;
}
return 0;
}
/* notes:
fflush(stdout);
*/
If you have a C99 (or newer) compiler just do
Count_border(con_input, (int[]){-1, 0, 1}, 3);
this (int[]){ something } is called a compound literal in C jargon and defines a temporary object (here an int array with 3 elements) that you can pass to your function.
Something like this?
#include <stdio.h>
void f(char arr[]);
int main(int argc, char *argv[])
{
f((char [4]){'1', '2', '3', '5'});
return 0;
}
void f(char arr[4])
{
int i;
for (i = 0; i < sizeof(arr)/sizeof(*arr); i++)
printf("%c ", arr[i]);
putchar('\n');
}

Resources