is a given array a sub sequence of another array - c

building a code that will check if a group of numbers in s_array[] is a sub-sequence of array[], that means that { 1, 5, 4 } is not a sub-sequence of array, whereas { 1, 4, 5} is one (order matters)
my code will first check if the first element of s_array[] exists in array[], once a common element is found it will proceed to check if the rest of s_array[]'s elements also exist in array[] and in the same order (other elements can be between them)
#include <stdio.h>
void main(){
int s_array[] = { 5, 7, 13 };
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int i, Bcount, m, counter = 1, j = 4;
//i, Bcount and m are loop counters
//counter will count number of repeated elements
//j is the number of elements in s_array + 1
for( i = 0; i <= 15; i++ ){
if( s_array[0] == array[i] ){ // does the first element exist?
for( Bcount = 1; Bcount < j; Bcount++ ){ //checking the rest
for( m = i; m < 15; m++){
if( s_array[Bcount] == array[m] ){
counter++;
i = m;
break;
}
}
}
}
if( j == counter ){
printf( "B is a sub-sequence of A.\n" );
break;
}
else{
printf( "B is not a sub-sequence of A.\n" );
break;
}
}
}
and honestly I can't see if it is the algorithm or that I did something wrong with the coding

First of all the first loop is wrong as i goes up to 15 and at this index you access array out of bounds (undefined behavior).
Then the loop is quite simple. You only need
one loop i index for array and si for s_array
only increment si if you find the number array[i] at s_array[si]
stop the loop if i covered array, or if si got the number of sub array elements (3)
if si is at least 3, the sub sequence was found
That is
int s_array[] = { 5, 7, 13 };
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int si,i;
for (si=0,i=0 ; i<15 && si<3 ; i++) {
if (s_array[si] == array[i]) si++;
}
printf ("Sub was %s\n", si<3 ? "not found":"found");

Should J not be equal to 3 and the first fot loop index to 14 (or make it strictly less than 15 rather than less than or equal to)? In your second for loop j may be equal to 3 and s_array[3] is invalid. I would try something like:
Bcount = 0;
counter = 1;
for( i = 0; i <= 14; i++ ){
if( s_array[Bcount] == array[i] ){
counter++;
Bcount++;
if(counter == 3){
printf("Success");
break;
}
}
}

In your example, the problem is that the loop get's terminated by the outer if condition:
if( j == counter ){
printf( "B is a sub-sequence of A.\n" );
break;
}
else{
printf( "B is not a sub-sequence of A.\n" );
break;
}
after the first loop cycle, the program checks this condition and breaks.
This condition should be outside the loop.

Related

print evens number and odds number from an array

Declare an array containing these number and print the evens numbers and odd numbers
Now I initialized an array that containing 11 integers.
Here is my code
#include <stdio.h>
int main(void) {
int nums[11] = {11,3,9,7,6,10,13,17,2,8,3}; // create an variables that store integers
int evens[11] = {0}; // initialized an array to store even numbers
int odds[11] = {0}; // initialized an array to store even numbers
int length = sizeof(nums) / sizeof(nums[0]); // get the length of nums
int nums_index = 0;
int evens_index = 0;
int odds_index = 0;
for (nums_index; nums_index < length;nums_index++) {
if (nums[nums_index] % 2 == 0) {
evens[evens_index] = nums[nums_index];
evens_index++;
}
else if(nums[nums_index] % 2 != 0) {
odds[odds_index] = nums[nums_index];
odds_index++;
}
printf("%d\n",evens[evens_index]);
printf("%d\n",odds[odds_index]);
}
return 0;
}
The major question is whether the output has problems when I compile my code.
The output is :0 11 0 3 0 9 0 7 6 0 10 0 0 13 0 17 2 0 8 0 0 3
Why it could happened?
Thank you all.
You need separate indexing for each array, advancing the index for evens and odds only when nums[i] value is one of the two.
Otherwise you would get sort of a copy of nums with zeroes in place of those numbers of the opposite type (odd/even).
For instance:
int j = 0;
int k = 0;
for (int i = 0; i < length; i++) {
if (nums[i] % 2 == 0) {
evens[j] = nums[i];
j++;
}
else if(nums[i] % 2 != 0) {
odds[k] = nums[i];
k++;
}
printf("%d\n",evens[i]);
printf("%d\n",odds[i]);
}
This will compose the arrays like:
11 3 9 7 13 17 3 0 0 0 0 --- for odds
6 10 2 8 0 0 0 0 0 0 0 0 --- for evens
The second problem is that you are printing inside the loop, firstly a value from evens and immediately after a value for odds.
So if you want to display them nice and separate, you can move both printf outside the first loop, then looping again on each result array for displaying it completely, before proceding to the other.
#include <stdio.h>
void PrintNumbers(int*, int);
int main(void) {
int nums[11] = {11,3,9,7,6,10,13,17,2,8,3}; // create an variables that store integers
int evens[11] = {0}; // initialized an array to store even numbers
int odds[11] = {0}; // initialized an array to store even numbers
int length = sizeof(nums) / sizeof(nums[0]); // get the length of nums
int nums_index = 0;
int evens_index = 0;
int odds_index = 0;
for (nums_index; nums_index < length; nums_index++)
{
if (nums[nums_index] % 2 == 0)
{
evens[evens_index] = nums[nums_index];
evens_index++;
}
else if(nums[nums_index] % 2 != 0)
{
odds[odds_index] = nums[nums_index];
odds_index++;
}
}
printf("Original List: ");
PrintNumbers(nums, length);
printf("Even numbers: ");
PrintNumbers(evens, length);
printf("Odd numbers: ");
PrintNumbers(odds, length);
return 0;
}
void PrintNumbers(int* numbers, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d, ", numbers[i]);
}
printf("\n");
}
Output:
Original List: 11, 3, 9, 7, 6, 10, 13, 17, 2, 8, 3,
Even numbers: 6, 10, 2, 8, 0, 0, 0, 0, 0, 0, 0,
Odd numbers: 11, 3, 9, 7, 13, 17, 3, 0, 0, 0, 0,

Trying to write a program that counts the amount of even numbers in an array and returns the value

I am trying to make a program that will count the number of even numbers in the provided arrays. When I run the program now, it will return the amount of numbers in the array, but not the amount of even numbers. For some reason my count_even function doesn't work. Can anyone help?
#include <stdio.h>
int main()
{
int data_array_1[] = { 1, 3, 5, 7, 9, 11 };
int data_array_2[] = { 2, -4, 6, -8, 10, -12, 14, -16 };
int data_array_3[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int data_array_4[] = { 6, 2, 4, 5, 1, -9 };
int data_array_5[] = { 1, 3, 9, 23, 5, -2, 4 };
int result_1 = count_even(data_array_1, 6);
printf("data_array_1 has %d even numbers.\n", result_1);
int result_2 = count_even(data_array_2, 8);
printf("data_array_2 has %d even numbers.\n", result_2);
int result_3 = count_even(data_array_3, 11);
printf("data_array_3 has %d even numbers.\n", result_3);
int result_4 = count_even(data_array_4, 6);
printf("data_array_4 has %d even numbers.\n", result_4);
int result_5 = count_even(data_array_5, 7);
printf("data_array_5 has %d even numbers.\n", result_5);
return 0;
}
int count_even(int* data_array, int size)
{
int even_num = 0;
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
The condition in your for loop is wrong.
The correct condition should say "as long as the index is smaller than size", but yours say "as long as the index equal to to size".
The condition should be i < size.
As for the result, it seems like it should return 0 (for the non-working code), not size.
Also, you are using size as an index, when you should use i.
In your count_even function, you are using the size attribute as the array index, when it should be i
int count_even(int* data_array, int size)
{
int even_num = 0
for(int i = 0; i <= size, ++i)
{
if(data_array[i] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
these two lines are the root of the problems in the code:
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
the for() statement, should be:
for (int i = 0; i < size; i++)
so the loop exits when reaching the end of the array
the if() statement is always looking at the same entry beyond the end of the array, This is undefined behaviour
The if() statement should be:
if (data_array[i] % 2 == 0)
However, the modulo operator & is not a good choice for negative numbers
a better choice would be:
if ( !(data_array[i] & 1 ) )

C best function to get split array on elements less, equals and greater than some value

I am programming in C. What is the best method (I mean in linear time) to spit array on elements less, equals and greater than some value x.
For example if I have array
{1, 4, 6, 7, 13, 1, 7, 3, 5, 11}
and x = 7 then it should be
{1, 4, 6, 1, 3, 5, 7, 7, 13, 11 }
I don't want to sort elements because I need more efficient way. Of course in this example in could be any permutation of {1, 4, 6, 1, 3, 5} and {13, 11}.
My thougt: less or grater than some element in array... In this example it is 7.
My function is:
int x = 7;
int u =0, z = 0;
for(int i=0; i<size-1; i++) // size - 1 because the last element will be choosen value
{
if(A[i] == x)
swap(A[i], A[u]);
else if(A[i] == x)
{
swap(A[i], A[n-(++z)]);
continue;
}
i++
}
for(int i = 0; i<z; i++)
swap(A[u+i],A[size-(++z)];
where u is number of current less elements, and z is the number of equals element
But if I have every elements in array equals there it doesn't work (size-(++z)) is going under 0
This is the so-called Dutch national flag problem, named after the three-striped Dutch flag. (It was named that by E.W. Dijkstra, who was Dutch.) It's similar to the partition function needed to implement quicksort, but in most explanations of quicksort a two-way partitioning algorithm is presented whereas here we are looking for a three-way partition. The classic quicksort partitioning algorithms divide the vector into two parts, one consisting of elements no greater than the pivot and the other consisting of elements strictly greater. [See note 1]
The wikipedia article gives pseudocode for Dijkstra's solution, which (unlike the classic partition algorithm usually presented in discussions of quicksort) moves left to right through the vector:
void dutchflag(int* v, size_t n, int x) {
for (size_t lo = 0, hi = n, j = 0; j < hi; ) {
if (v[j] < x) {
swap(v, lo, j); ++lo; ++j;
} else if (v[j] > x) {
--hi; swap(v, j, hi);
} else {
++j;
}
}
There is another algorithm, discovered in 1993 by Bentley and McIlroy and published in their paper "Engineering a Sort Function" which has some nice diagrams illustrating how various partitioning functions work, as well as some discussion about why partitioning algorithms matter. The Bentley & McIlroy algorithm is better in the case that the pivot element occurs infrequently in the list while Dijkstra's is better if it appears often, so you have to know something about your data in order to choose between them. I believe that most modern quicksort algorithms use Bentley & McIlroy, because the common case is that the array to be sorted has few duplicates.
Notes
The Hoare algorithm as presented in the Wikipedia Quicksort article, does not rearrange values equal to the pivot, so they can end up being present in both partitions. Consequently, it is not a true partitioning algorithm.
You can do this:
1) Loop through the array, if element is less than x then put in new array1.
2)If element is greater than x then put in new array2.
This is linear time O(n)
I tried something like this below which I think is O(n). Took me a little bit to work the kinks out but I think it's pretty similar to the dutchflag answer above.
My ouptput
a.exe
1 4 6 5 3 1 7 7 11 13
1 4 5 6 3 1 7 7 7 11 13
code:
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
void order(int * list, int size, int orderVal)
{
int firstIdx, lastIdx, currVal, tempVal;
firstIdx = 0;
lastIdx = size-1;
for ( ;lastIdx>firstIdx;firstIdx++)
{
currVal = list[firstIdx];
if (currVal >= orderVal)
{
tempVal = list[lastIdx];
list[lastIdx] = currVal;
lastIdx--;
list[firstIdx] = tempVal;
if (tempVal >= orderVal)
firstIdx--;
}
}
lastIdx = size-1;
for( ;lastIdx>firstIdx && middleNum>0;lastIdx--)
{
currVal = list[lastIdx];
if (currVal == orderVal)
{
tempVal = list[firstIdx];
list[firstIdx] = currVal;
firstIdx++;
list[lastIdx] = tempVal;
if (tempVal == orderVal)
lastIdx++;
}
}
}
int main(int argc, char * argv[])
{
int i;
int list[] = {1, 4, 6, 7, 13, 1, 7, 3, 5, 11};
int list2[] = {1, 4, 7, 6, 7, 13, 1, 7, 3, 5, 11};
order(list, ARRAY_SIZE(list), 7);
for (i=0; i<ARRAY_SIZE(list); i++)
printf("%d ", list[i]);
printf("\n");
order(list2, ARRAY_SIZE(list2), 7);
for (i=0; i<ARRAY_SIZE(list2); i++)
printf("%d ", list2[i]);
}
Here is an example using a bubble sort. Which type of sort algorithm is best, is up to you, this is just to demonstrate. Here, I treat values < x as -1, values == x as 0, values > x as 1.
Note that the elements < x and those > x are still in the same sequence.
#include <stdio.h>
int main(void)
{
int array[] = { 1, 4, 6, 7, 13, 1, 7, 3, 5, 11 };
int x = 7;
int len = sizeof array / sizeof array[0];
int i, j, m, n, tmp;
for (i=0; i<len-1; i++) {
m = array[i] < x ? -1 : array[i] == x ? 0 : 1;
for (j=i+1; j<len; j++) {
n = array[j] < x ? -1 : array[j] == x ? 0 : 1;
if (m > n) {
tmp = array[i]; // swap the array element
array[i] = array[j];
array[j] = tmp;
m = n; // and replace alias
}
}
}
for(i=0; i<len; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}
Program output:
1 4 6 1 3 5 7 7 13 11

synchronization of position in different watch

I have tried to solve the following problem unsuccessfully:
You are given 16 clocks, all set at some position between 1 and 12. The initial configuration is:
12, 9, 3, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are given a set of switch lines:
# define max_switch 10
int switchLines[max_switch][5] =
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
Entries equal to -1 are ignored. When you press a switch, the value of the clocks listed in the switch line increases by 3.
For example pressing the first switch in the initial configuration would yield:
3, 12, 6, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are allowed to press any switch any number of time in any order.
What is the minimum number of switch presses needed to set all the clocks to 12 ?
I am looking for an algorithm to solve the above problem.
Below is the solution I am trying
#include <stdio.h>
#include <stdlib.h>
int clock1[16] ={12, 9, 3, 12 ,6, 6 ,9 ,3 ,12, 9, 12, 9 ,12 ,12, 6 ,6};
int swicthApplied = 0;
#define mac_sw 10
int switchLink[mac_sw][5]=
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
int isSwicthRequired()
{
int i=0, need = 0;
for(i=0;i<16;i++)
{
if(clock1[i] < 12)
{
need = 1;
}
}
return need;
}
int findmax(int array[], int size)
{
int maximum, c, location = 0;
maximum = array[0];
if(array[0] == 0) location = -2;
for (c = 1; c < size; c++)
{
if (array[c] > maximum)
{
maximum = array[c];
location = c ;
}
}
return location +1;
}
runSwicth(int pos)
{
int i =0;
for(i=0;i<5;i++)
{
int valu = switchLink[pos][i];
if(valu == -1 ) continue;
if(clock1 [valu] == 12)
{
// continue;
clock1 [valu] = 3;
}
else
clock1 [valu] = clock1[valu] + 3;
}
printClock(clock1,16);
swicthApplied = 1 + swicthApplied;
//exit(0);
}
int findBestMatchSwitch( void)
{
//if(maxSwicth >=10) return -1;
int maxSwicth = mac_sw,numberofSwicths = 5,i,j;
int array[10] = {0,0,0,0,0,0,0,0,0,0};
for( i = 0;i<maxSwicth;i++)
{
for(j=0;j<numberofSwicths;j++)
{
int pos = switchLink[i][j] ;
if(pos == -1) continue;
if(clock1[pos] != 12)
{
array[i] = array[i] +1;
}
}
}
int loc = findmax(array,10);
if(loc == -1) return -1;
applySwicth(loc -1);
//omitLoc[loc-1] = -1;
return 0;
//exit(0);
}
int runAlignment()
{
int need =0;
while(1)
{
need = isSwicthRequired();
if (need ==0) break;
if(findBestMatchSwitch() == -1)
{
return -1;
}
}
return need;
}
int main(void) {
runAlignment();
printf("Swicthes Required [%d]",swicthApplied);
//getClockneed();
//printClock(clockNeed,16);
return EXIT_SUCCESS;
}
By definition, a solution is a list of switches of minimum length such that, when the switches are pressed in sequence, the initial configuration is transformed into the desired one.
Note that the order in which the switches are pressed doesn't actually matter. Note also that in a minimal solution no switch is pressed more than three times.
Hence for each of ten switches, you have four choices (0 to 3 presses) to consider, i.e. the total number of possibilities to examine is 4^10 or about a million.

C - Recursive, cumulative sum of an array

I've been tasked with making a recursive function that takes an array of numbers, and turns it into an array of the cumulative sum of all the numbers up to this point, thus:
1, 2, 3, 4, 5 becomes 1, 3, 6, 10, 15
This is what I came up with:
#include <stdio.h>
int cumul(int tab[], int length, int ind) {
if (ind > 0) {
tab[ind] += tab[ind-1];
}
if (ind < length) {
cumul(tab, length, ind+1);
}
return 0;
}
int main() {
int ind;
int tab[6] = {1, 2, 3, 4, 5, 6};
int length = sizeof(tab)/sizeof(tab[0]);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
cumul(tab, length, 0);
for (ind = 0; ind < length; ind++) {
printf("%d ", tab[ind]);
}
printf("\n");
return 0;
}
It works well in most cases but I've hit a snag for oddly specific arrays:
For example, it doesn't work for tab[6] = {1, 2, 3, 4, 5, 6}, here's the output:
1 2 3 4 5 6
1 3 6 10 15 21 27 7 4196016 0 -1076574208 32528 -1609083416 32767 -1609083416 32767 0 1 4195802 0 0 0 -1815242402 30550560 4195424 0 -1609083424
I have no idea why it goes bonkers. It works fine for just about any tab[5] and tab[7] arrays I tried, but fails for every tab[6] array I tried.
The problem occurs when ind reaches length-1. For example, if length is 6, and ind is 5, then the recursive call is
cumul(tab, 6, 6); // length=6 ind+1=6
At the next level of recursion, after the if ( ind > 0 ), the code will do this
tab[6] += tab[5]; // ind=6 ind-1=5
That results in undefined behavior because you're writing beyond the end of the array.
You could check the upper bound in the first if statement, e.g.
if ( ind > 0 && ind < length )
But it's better to just avoid the recursive call by changing the second if statement to
if ( ind < length - 1 )
Either change avoids the situation where you access tab[length].

Resources