binary search counter not updating - c

I have two arrays, a fixed Array A and a dynamically updating array X. I am trying to find the max interleaving factor i for X^i, such that X^i is a subsequence of A.
My X and A arrays are populating correctly, as I've tested them on each iteration through the binary search. However, my counter is not.
Here is my code:
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int j, k, max_repeat = 0;
while(min_i <= max_i){
int i = 0, count = 0, repeats = (max_i + min_i)/2;
printf("\n");
int * temp = malloc(size_x * sizeof(int) * repeats);
for(k = 0; k < size_x; ++k){
for(j = 0; j < repeats; ++j){
temp[k * repeats + j] = X[k];
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", temp[i]);
}
printf("A: ");
for (i = 0; i < size_a; i++){
printf("%d ", A[i]);
}
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
printf("Count: %d", count);
if (count >= size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
max_repeat++;
}
else{
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
free(temp);
}
printf("Max repeat: %d", max_repeat);
}
Array A = [4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1] and X = [1,2,3] initially. So X^3 = [1,1,1,2,2,2,3,3,3]. This should fail, because count is not > = size_x * repeats (count should be 5 on this iteration), and it does, but count = 0 throughout each iteration when it should clearly update. What am I missing? I have been staring at this for way to long, so I'm sure it's something simple.
EDIT Expected value:
Low 0 Mid 3 High 6 Fails
Low 0 Mid 1 High 2 Passes
Low 2 Mid 2 High 2 Fails
Actual value:
Low 0 Mid 3 High 6 Fails
Low 0 Mid 1 High 2 Fails
Low 0 Mid 0 High 0 Passes

Related

Array size changed after sorting

I'm currently working on an assignment which tells me to get the largest count number on a sequence in a array (ex: arr[] = {1,2,3,4,5}, valid sequence is {1,2},{2,3},{5}, or {2,3,4,5}. I've used an algorithm that finds the largest value of an array without sorting it, but, the online judge considers it wrong because it ran for too long (Time Limit Error). So I've changed my code to use a sorting algorithm.
I'm trying to find the largest value in an array by sorting it first, then printing the last value (biggest) of the array, which worked if I input this:
Input:
1 // cases
3 2
2 2 2
Output:
SIZE of Array is: 3
UNSORTED countArr:
0. 1
1. 1
2. 1
(after sorting) SORTED countArr:
0. 1
1. 1
2. 1
However, if I try to have to input multiple "cases" I would get:
Input:
2 // cases
4 11
2 9 1 1
3 2
2 2 2
Output:
SIZE of Array is: 4
UNSORTED countArr:
0. 2
1. 3
2. 2
3. 1
(after sorting) SORTED countArr:
0. 1
1. 2
2. 2
3. 3
SIZE of Array is: 4 //why did the array size become 4, instead of 3
UNSORTED countArr:
0. 1
1. 1
2. 1
3. 3 // and what is this 3 doing here? it should have ended at number 2.
(after sorting) SORTED countArr:
0. 1
1. 1
2. 1
3. 3 // same as above
If anyone could help, could you tell me where I'm wrong?
Source code:
#include <stdio.h>
// all function is for quicksort
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition (int arr [], int low, int high) {
int pivot = arr [high];
int i = (low - 1);
for (int j = low; j <= high- 1; j++) {
if (arr [j] < pivot) {
i++;
swap (&arr [i], &arr [j]);
}
}
swap (&arr [i + 1], &arr [high]);
return (i + 1);
}
void quickSort (int arr[], int low, int high) {
if (low < high) {
int pi = partition (arr, low, high);
quickSort (arr, low, pi - 1);
quickSort (arr, pi + 1, high);
}
}
int main () {
int cases, numofElement;
int limit, set [5001], sum = 0, count = 0, countArr [100001], size = 0, largest;
int i, j, k, l, m;
scanf ("%d", &cases);
for (i = 0; i < cases; i++) {
scanf ("%d %d", &numofElement, &limit);
for (j = 0; j < numofElement; j++) {
scanf ("%d", &set [j]);
}
// so the program knows if the array 'set []' is reaching its last digit
set [numofElement] = -2;
for (k = 0; k < numofElement; k++) {
if (set [k] > limit) {
// to skip over or (if all sequence is invalid) to print "-1"
countArr [k] = -1;
continue;
}
for (l = k; l < numofElement; l++) {
sum += set [l];
count += 1;
if ((sum <= limit) && (sum + set [l + 1] > limit || set [l + 1] == -2)) {
countArr [k] = count;
sum = 0;
count = 0;
break;
}
}
}
// count how many number there are in 'countArr []', so we can find its largest value
size = 0;
l = 0;
while (countArr [l] != 0) {
size += 1;
l++;
}
printf ("SIZE of Array is: %d\n", size);
printf ("UNSORTED countArr:\n");
for (j = 0; j < size; j++) {
printf ("%d. %d\n", j, countArr [j]);
}
// sort the 'temp []' array, and output its largest value
quickSort (countArr, 0, size - 1);
printf ("(after sorting) SORTED countArr:\n");
for (j = 0; j < size; j++) {
printf ("%d. %d\n", j, countArr [j]);
}
}
return 0;
}
Is a simple error, you don't reset the element of countArr array to 0 at the beginning of the first for cycle.
If you fix this your program should work.
After this istruction you need to add the reset to zero :
for (i = 0; i < cases; i++){
... reset to zero countArr
... rest of the programm
}

counter to check if array X is subsequence of A not working (C)

I've tried following this program by hand, but I still can't get it to work.
I have an array A = [4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1] and array X = [1,2,3].
I need to find the max number i for X^i that is a subsequence of A, and do this by binary search.
Since size of A is 20, and size of X is 3, the max possible i = 20/3 = 6. So my search will start at i = 3, which means that X^3 = [1,1,1,2,2,2,3,3,3].
This is not a subsequence of A, so binary search repeats for i = 1, X^1 = [1,2,3].
This is a subsequence of A, meaning it should pass and binary search should try again for i = 2.
However, my condition to see if the iteration passes or not is not working properly.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void create_initial_arrays(int size_a, int *A, int size_x, int *X);
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i);
int main(){
int size_a, size_x;
scanf("%d", &size_a);
scanf("%d", &size_x);
int max_i = size_a / size_x;
int min_i = 0;
printf("Max: %d\n", max_i);
int *A = (int*) malloc(size_a *sizeof(int));
int *X = (int*) malloc(size_x *sizeof(int));
create_initial_arrays(size_a, A, size_x, X);
printf("Old X: ");
for(int i = 0; i < size_x; i++){
printf("%d ", X[i]);
}
printf("\n");
binary_search(size_a, A, size_x, X, max_i, min_i);
free(X);
free(A);
}
void create_initial_arrays(int size_a, int *A, int size_x, int *X){
int i, throwaway;
for(i = 0; i < size_a; i++){
scanf("%d", &A[i]);
}
scanf("%d", &throwaway);
for(i = 0; i < size_x; i++){
scanf("%d", &X[i]);
}
scanf("%d", &throwaway);
}
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int j, k, max_repeat = 0;
while(min_i <= max_i){
int i = 0, count = 0, repeats = (max_i + min_i)/2;
printf("\n");
int * temp = (int*) malloc(size_x * sizeof(int) * repeats);
for(k = 0; k < size_x; ++k){
for(j = 0; j < repeats; ++j){
temp[k * repeats + j] = X[k];
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", temp[i]);
}
printf("A: ");
for (i = 0; i < size_a; i++){
printf("%d ", A[i]);
}
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
printf("Count: %d", count);
if (count >= size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
max_repeat++;
}
else{
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
free(temp);
}
printf("Max repeat: %d", max_repeat);
}
And this is the section that I think must be problematic:
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
I've output both Arrays to make sure they are populated correctly (they are) and the counter after each iteration. Here is my code output:
Old X: 1 2 3
New X: 1 1 1 2 2 2 3 3 3 A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 3 High 6 Fails
New X: 1 2 3 A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 1 High 2 Fails
New X: A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 0 High 0 Passes
Max repeat: 1
Notice that count remains 0 throughout. On the first iteration for X^3 = [1,1,1,2,2,2,3,3,3], the condition is true 5 times ([1,1,1,2,2] is a subsequence of A, so count should be 5, but 5 is not >= size_x * repeats(3 * 3), so it fails as expected. Binary search reduces to Low 0 Mid 1 High 2, so i = repeats = 1.
X^1 = [1,2,3] is a subsequence of A, and count should be 5 on this iteration ([1,2,3] plus two extra counts of 3) which is >= size_x * repeats (3*1), so it should pass, and redo the search for i = 2. However, count remains zero and fails.
Why is count not updating? I know I need to keep it in the loop because I need it reset to 0 for each iteration, but I don't really understand why A[j] == temp[i] is not ever passing.

Interleaving array in C

I posted earlier, but I did not properly format or add my code. Say I have an int array x = [1,2,3]. Given a value i, I want to create an array x^i, such that, if i = 3, array x^i = [1,1,1,2,2,2,3,3,3]. If i = 5, array x^i = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5]. I am dynamically allocating memory for this.
However, my code for i = 3 is creating an array = [1,2,3,1,2,3,1,2,3]. I've tried many different things, and I got something like [1,1,1,1,1,1,1,1,1] or [3,3,3,3,3,3,3,3,3] but never the correct answer.
Here is my code:
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int i, j, k, count = 0, max_repeat = 0;
while(min_i <= max_i){
int repeats = (max_i + min_i)/2;
int * temp = realloc(X, size_x * sizeof(int) * repeats);
X = temp;
for(k = 0; k < size_x; ++k){
int idx = size_x - k -1;
temp = &X[idx];
for(j = 0; j < repeats; ++j){
X[idx * repeats + j] = *temp;
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", X[i]);
}
int count = 0;
for(i = 0; i < size_x * repeats; i++){
for(j = 0; j < size_a; j++){
if(A[j] == X[i]){
count++;
i++;
}
}
}
if (count == size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
}
else
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
}
the variable repeats represents the value i in x^i.
The output is this:
Old X: 1 2 3
New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High 6 Fails
New X: 1 1 1 Low: 0 Mid 1 High 2 Fails
New X: Low: 0 Mid 0 High 0 Fails
The first iteration is correct, however, the second iteration should not be [1,1,1], it should be [1,2,3].
Where am I going wrong?
Here you go:
int misleading_function_names_is_bad_practice(size_t xsize, int x[xsize], size_t i)
{
void * const tmp = realloc(x, xsize * sizeof(*x) * i);
if (tmp == NULL) {
return -__LINE__;
}
x = tmp;
for (size_t k = 0; k < xsize; ++k) {
// index of the last original digit counting down
const size_t idx = xsize - k - 1;
const int tmp = x[idx];
for (size_t l = 0; l < i; ++l) {
// fill from the back
x[idx * i + l] = tmp;
}
}
return 0;
}
Live example available at onlinegdb.

Use binary search to find interleaving sequence in C

I have two arrays, A and X, where A >= X. I want to find the max interleaving factor i for X^i such that X^i is a subsequence of A. For example, if A = [4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1], and X = [1,2,3], then i = 1, because X^1 = [1,2,3] and that sequence is in A. My program should use a binary search to find this max interleaving factor i and trace whether or not each iteration is a sequence of A. So using binary search for the above example, i would start = 3 (as max possible for A/X = 6), and X^3 = [1,1,1,2,2,2,3,3,3] and that is not a sequence in A.
Here is my code so far:
#include <stdio.h>
#include <stdlib.h>
void create_initial_arrays(int size_a, int *A, int size_x, int *X);
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i);
int main(){
int size_a, size_x;
scanf("%d", &size_a);
scanf("%d", &size_x);
int max_i = size_a / size_x;
int min_i = 0;
printf("Max: %d\n", max_i);
int *A = (int*) malloc(size_a *sizeof(int));
int *X = (int*) malloc(size_x *sizeof(int));
create_initial_arrays(size_a, A, size_x, X);
printf("Old X: ");
for(int i = 0; i < size_x; i++){
printf("%d ", X[i]);
}
printf("\n");
binary_search(size_a, A, size_x, X, max_i, min_i); //practice reallocating size of array
//for(int i = 0; i < size_x; i++){
// printf("%d ", A[i]);
//}
}
void create_initial_arrays(int size_a, int *A, int size_x, int *X){
int i, throwaway;
for(i = 0; i < size_a; i++){
scanf("%d", &A[i]);
}
scanf("%d", &throwaway);
for(i = 0; i < size_x; i++){
scanf("%d", &X[i]);
}
scanf("%d", &throwaway);
}
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int i, j, k, count = 0, max_repeat = 0;
while(min_i <= max_i){
int repeats = (max_i + min_i)/2;
printf("\n");
int * temp = realloc(X, size_x * sizeof(int) * repeats);
X = temp;
for(k = 0; k < size_x; ++k){
int idx = size_x - k -1;
temp = &X[idx];
for(j = 0; j < repeats; ++j){
X[idx * repeats + j] = *temp;
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", X[i]);
}
for(i = 0; i < size_x * repeats; i++){
for(j = 0; j < size_a; j++){
if(A[j] == X[i]){
count++;
i++;
}
}
}
if (count == size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
max_repeat++;
}
else
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
printf("Max repeat: %d", max_repeat);
}
Here is my current output:
New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High 6 Fails
New X: 1 1 1 Low: 0 Mid 1 High 2 Fails
New X: Low: 0 Mid 0 High 0 Fails
I am expecting this:
New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High 6 Fails
New X: 1 2 3 Low: 0 Mid 1 High 2 Passes
New X: Low: 2 Mid 2 High 2 Fails
Max i = 1.
Meaning, that my code is not creating the correct array on the second iteration. X^1 should equal [1,2,3] not [1,1,1]. Why is it not creating the array properly on the second iteration but it does on the first?
Why is it not creating the array properly on the second iteration but it does on the first?
In the first loop you take X which is {1, 2, 3} and change it into {1, 1, 1, 2, 2, 2, 3, 3, 3} by repeating the first number 3 times, repeating the second number 3 times and repeating the third number 3 times.
In the second loop you start with X being {1, 1, 1, 2, 2, 2, 3, 3, 3}. Now you construct a new X by repeating the first number 1 time, repeating the second number 1 time and repeating the third number 1 time.
As the first, the second and the third numbers are all 1 you end up with {1, 1, 1}
In other words: Your first loop changed X and therefore you second loop use another value for X than the first loop. Consequently, the second loop produce an unexpected value for X

Inverse of a binary matrix in C

I have a binary matrix (zeros and ones) D[][] of dimension nxn where n is large (approximately around 1500 - 2000). I want to find the inverse of this matrix in C.
Since I'm new to C, I started with a 3 x 3 matrix and working around to generalize it to N x N. This works for int values, however since I'm working with binary 1's and 0's. In this implementation, I need unsigned int values.
I could find many solutions for int values but I didn't come across any solution for unsigned int. I'd like to find the inverse of a N x N binary matrix without using any external libraries like blas/lapack. It'd be great if anyone could provide a lead on M x N matrix.
Please note that I need inverse of a matrix, not the pseudo-inverse.
/* To find the inverse of a matrix using LU decomposition */
/* standard Headers */
#include<math.h>
#include<stdio.h>
int main() {
/* Variable declarations */
int i,j;
unsigned int n,m;
unsigned int rows,cols;
unsigned int D[3][3], d[3], C[3][3];
unsigned int x, s[3][3];
unsigned int y[3];
void LU();
n = 2;
rows=3;cols=3;
/* the matrix to be inverted */
D[0][0] = 1;
D[0][1] = 1;
D[0][2] = 0;
D[1][0] = 0;
D[1][1] = 1;
D[1][2] = 0;
D[2][0] = 1;
D[2][1] = 1;
D[2][2] = 1;
/* Store the matrix value for camparison later.
this is just to check the results, we don't need this
array for the program to work */
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++) {
C[m][j] = D[m][j];
}
}
/* Call a sub-function to calculate the LU decomposed matrix. Note that
we pass the two dimensional array [D] to the function and get it back */
LU(D, n);
printf(" \n");
printf("The matrix LU decomposed \n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
printf(" %d \t", D[m][j]);
}
printf("\n");
}
/* TO FIND THE INVERSE */
/* to find the inverse we solve [D][y]=[d] with only one element in
the [d] array put equal to one at a time */
for (m = 0; m <= rows-1; m++) {
d[0] = 0;
d[1] = 0;
d[2] = 0;
d[m] = 1;
for (i = 0; i <= n; i++) {
x = 0;
for (j = 0; j <= i - 1; j++){
x = x + D[i][j] * y[j];
}
y[i] = (d[i] - x);
}
for (i = n; i >= 0; i--) {
x = 0;
for (j = i + 1; j <= n; j++) {
x = x + D[i][j] * s[j][m];
}
s[i][m] = (y[i] - x) / D[i][i];
}
}
/* Print the inverse matrix */
printf("The Inverse Matrix\n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
printf(" %d \t", s[m][j]);
}
printf("\n");
}
/* check that the product of the matrix with its iverse results
is indeed a unit matrix */
printf("The product\n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
x = 0;
for (i = 0; i <= 2; i++) {
x = x + C[m][i] * s[i][j];
}
//printf(" %d %d %f \n", m, j, x);
printf("%d \t",x);
}
printf("\n");
}
return 0;
}
/* The function that calcualtes the LU deomposed matrix.
Note that it receives the matrix as a two dimensional array
of pointers. Any change made to [D] here will also change its
value in the main function. So there is no need of an explicit
"return" statement and the function is of type "void". */
void LU(int (*D)[3][3], int n) {
int i, j, k;
int x;
printf("The matrix \n");
for (j = 0; j <= 2; j++) {
printf(" %d %d %d \n", (*D)[j][0], (*D)[j][1], (*D)[j][2]);
}
for (k = 0; k <= n - 1; k++) {
for (j = k + 1; j <= n; j++) {
x = (*D)[j][k] / (*D)[k][k];
for (i = k; i <= n; i++) {
(*D)[j][i] = (*D)[j][i] - x * (*D)[k][i];
}
(*D)[j][k] = x;
}
}
}
This is just a sample example that I tried and I have -1 values in the inverse matrix which is my main concern. I have 1000 x 1000 matrix of binary values and the inverse should also be in binary.
The matrix:
1 1 0
0 1 0
1 1 1
The matrix LU decomposed:
1 1 0
0 1 0
1 0 1
The Inverse Matrix:
1 -1 0
0 1 0
-1 0 1
The product:
1 0 0
0 1 0
0 0 1

Resources