0

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?

quazi_moto
  • 449
  • 1
  • 3
  • 14
  • You need to keep a copy of the original X array. The code that computes the new X only works when X is being expanded from the original. – user3386109 Oct 06 '18 at 03:42

1 Answers1

1

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

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • I understand what you're saying, and I know I need another array to hold the original array. I'm really not sure how to fix it though. I was actually trying to save the original with the temp variable. I need the expansion to reoccur on X, and then the binary search to occur on each iteration. Could you show me how to do this? Also, it looks like my binary search is still failing. [1,1,1], even though incorrect, should still pass. – quazi_moto Oct 06 '18 at 03:59
  • @Rahme The solution to this problem is simple. Just don't change `X`. Instead do the work on `temp`. Once that is fixed, you can ask a new question for any other problem you have. One problem -> One question. Another problem -> Another question. – Support Ukraine Oct 06 '18 at 04:04
  • So if I take out the line X = temp, I get a malloc memory error. How would I change the line X[idx * repeats + j] = *temp to temp[idx * repeats + j] = ?? – quazi_moto Oct 06 '18 at 04:08
  • @Rahme Something like: `temp[idx * repeats + j] = X[…];` BTW: Check your last `if` statement! The `else` seems to miss some `{` and `}` – Support Ukraine Oct 06 '18 at 04:11
  • I tried X[idx] and got [1,1,1, garbage, 2,2,2, 0,1], so I think it's close to that. Any more hints? :) – quazi_moto Oct 06 '18 at 04:18
  • @Rahme My advice would be to rewrite the loop where you construct `temp`. Currently you are doing it "backwards", i.e. handling last element of `X` first. You probably did that because you were changing `X` and had to take care about overwriting. However, since you don't change `X` anymore you can make the code more simple by starting from element zero of `X` – Support Ukraine Oct 06 '18 at 04:22
  • 1
    @Rahme Like: ` for(k = 0; k < size_x; ++k){ for(j = 0; j < repeats; ++j){ temp[k * repeats + j] = X[k]; } } ` – Support Ukraine Oct 06 '18 at 04:24
  • So I'm still having the same problem: works for the first iteration, error for the next. The error is "pointer being realloc'd was not allocated". – quazi_moto Oct 06 '18 at 04:33
  • @Rahme Don't use `realloc` ! Use `malloc` (and `free`) – Support Ukraine Oct 06 '18 at 04:34
  • Duh. Thank you so much for helping me this entire time. Will make a new post for binary question. I'm still very new to programming. I appreciate your help. – quazi_moto Oct 06 '18 at 04:37