0

I have a problem thats giving me a huge ache. This piece of code purpose is to fill up an array with integer values and at the same time defend against strings and etc....but it doesn't defend against duplicates, but tried I got to far as replacing the number with a new number for example Enter 6 integers 1, 2, 2, 3, 4, 5

my code will let me replace that 2 at position 1 with another number. What I want it to do is not to repeat the same number again, for example please replace 2 at position 1. I dont want the user to enter 2 again... and I want to make it to double check the work the array if any repeating numbers exists thank you.

        system("clear");
        printf("\nEntering Winning Tickets....\n");
        nanosleep((struct timespec[]){{1, 0}}, NULL);

        system("clear");
        char userInput[256];
        char c;

        int duplicationArray[6] = {-1, -1, -1, -1, -1, -1};
        for (i = 0; i < 6; i++)
        {
            printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
            fgets(userInput, 256, stdin);
            if ((sscanf(userInput, "%d %c", &winningNumbers[i], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
            {
                printf("\nInvalid Input.\n") ;
                nanosleep((struct timespec[]){{0, 350000000}}, NULL);
                system("clear");
                i = i - 1;
            }
        }

        for (i = 0; i < 6 - 1; ++i)
        {

            min = i;
            for (j = i+1; j < 6; ++j)
            {
                if (winningNumbers[j] < winningNumbers[min])
                    min = j;
            }

            temp = winningNumbers[i];
            winningNumbers[i] = winningNumbers[min];
            winningNumbers[min] = temp;

        }

        for (i = 0; i < 6; i++)
        {
            if (winningNumbers[i] == winningNumbers[i+1])
            {
                duplicationArray[i] = i;
                duplicationCounter++;

            }

            else
            {
                duplicationCounter--;
            }
        }


           if (duplicationCounter > -6)

        {

            for (i = 0; i < 6; i++)
            {
                int j, min, temp;
                min = i;
                for (j = i+1; j < 6; ++j)
                {
                    if (duplicationArray[j] > duplicationArray[min])
                        min = j;
                }

                temp = duplicationArray[i];
                duplicationArray[i] = duplicationArray[min];
                duplicationArray[min] = temp;

            }

            for (i = 0; i < 6; i++)
            {
                if (duplicationArray[i] == -1)
                {
                    zeroCounter++;
                }
            }
            int resize = (6 - zeroCounter)+1;

            for (i = 0; i <= resize; i++)
            {
                if (duplicationArray[i] == -1)
                {
                    i++;
                }

                else if (duplicationArray[i] != -1)
                {
                    system("clear");

                    printf("\nDuplicated numbers has been dected in your array. ");
                    printf("\nPlease replace the number %d at postion %d with another number: ", winningNumbers[duplicationArray[i]], duplicationArray[i]);
                    fgets(userInput, 256, stdin);

                    if ((sscanf(userInput, "%d %c", &winningNumbers[duplicationArray[i]], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
                    {
                        printf("\nInvalid Input.\n") ;
                        nanosleep((struct timespec[]){{0, 350000000}}, NULL);
                        system("clear");
                        i = i - 1;
                    }
                }               
            }

            duplicationCounter = 0;

            for (i = 0; i < 6; i++)
            {
                if (winningNumbers[i] == winningNumbers[i+1])
                {
                    duplicationArray[i] = i;
                    duplicationCounter++;

                }

                else
                {
                    duplicationCounter--;
                }

            }

            printf("%d, ", duplicationCounter);

        }
21
  • You should add comment lines to describe what each block is supposed to do. Commented Nov 22, 2013 at 7:27
  • use 50bit for duplicate check. Commented Nov 22, 2013 at 7:28
  • @user694733 Sorry I kinda described it in the beginning Commented Nov 22, 2013 at 7:30
  • @BLUEPIXY whats that? Commented Nov 22, 2013 at 7:31
  • input number range (1-50) {x | 1 <= x <= 50}, It can be seen immediately duplicate values ​​if I set the bit corresponding to the time you enter a numerical value whether it has been entered. Commented Nov 22, 2013 at 7:34

2 Answers 2

1
#include <stdio.h>
#include <stdint.h>

#define DATA_SIZE 6

int main(void){
    char userInput[256];
    int inputNum, winningNumbers[DATA_SIZE];
    uint64_t table = 0;
    int i=0;
    while(i<DATA_SIZE){
        printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
        fgets(userInput, sizeof(userInput), stdin);
        if(sscanf(userInput, "%d", &inputNum) != 1 || inputNum <= 0 || inputNum >= 50)
            continue;
        uint64_t bit = 1 << inputNum;
        if(table & bit)
            continue;
        table |= bit;
        winningNumbers[i++] = inputNum;
    }
    for(i=0;i<DATA_SIZE;++i)
        printf("%d ", winningNumbers[i]);
    printf("\n");
    return 0;
}
Sign up to request clarification or add additional context in comments.

6 Comments

+1 storing the entire table in a 64-bit unsigned. I was about to post a simple lookup table answer, but this is considerably more concise, exploiting the fact that input domain is fewer than 64 contiguous elements.
@BLUEPIXU it works amazing thank you. This is amazing can you please show me what you have done?? and how you made my code so much compressed
@Leoc He uses a 64bit number as a "table" Each number in your input is a value between 1 and 50. So he takes the number (already range-checked to be in between 1..50), and creates a 64bit value with a single bit lit, that bit being the one that corresponds to the input number. This is then bitwise-ANDed against the table var (a 64bit value initially set to 0, i.e. all bits cleared). If the matching bit in the table var is already lit, the number has been seen before, otherwise we set it and move to the next number.
@WhozCraig ahh I see, that's pretty cool, but I want to be original is there any way my code can be fixed up. I dont want to offend anyone. Its beautiful piece of code but thats just how I am
Nothing stopping you from doing the same. Just nix most of the duplicate-detection logic out of your code and replace it with the table-var approach here. The rest of your code you can certainly keep and continue to work on as needed. This really is a reasonably elegant solution for your duplicate-detection woes, and should be considered.
|
0
#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 6

int inputNumberWithRangeCheck(const char *msg, const char *errMsg, int rangeStart, int rangeEnd){
    char inputLine[256];
    int n;

    for(;;){
        printf("%s", msg);
        fgets(inputLine, sizeof(inputLine), stdin);
        if(sscanf(inputLine, "%d", &n) != 1 || n < rangeStart || n > rangeEnd)
            fprintf(stderr, "%s", errMsg);
        else
            return n;
    }
}

int inputNumber(void){
    return inputNumberWithRangeCheck(
        "\nPlease enter the winning ticket number!(#'s must be between 1-49): ",
        "Invalid Input.\n",
        1,49);
}

int *inputArray(int *array, size_t size){
    int i;
    for(i=0;i<size;++i){
        printf("\nInput for No.%d\n", i+1);
        array[i] = inputNumber();
    }
    return array;
}

int **duplicateCheck(int *array, size_t size){
    int **check, count;
    int i, j;

    check = malloc(size*sizeof(int*));
    if(!check){
        perror("memory allocate\n");
        exit(-1);
    }
    //There is no need to sort the case of a small amount of data
    //(Cost of this loop because about bubble sort)
    for(count=i=0;i<size -1;++i){
        for(j=i+1;j<size;++j){
            if(array[i] == array[j]){
                check[count++] = &array[i];
                break;
            }
        }
    }
    check[count] = NULL;
    if(count)
        return check;
    else {
        free(check);
        return NULL;
    }
}

int main(void){
    int winningNumbers[DATA_SIZE];
    int **duplication;
    int i, j;

    inputArray(winningNumbers, DATA_SIZE);

    while(NULL!=(duplication = duplicateCheck(winningNumbers, DATA_SIZE))){
        for(i=0;i<DATA_SIZE;++i){
            if(duplication[i]){
                printf("\nyour input numbers : ");
                for(j=0;j<DATA_SIZE;++j)
                    printf("%d ", winningNumbers[j]);
                fprintf(stderr, "\nThere is duplicate. Please re-enter.\n");
                *duplication[i] = inputNumber();
            } else
                break;
        }
        free(duplication);
    }
    for(i=0;i<DATA_SIZE;++i)
        printf("%d ", winningNumbers[i]);
    printf("\n");
    return 0;
}

4 Comments

Then what's the difference
error: expected ';' at end of declaration ...*msg, char *errMsg, int rangeStart, int rangeEnd) warning: format string is not a string literal (potentially insecure) [-Wformat-security] ormat string is not a string literal (potentially insecure) [-Wformat-security]
@Leoc warning will appear in clang, but it is not the error. It is assumed that have failed to copy the code if error is that out.
I was fixed inputNumberWithRangeCheck. I think the warning will become not now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.