Permutation of an array of strings - c

I am solving this challenge :
https://www.hackerrank.com/challenges/permutations-of-strings/problem
I am using this algorithm :
https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
Suppose I enter my array of strings as {"a", "b", "c"}, then the output should be :
a b c
a c b
b c a
c b a
b a c
c a b
Since there are 3 distinct strings, there are 3! = 6 permutations.
The program is also supposed to handle duplicate cases, so if I enter {"a", "b", "b"}, there will only be 3! / 2! = 3 permutations.
Anyways when my program reaches c b a then it quits. Why? How can I fix that?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(char** s1, char** s2) // to swap two strings
{
char* temp = *s1;
*s1 = *s2;
*s2 = temp;
}
int next_permutation(int n, char **s)
{
/**
* Complete this method
* Return 0 when there is no next permutation and 1 otherwise
* Modify array s to its next permutation
*/
int k, i, l;
k = i = l = 0;
for(i = n - 2; i >= 0; i--) // first step
if(strcmp(s[i], s[i + 1]) < 0) {
k = i;
break;
}
if(i == -1)
return 0;
for(i = n - 1; i >= k + 1; i--) // second step
if(strcmp(s[k], s[i]) < 0) {
l = i;
break;
}
swap(&s[k], &s[l]); // third step
for(i = k + 1; i < n / 2; i++) // fourth step
swap(&s[i], &s[n - i - 1]);
return 1;
}
int main() // locked code
{
char **s;
int n;
scanf("%d", &n);
s = calloc(n, sizeof(char*));
for (int i = 0; i < n; i++)
{
s[i] = calloc(11, sizeof(char));
scanf("%s", s[i]);
}
do
{
for (int i = 0; i < n; i++)
printf("%s%c", s[i], i == n - 1 ? '\n' : ' ');
} while (next_permutation(n, s));
for (int i = 0; i < n; i++)
free(s[i]);
free(s);
return 0;
}

This is the final code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(char** s1, char** s2) // swaps two strings
{
char* temp = *s1;
*s1 = *s2;
*s2 = temp;
}
int next_permutation(int n, char **s) // function to complete
{
int k, i, l;
k = i = l = 0;
for(i = n - 2; i >= 0; i--) // step 1
if(strcmp(s[i], s[i + 1]) < 0) {
k = i;
break;
}
if(i == -1)
return 0;
for(i = n - 1; i >= k + 1; i--) // step 2
if(strcmp(s[k], s[i]) < 0) {
l = i;
break;
}
swap(&s[k], &s[l]); // step 3
int inner = k + 1 + n - 1; // step 4
int cond = inner / 2;
for(i = n - 1; i > cond; i--)
swap(&s[i], &s[inner - i]);
return 1;
}
int main() // locked code
{
char **s;
int n;
scanf("%d", &n);
s = calloc(n, sizeof(char*));
for (int i = 0; i < n; i++)
{
s[i] = calloc(11, sizeof(char));
scanf("%s", s[i]);
}
do
{
for (int i = 0; i < n; i++)
printf("%s%c", s[i], i == n - 1 ? '\n' : ' ');
} while (next_permutation(n, s));
for (int i = 0; i < n; i++)
free(s[i]);
free(s);
return 0;
}

Related

cant change the character in c

I'm learning c and I have a problem with the following code. I want to convert "Hello" to "H*llo". But the code does not work.
The code does not give an error and does not work.
#include <stdio.h>
int length(char *abc){
int i;
for (i = 0; i < abc[i]; i++);
return i;
}
int hideAfromB(char *a, char *b){
int n = 0;
int aLength = length(a);
int bLength = length(b);
for (int i = 0; i < bLength; i++){
if (a[0+n] == b[i]){
n = n + 1;
if (n == aLength){
for (int j = 0; j < aLength; j++)
{
b[i-j] = '*';
}
n = 0;
}
}
else{
n = 0;
}
}
printf("%s",b);
return 0;
}
int main()
{
hideAfromB("e","Hello");
return 0;
}
I need help.
Thanks.
Because the string "Hello" is a constant and you can't change it.
As other have stated, declaring explicitly a char array will sove the problem:
#include <stdio.h>
#include <string.h>
int length(char *abc){
int i;
for (i = 0; i < abc[i]; i++);
return i;
}
int hideAfromB(char *a, char *b){
int n = 0;
int aLength = strlen(a);
int bLength = strlen(b);
for (int i = 0; i < bLength; i++){
if (a[0+n] == b[i]){
n = n + 1;
if (n == aLength){
for (int j = 0; j < aLength; j++)
{
b[i-j] = '*';
}
n = 0;
}
}
else{
n = 0;
}
}
printf("%s",b);
return 0;
}
int main()
{
char t [] = "Hello";
hideAfromB("e",t);
return 0;
}
Link to the fixed code:
The main issue is that the second argument in hideAfromB("e","Hello"); is a constant string which can not be modified.
for (i = 0; i < abc[i]; i++);
This literally iterates through the array until the iterator value is bigger than the value in the array while executing an empty instruction (;).
size_t is the proper type for string length.
You could use strstr to find a single character in a string.
#include <stdio.h>
#include <string.h>
int length(char *abc){
for (int i = 0; i >= 0; i++) {
if (abc[i] == '\0') {
return i;
}
}
return -1; // indicate string end not found
}
int hideAfromB(char *a, char *b){
int n = 0;
size_t aLength = strlen(a); // standard function
int bLength = length(b); // modified own function
for (size_t i = 0; i < bLength; i++){
if (a[n] == b[i]){
n = n + 1;
if (n == aLength){
for (int j = 0; j < aLength; j++)
{
b[i-j] = '*';
}
n = 0;
}
}
else{
n = 0;
}
}
printf("%s\n",b);
return 0;
}
int main()
{
char hello[] = "Hello"; // the elements of the array can be modified
hideAfromB("e", hello);
return 0;
}
$ gcc -Wall compare.c
$ ./a.out
H*llo
$

remove duplicate number in array in c

I want my output print the array without any duplicate number
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUBBLE 5
int main()
{
int myArray[BUBBLE];
int i, j ,a , b, k;
int temp = 0;
int num;
int cunt, size;
cunt=0;
float floatType;
int integerType;
srand(time(NULL));
make the array randomlly
//Fill Array Randomlly
for (i = 0; i < BUBBLE; i ++)
{
num = rand() % BUBBLE + 1;
myArray[i] = num;
}
here my problem is not working
in the program tell me
Error value required as decrement operand
for (a = 0; i < BUBBLE; a++) {
for (b = a + 1; j < BUBBLE;) {
if (myArray[i] == myArray[i]) {
for (k = b; k < BUBBLE; k++) {
myArray[k] = myArray[k + 1];
}
BUBBLE --;
} else
b++;
}
}
Sort Array With Bobble Algorhim
here my sort
for(i = 0; i < BUBBLE; i++)
{
for (j = 0; j < BUBBLE-1; j++)
{
if (myArray[j] > myArray[j+1])
{
temp = myArray[j];
myArray[j] = myArray[j+1];
myArray[j+1] = temp;
cunt++;
}
}/*End inner for loop*/
}/*End outer for loop*/
the output
//Print Array After Sort
for (i = 0; i < BUBBLE; i++)
{
printf("%d\n",myArray[i]);
}
// Count For How Many Swap
printf("the numbeer of pases is %d \n" ,cunt);
printf("Size of float: %ld bytes\n",sizeof(floatType));
printf("Size of int: %ld bytes\n",sizeof(integerType));
system("PAUSE");
return 0;
}/*End of main*/
You may not change integer constants. At the compile-time this code snippet
for (a = 0; i < BUBBLE; a++) {
for (b = a + 1; j < BUBBLE;) {
if (myArray[i] == myArray[i]) {
for (k = b; k < BUBBLE; k++) {
myArray[k] = myArray[k + 1];
}
BUBBLE --;
} else
b++;
}
}
actually looks like
for (a = 0; i < 5; a++) {
for (b = a + 1; j < 5;) {
if (myArray[i] == myArray[i]) {
for (k = b; k < 5; k++) {
myArray[k] = myArray[k + 1];
}
5--;
^^^
} else
b++;
}
}
That is the compiler substitutes the name BUBBLE for the integer constant 5.
Moreover it is unclear where for example the variables i and j are initialized. And this condition in the if statement
if (myArray[i] == myArray[i]) {
^^^ ^^^
does not make sense.
You should declare a variable that will keep the actual number of elements in the array during deleting duplicates because you can not change the size of an already initialized array.
"Removing" duplicates can look as it is shown in the demonstrative program
#include <stdio.h>
#define BUBBLE 5
int main(void)
{
int a[BUBBLE] = { 1, 2, 1, 3, 2 };
for ( size_t i = 0; i < BUBBLE; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
size_t n = 0;
for ( size_t i = 0; i < BUBBLE; i++ )
{
size_t j = 0;
while ( j < i && a[j] != a[i] ) ++j;
if ( j == i )
{
if ( n != i ) a[n] = a[i];
++n;
}
}
for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
Its output is
1 2 1 3 2
1 2 3
The variable n keeps the actual number of elements of the array after removing duplicates.

Count alternating up / down sequences

Description of the problem :
Compute the number of all the sequences which go up down from some input n.
So the user input n; with that n then I create an array of numbers 1..n and then number the sequences with that property
Example: n = 4
1 3 2 4
1 4 2 3
2 3 1 4
2 4 1 3
3 4 1 2
Answer: 5
My program works but for some reason I sometimes get 0 instead of the answer.
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permute(int *array, int i, int length, int *count) {
if (length == 2) {
*count = 1;
return;
}
if (length == i) {
int v = 0, flag = 1;
while (v < length) {
if (v % 2 == 0) {
if (array[v] < array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
if (v % 2 != 0) {
if (array[v] > array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
}
if (flag == 1) {
/*
int a;
for (a = 0; a < length; a++)
printf("%d", array[a]);
printf("\n");
*/
*count = *count + 1;
}
}
int j = i;
for (j = i; j < length; j++) {
swap(array + i, array + j);
permute(array, i + 1, length, count);
swap(array + i, array + j);
}
return;
}
int main(int argc, char **argv) {
int n;
scanf("%d", &n);
int *arr = safeMalloc(n * sizeof(int));
int i;
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permute(arr, 0, n, &count);
printf("%d\n", count);
return 0;
}
You basically generate all permutations of the array elements and count the valid ones.
Your code has a minor flaw:
the loop while (v < length) { goes one step too far: you access tab[v + 1] so the loop should stop at v < length - 1. As currently coded, it has undefined behavior.
You can further simply the code:
there should be no need to special case length == 2.
flag useless as you always return when you clear it.
if (v % 2 != 0) is redundant: else would suffice.
Here is a fixed and simplified version:
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permutate(int *array, int i, int length, int *count) {
if (i == length) {
for (int v = 0; v < length - 1; v++) {
if (v % 2 == 0) {
if (array[v] >= array[v + 1]) {
return;
}
} else {
if (array[v] <= array[v + 1]) {
return;
}
}
}
*count = *count + 1;
} else {
for (int j = i; j < length; j++) {
swap(array + i, array + j);
permutate(array, i + 1, length, count);
swap(array + i, array + j);
}
}
}
int main(int argc, char **argv) {
int n;
if (scanf("%d", &n) == 1 && n > 0) {
int *arr = safeMalloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permutate(arr, 0, n, &count);
printf("%d\n", count);
}
return 0;
}
if you call tab(n,k) the number of updown sequence of length n with k being the last number in your sequence, you can write a recursive formula and implement it like that:
int N = 5+1;
int** tab = new int*[N];
for (int n = 0; n < N; n++) {
tab[n] = new int[N];
for (int k = 0; k < N; k++) {
tab[n][k] = 0;
}
}
tab[1][1] = 1;
for (int n = 2; n < N; n++) {
for (int k = 1; k <= n; k++) {
if (n % 2 == 0) {
for (int j = 0; j < k; j++) {
tab[n][k] += tab[n-1][j];
}
}
else {
for (int j = k; j < n; j++) {
tab[n][k] += tab[n-1][j];
}
}
}
}
int res = 0;
for (int j = 0; j < N; j++) {
res += tab[N - 1][j];
}
You can solve this without iterating through the permutations. Say you're trying to calculate f(n). Where can the new, high number go? It has to go in an 'up' position, which is an even position. You can have any valid sequence of odd length preceding it, and any valid sequence following it.
Let's say we're calculating f(n,k) where the highest val is in position k, zero indexed. This is zero for k even. For odd k we get:
f(n,k) = choose(n-1, k) * f(k) * f(n - k - 1)
To get f(n), sum f(n,k) over odd k < n.
We have to calculate the first few by hand.
f(0) = 1
f(1) = 1
f(2) = 1
f(3) = f(3,1) = choose(2,1) * f(1) * f(1) = 2 * 1 *1 = 2
f(4) = f(4,1) + f(4,3) = choose(3,1) * f(1) * f(2) + choose(3,3) * f(3) * f(0) = 3*1*1 + 1*2*1 = 5
f(5) = f(5,1) + f(5,3) = choose(4,1) * f(1) * f(3) + choose(4,3) * f(3) * f(1) = 4*1*2 + 4*2*1 = 16

My program for printing longest palindrome subsequence isn't working, When I run it,console windows stops working after taking input

#include <stdio.h>
#include <string.h>
int ai, aj; // ai and aj to store the value of i and j respectively
int maxx(int a, int b) { // to return max of the two numbers
return (a <= b) ? b : a;
}
void LongestPal(char a[], int n) { // to find longest palindrome
int i, j, max = 0;
int p[1000][1000] = { 0 };
for (j = 0; j < n; j++)
for (i = 0; i <= j; i++) {
if (i == j) { // for one string having only one character
p[i][j] = 1;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
if (j == (i + 1)) { // for string having two characters
if (a[i] == a[j]) { // if the string is like "aa","bb" etc.
p[i][j] = 2;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
} else { // if string like "ab","ba" etc.
p[i][j] = 1;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
} else { // for all other type of strings
if (a[i] == a[j]) { // if a longer palindrome found
p[i][j] = p[i-1][j-1] + 2;
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
} else { // if no longer palindrome is present
p[i][j] = maxx(p[i+1][j], p[i][j-1]);
if (max < p[i][j]) {
max = p[i][j];
ai = i;
aj = j;
}
}
}
}
}
int main() {
int i, j, n;
char a[1000];
printf("Just enter the string hoss!\n");
scanf("%s", &a);
n = strlen(a);
LongestPal(a, n);
for (i = ai; i <= aj; i++)
printf("%c", a[i]);
return 0;
}
In this program I wanna find longest palindrome Subsequence, but unable to run program
I have written comments for each case
This program for printing longest palindrome subsequence isn't working, When I run it, the Windows console stops working after taking input.
Your program fails because it allocates too much data with automatic storage (aka on the stack). int p[1000][1000] uses 4MB, probably too much for your system default stack size. You can try and use less space by allocating this array as:
int p[n][n];
This is allowed in C99, but your compiler might not support C99.
Your algorithm is a little complicated. Why not enumerate all positions for i and j and just verify with an auxiliary function if you have a palindrome there and keep track of the longest one:
#include <stdio.h>
#include <string.h>
int isPalindrome(const char *a, int i, int j) {
for (; i < j; i++, j--) {
if (a[i] != a[j])
return 0;
}
return 1;
}
void getLongestPalindrome(const char *a, int n, int *ai, int *aj) {
int i, j, maxi, maxj;
for (maxi = maxj = i = 0; i < n; i++) {
for (j = n - 1; j > i + maxj - maxi; j--) {
if (isPalindrome(a, i, j)) {
maxi = i;
maxj = j;
break;
}
}
}
*ai = maxi;
*aj = maxj;
}
int main(void) {
char a[1000];
int i, j;
printf("Enter the string: ");
if (scanf("%999s", a) == 1) {
getLongestPalindrome(a, strlen(a), &i, &j);
printf("longest palindrome at %d..%d: %.*s\n", i, j, j - i + 1, a + i);
}
return 0;
}

I cannot find memory leak. (SIGSEGV) (segmented sieve of Eratosthenes) (C)

I'm trying to implement segmented sieve of Eratosthenes in C (im beginner programmer) and it just prints proper output but I'm getting SIGSEGV when I'm submitting in on SPOJ. Can you help me spot the leak?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void segmented_sieve(int *m, int *n, int t) {
int count, i, j, l, sqrt_imax, hlp_imin;
count = i = j = l = sqrt_imax = hlp_imin = 0;
int *imin, *imax;
imin = m;
imax = n;
sqrt_imax = (int)sqrt((double)imax[t]);
int *sieve;
sieve = malloc((imax[t] + 1) * sizeof(*sieve));
memset(sieve, 1, (imax[t] + 1) * sizeof(*sieve));
for (i = 2; i <= sqrt_imax; ++i) {
for (j = i * i; j <= imax[t]; j += i)
sieve[j] = 0;
}
int *next;
next = malloc((int)sqrt(1000000000) * sizeof(*next));
for (i = 2; i <= sqrt_imax; ++i) {
if (sieve[i] > 0) {
++count;
next[count] = i;
}
}
for (i = 1; i <= count; ++i) {
if (imin[t] <= 2) {
imin[t] = 2;
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = j * j; l <= n[t]; l += j)
sieve[l] = 0;
break;
}
}
else {
hlp_imin = (int)(m[t] / next[i]);
hlp_imin *= next[i];
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = hlp_imin; l <= imax[t]; l += j)
sieve[l] = 0;
break;
}
}
}
for (i = imin[t]; i < imax[t]; ++i)
sieve[i] > 0 ? printf("%d\n", i) : 0;
free(sieve);
free(next);
}
int main()
{
int t, tmp, i;
t = tmp = i = 0;
scanf("%d", &t);
int *m;
m = malloc(t * sizeof(*m));
int *n;
n = malloc(t * sizeof(*n));
for (i = 0; i < t; ++i) {
scanf("%d", &tmp);
m[i] = tmp;
scanf("%d", &tmp);
n[i] = tmp;
}
for (i = 0; i < t; ++i) {
segmented_sieve(m, n, i);
printf("\n");
}
free(m);
free(n);
return 0;
}
I fixed it by changing int to char. now just getting TLE...
Think about what happens if you get two values imin = 2,000,000,000 and imax = 2,000,000,010. You should create a tiny sieve for just 11 numbers. But you allocate storage for 2 billion ints which is probably more than your computer can handle.

Resources