C 中的重复元素消除

问题描述 投票:0回答:1

我被要求用 C 语言解决这个问题(它评分,只是一个实验室练习。):

使用单下标(一维)数组来解决以下问题 问题。读入 10 个数字,每个数字在 10 到 100 之间(含 10 和 100)。由于每个数字是 读取,仅当它不是已读取的数字的重复时才打印它。为“最坏情况”做好准备 这 10 个数字都不同。使用尽可能小的数组来解决这个问题。

我想并尝试通过使用指针并编写一个removeElement函数来解决这个问题,但它部分有效,并且当我输入多个重复项和/或因此执行此操作时,输出变得更加错误。我将代码写在单独的文件中,因此我将按顺序添加它们。另外我想澄清一下,我也尝试过 realloc 函数,但它也不起作用。我的核心算法是:当重复项出现时,减少 newSize 并将内存分配给具有新大小的新数组,然后从旧数组中传输非重复元素。我也提供了一个测试用例。

/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(){
   int* initialArray = NULL; /* array that takes all inputs and have duplicates */
   int* newArray = NULL; /* array that should have the non-duplicated elements only */

   int SIZE = 10;
   int newSize = SIZE;
   int input = 0;
   int locCtr = 0;

   initialArray = (int*)malloc(sizeof(int) * SIZE);
   newArray = (int*) malloc(sizeof(int) * newSize);

   printf("Welcome! Please enter your 10 numbers, between 10 and 100, inclusive! \n");
   while(locCtr < 10){
       scanf("%d", &input);
       if (input >= 10 && input <= 100) { //input istenen sınırlar içerisindeyse
           if(locCtr == 0){
               printf("Value: %d \n", input);
               initialArray[locCtr] = input;
               newArray[locCtr] = input;
               locCtr++;
           }
           else{
                if (isDuplicate(initialArray, SIZE, input) == 0){ //duplicate yoksa
                    printf("Value: %d \n", input);
                    initialArray[locCtr] = input;
                    locCtr++;
                }
                else if(isDuplicate(initialArray, SIZE, input) == 1){ //duplicate varsa
                    initialArray[locCtr] = input; //inputumuzu görebilmek için kaydediyoruz
                    newSize--;
                    newArray = removeElement(initialArray, newSize, input);
                    locCtr++;
                }
            }
        }
        else { //input sınırlar içerisinde değilse
            printf("Invalid input! Please enter your numbers in the interval of [10,100]! \n");
        }
    }
    
    printf("Your initial array is: ");
    printArray(initialArray, SIZE);

    printf("Your final array is: ");
    printArray(newArray, newSize);

    printf("Bye bye! \n");

    free(initialArray);
    free(newArray);

    return 0;
}
/* header.h */
int* removeElement(int* oldArray, int newSize, int input);
int isDuplicate(int* array, int SIZE, int input);
void printArray(int* finalArray, int SIZE);
/* functions.c */
#include <stdio.h>
#include <stdlib.h>
#include "header.h"

int* removeElement(int* oldArray, int newSize, int input){
    int* newArray = (int*)malloc(sizeof(int) * newSize);
    int j = 0; //newArray indeksi
    for(int i = 0; i < newSize; i++){
        if(oldArray[i] != 0){ //0 değilse al duplicate ise 0 yapıyor
          newArray[j] = oldArray[i];
          j++;
        }
    }
    return newArray;
}

int isDuplicate(int* array, int SIZE, int input){
    for(int i = 0; i < SIZE; i++){
        if(array[i] == input){
            printf("Duplicate found! \n");
            return 1;
        }
    }
    return 0;
}

void printArray(int* finalArray, int SIZE){
    printf("[%d ", finalArray[0]);
    for(int i = 1; i < SIZE - 1; i++){
        printf("%d ", finalArray[i]);
    }
    printf("%d] \n", finalArray[SIZE - 1]);
}

测试用例:

Welcome! Please enter your 10 numbers, between 10 and 100, inclusive!
10
Value: 10
20
Value: 20
30
Value: 30
40
Value: 40
40
Duplicate found!
Duplicate found!
50
Value: 50
50
Duplicate found!
Duplicate found!
60
Value: 60
75
Value: 75
80
Value: 80
Your initial array is: [10 20 30 40 40 50 50 60 75 80]
Your final array is: [10 20 30 40 40 50 50 1128087892]
Bye bye!

感谢您提前提供的帮助,如果我的问题格式有任何错误,我很抱歉(我在 Stack Overflow 上找不到任何使用指针的解决方案。)。

arrays c duplicates
1个回答
0
投票

由于您无法更改数组的大小以使用最小分配,因此您需要使用动态分配(它创建具有精确数量的不同元素的数组):

int inArray(const int *array, const size_t size, const int val)
{
    int result = 0;
    if(array && size)
    {
        for(size_t index = 0; index < size; index++)
        {
            if(array[index] == val)
            {
                result = 1;
                break;
            }
        }
    }
    return result;
}

int *distinct(const int *arr, const size_t sourceSize, size_t *destArraySize)
{
    int *distinctE = NULL;
    *destArraySize = 0;
    
    if(arr)
        for(size_t index = 0; index < sourceSize; index++)
        {
            if(!inArray(distinctE, *destArraySize, arr[index]))
            {
                int *tmp = realloc(distinctE, (*destArraySize + 1) * sizeof(*distinctE));
                if(tmp) 
                {
                    distinctE = tmp;
                    distinctE[*destArraySize] = arr[index];
                    (*destArraySize)++;
                }
                else
                {
                    free(distinctE);
                    distinctE = NULL;
                    *destArraySize = 0;
                    break;
                }
            }
        }
    return distinctE;
}

int main(void)
{
    size_t size;
    int arr[] = {10, 20, 30, 40, 40, 50, 50, 60, 75, 80};
    int *destArr = distinct(arr, sizeof(arr)/sizeof(arr[0]), &size);

    if(destArr)
    {
        printf("Result size: %zu\n", size);
        for(size_t index = 0; index < size; index++)
            printf("%d ", destArr[index]);
        printf("\n");
    }
    free(destArr);
}

https://godbolt.org/z/593EM8bsb

© www.soinside.com 2019 - 2024. All rights reserved.