Zzdouble 发表于 2020-1-31 01:44

C语言,力扣:从排序数组中删除重复项,提交有堆缓冲区溢出,新手求大神指点

本帖最后由 Zzdouble 于 2020-1-31 01:55 编辑

代码如下:

#include <stdlib.h>
#include <stdio.h>

// positionalInformation 记录数据位置信息的结构体
// @site 记录数组位置的指针
// @length 指针长度
typedef struct positionalInformation {
    int* site;
    intlength;
}arrayPostion;

// freePositionalInformation 结构体指针内存释放函数
void freePositionalInformation(arrayPostion* q) {
    free(q->site);
    free(q);
}

// arraySecedentMax函数 比较数组项数本身与之后项数,得到第一个比本身大的值,没有的话返回本身项数,输入错误会提醒并返回0
// @nums 数组首地址
// @Number 数组项数
// @arrayLength 数组长度
int arraySecedentMax(int* nums, int number, int arrayLength) {

    if (number > arrayLength - 2) {
      printf("number > arrayLength - 2(This is not right!)");
      return 0;
    }

    int loop = 0;
    int max = *(nums + number);

    while (loop != arrayLength - number) {
      loop += 1;
      if (max < *(nums + number + loop))
      {
            max = *(nums + number + loop);
            return max;
      }
    }
    return *(nums + number);
}

// getArrayMax 获取数组中最大值 数组长度请正确输入
// @nums 数组首地址
// @arrayLength 数组长度
int getArrayMax(int* nums, int arrayLength) {

    int max = -32786;
    int loop = 0;
    while (loop != arrayLength)
    {
      if (*(nums + loop) > max)
            max = *(nums + loop);

      loop += 1;
    }

    return max;
}

// getSameNumOfLocations函数 获取数字为num在数组nums中的位置,如果数组中不存在这个数字或这个数只有一个那么返回NULL,
// 否则返回一个动态数组其中不包含第一个数
// @nums 数组首地址
// @Num 具体数字
// @arrayLength 数组长度
arrayPostion* getSameNumOfLocations(int* nums, int num, int arrayLength)
{
    int counts = 0;
    int number = 0;

    arrayPostion* postion = NULL;

    for (int i = 0; i < arrayLength; i++) {
      if (*(nums + i) == num)
            counts += 1;
    }

    if (counts < 2) {
      return postion;
    }

    postion = (arrayPostion*)malloc(sizeof(arrayPostion));
    if (postion == NULL) {
      printf("postion 动态申请失败");
      return NULL;
    }

    postion->site = (int*)malloc(counts * sizeof(int));
    postion->length = counts;

    if (postion->site == NULL) {
      printf("postion->site 动态申请失败");
      return NULL;
    }

    //counts = 0;
    counts = 1;

    for (int i = 0; i < arrayLength; i++) {
      if (*(nums + i) == num) {
            // counts += 1;

            if (counts > 1) {
                *(postion->site + counts - 2) = i;
            }

            counts += 1;
      }
    }

    return postion;
}

// arraySort_1 对数组重新排序排序
// @nums 数组首地址
// @arrayLength 数组长度
// @site 重复数字的位置
void arraySort_1(int* nums, int arrayLength, int site) {

    int loop = 0;
    int record_num = 0;

    while (loop != arrayLength - site - 1) {
      record_num = *(nums + site + loop);
      *(nums + site + loop) = *(nums + site + loop + 1);
      *(nums + site + loop + 1) = record_num;
      loop += 1;
    }
}

// arraySort函数 根据arrayPostion* 结构体指针重新对数组指针排序
// @nums 数组首地址
// @arrayLength 数组长度
// @arrayPostion 重复数字的位置信息
void arraySort(int* nums, int arrayLength, arrayPostion* postion) {

    int loop = 0;
    int nextMax = 0;
    int arrayMax = getArrayMax(nums, arrayLength);

    while (loop != postion->length) {

      if (loop == 0) {
            nextMax = arraySecedentMax(nums, *(postion->site), arrayLength);
            *(nums + *(postion->site)) = nextMax;
      }
      else {
            *(nums + *(postion->site)) = arrayMax;
            arraySort_1(nums, arrayLength, *(postion->site));
      }

      loop += 1;
    }
    freePositionalInformation(postion);
}

// 删除重复
// @nums 数组首地址
// @numsSize 数组字节大小
int removeDuplicates(int* nums, int arrayLength) {
    int num = 0;
    int length = arrayLength;
    int loop = 0;
    int arrayMax = *(nums + (length - 1));
    // counst为1是因为最后的数不需要排序
    int counst = 1;
    arrayPostion* postion = NULL;

    while (loop != length) {

      if (arrayMax != *(nums + loop)) {
            counst += 1;
            postion = getSameNumOfLocations(nums, *(nums + loop), length);
            if (postion != NULL) {
                // 排序处理
                arraySort(nums, length, postion);
            }

      }

      loop += 1;
    }

    return counst;
}

int main()
{
    intarray[] = { 1,1,1,1,1,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,7,7,7,7,7,7,8,8,8,8,8,9,10,10,13,18,19,20,20,20,78,78,99,101,101,202,202,333,333,444};
    //intarray[] = { 1,1,2,3, };
    intlength = sizeof(array) / 4;
    //intnum = removeDuplicates(array, sizeof(array));
    int number = removeDuplicates(array, length);


    //int* q = (int*)malloc(20 * sizeof(int));
    //*q = 1;
    //*(q + 1) = 1;
    //*(q + 2) = 1;
    //*(q + 3) = 1;
    //*(q + 4) = 1;
    //*(q + 5) = 1;
    //*(q + 6) = 2;
    //*(q + 7) = 2;
    //*(q + 8) = 2;
    //*(q + 9) = 3;
    //*(q + 10) = 3;
    //*(q + 11) = 3;
    //*(q + 12) = 4;
    //*(q + 13) = 4;
    //*(q + 14) = 5;
    //*(q + 15) = 6;
    //*(q + 16) = 7;
    //*(q + 17) = 7;
    //*(q + 18) = 7;
    //*(q + 19) = 8;
    //number = removeDuplicates(q, 20);

    //for (int i = 0; i < 20; i++)
    //{
    //    printf("%d", *(q + i));
    //}
    printf("hello world");
}

Zzdouble 发表于 2020-1-31 02:00

查了百度,把结构体改成变量和把循环中变量顺序调整过,依然没能过,新手求大神指点一下。

fc4lee 发表于 2020-1-31 20:58

本帖最后由 fc4lee 于 2020-1-31 21:25 编辑

同学,你的解体思路有点乱,比较简单的思路是:
1.    先准备一个和给定数组一样大小的数组并初始化,比如:int result[],用来存放去重后的结果;
2.    遍历整个给定数组array[],如果当前被访问的数组成员不存在于result中,则拷贝该成员到result中,如果已存在于result中,则继续访问下一个array数组成员
然后
就没有然后了

Zzdouble 发表于 2020-1-31 21:38

fc4lee 发表于 2020-1-31 20:58
同学,你的解体思路有点乱,比较简单的思路是:
1.    先准备一个和给定数组一样大小的数组并初始化,比如 ...

题目网址:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/1/array/21/
从排序数组中删除重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

fc4lee 发表于 2020-1-31 21:43

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int result ; //存放去重后的数

/*
@para num   待检查数字
@para array 待检查数组
@para length 待检查数组长度
@Return 0,存在于数组中
      1,不存在于数组中
*/
int in_array(int num, int* array, int length)
{
      int flag = 1, i = 0;
      for(i = 0; i<=length; i++){
                if(num == array){
                        flag = 0;
                        break;
                }
      }
      return flag;      

}

int main()
{
    int i = 0, array[] = { 1,1,1,1,1,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,7,7,7,7,7,7,8,8,8,8,8,9,10,10,13,18,19,20,20,20,78,78,99,101,101,202,202,333,333,444};
    int length = sizeof(array) / sizeof(int);//int 字长不一定是4
    int result_length = 0;
    memset(result, 0, sizeof(result));
    for(i = 0; i<=length; i++){
            if(0 == in_array(array, result, result_length)) continue;// 存在,继续访问下一个
            else{
                result = array;
            }
    }
/*   
    for(i = 0; i<length; i++){
      if(0!=result[%d])
      printf("result[%d] = %d\n", i, result);
    }
*/
    return 0;
}
            x1      >    <    >>    <<    O
   
x1

Zzdouble 发表于 2020-1-31 21:50

fc4lee 发表于 2020-1-31 21:43
#include
#include
#include


感谢解答

Zzdouble 发表于 2020-1-31 21:56

找到问题了,在arraySort_1函数中
页: [1]
查看完整版本: C语言,力扣:从排序数组中删除重复项,提交有堆缓冲区溢出,新手求大神指点