我想打印C

时间:2018-08-19 01:32:46

标签: c arrays linux pointers memory

Hi希望显示随机数组的重复元素,其大小可由用户指定。我在输出中遇到的问题是,该函数正在打印重复的次数与重复的次数相同,但是我只希望打印一次。 这是我的代码和前者之后的输出:

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

int main(void) {
int array_size = 0;
int *my_array;
int i = 0;

printf("Enter the size of the array:\n");
scanf("%d",&array_size);

my_array = malloc(array_size * sizeof my_array[0]);
if(NULL == my_array) {
    fprintf(stderr,"MEMORY ALLOLCATION FAILED \n");
    return EXIT_FAILURE;
}

for(i=0;i<array_size;i++){
    my_array[i] = rand()%array_size;
}
printf("What's in the array:\n");
for(i = 0;i<array_size;i++){
    printf("%d ",my_array[i]);
}
printf("\n");

display_repeats(my_array, array_size);
free(my_array);
return EXIT_SUCCESS;
}

void display_repeats(int *a,int n){
int *repeats;
repeats = malloc(n * sizeof repeats[0]);
int i=0;
int j=0;
int count = 0;


for(i=0;i<n;i++){
  for(j=0;j<n;j++){

     if(a[i] == a[j]){
        count++;
    }
   }
if(count>1){
repeats[i] = count;
printf("%d occurs %d times\n",a[i],repeats[i]);
}


 count = 0;

 }

free(repeats);
}

这是我得到的输出

Enter the size of the array:
5
What's in the array:
3 1 2 0 3 
3 occurs 2 times
3 occurs 2 times

我希望“ 3次出现2次”打印一次。 请帮忙!

5 个答案:

答案 0 :(得分:2)

正在发生的事情是您的代码意识到3在此块中重复了两次:

for(i=0;i<n;i++){

  for(j=0;j<n;j++){
    if(a[i] == a[j]){
    count++;
    }
  }

  if(count>1){
    repeats[i] = count;
    printf("%d occurs %d times\n",a[i],repeats[i]);
  }
}

i等于0时,它将查看数组并意识到重复3,因此count>1将是true。然后,当i等于4时,count>1将再次为true,并且您会得到两次打印。

为了解决此问题,我将创建一个数组,该数组存储已被验证为重复的数字并进行检查。

答案 1 :(得分:1)

由于您的情况是元素的值

memset(repeats, 0, n*sizeof(repeats[0]));
for(i=0;i<n;i++){
  for(j=0;j<n;j++){
     count = repeats[a[i]];
     if(count>0)
        break;
     if(a[i] == a[j]){
        count++;
     }
  }
  repeats[a[i]] = count;

这个想法是存储每个值的计数,并在开始搜索每个新值之前检查以检查是否已被计数。

答案 2 :(得分:0)

尝试一下:

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

因此,请勿将同一元素与其自身进行比较。

答案 3 :(得分:0)

display_repeats()中,您可以简单地更新2行并添加3行以使您的程序具有正确的行为。我们将在以后看到它:我们可以使用C99语法和逗号C运算符优化最终代码,以编写比原始代码少得多的行(9行而不是20行!)。 >

因此,在此答案中,您将找到如何获得具有正确行为且非常短,比初始代码短的最终代码:

void display_repeats(int *a, int n) {
  for (int i = 0; i < n; i++) {
    if (a[i] == -1) continue;
    int count = 1;
    for (int j = i + 1; j < n; j++)
      if (a[i] == a[j]) count++, a[j] = -1;
    if (count > 1) printf("%d occurs %d times\n", a[i], count);
  }
}

这个想法是在计数增加之后,将与前一个匹配的每个数组值设置为-1。因为您不想再次计算该值。

因此只需执行以下操作:

  • 在您写count = 0的两行中,将0替换为1,因为您确定列表中的每个数字都必须至少计算一次。

    这样,您可以避免检查内部循环中i等于j的情况:在计数中已经考虑了它。因此,在内循环的开头添加if (i == j) continue;

  • 使用先前的更新,您现在可以确定在内部循环中递增计数时,j不等于i。因此,您可以在数组中更改a[j]的值而无需更改a[i]

  • 因此,在增加计数后立即添加a[j] = -1;。这样,当我递增以检查新值的新计数时,就不可能已经对新的计数值进行了计数。

  • 最后,您不想计算数组中-1的次数。但是您已将某些值替换为-1。因此,只需在外部循环的开头添加if (a[i] == -1) continue;即可避免计算数组中-1的数量。

此中间代码是:

void display_repeats(int *a,int n) {
int *repeats;
repeats = malloc(n * sizeof repeats[0]);
int i=0;
int j=0;
int count = 1;

for(i=0; i<n; i++) {
  if (a[i] == -1) continue;
  for(j=0; j<n; j++) {
    if (i == j) continue;
    if(a[i] == a[j]) {
      count++;
      a[j] = -1;
    }
  }
  if(count > 1) {
    repeats[i] = count;
    printf("%d occurs %d times\n",a[i],repeats[i]);
  }
  count = 1;
 }
free(repeats);
}

现在,我们可以优化此代码。

首先,我们可以避免在j <= i时测试a[i] == a[j]:如果发生这种情况,我们知道我们之前已经显示了a [j]的计数(a [j]出现的次数在数组中)。因此,我们可以将for (j=0; j < n; j++) {替换为for (j=i+1; j<n; j++) {

通过最后一次更新,我们知道内循环的第一行将永远不会匹配:我不能等于j。因此,我们可以删除此行(if (i == j) continue;)。

请注意,重复数组中存储的值仅用于获取printf()调用中的count值。因此,我们可以删除对重复数组的所有引用,而只需在printf()调用中使用count。

现在,您可以看到我们将count设置为1,两次。如果不在主循环结束时将其设置为1,则只能执行一次,以准备一个新循环,但要在开始时进行。

现在,请注意i,j和count具有相同的类型,因此只能使用一行来定义它们:int i = 0, j = 0, count = 1;。而且,i和j稍后在for循环中定义,因此无需在此处定义其初始值。因此,我们可以简单地编写int i, j, count = 1;。但是现在在外部循环的开始处定义了计数,因此我们无需事先定义它。因此,我们只需要定义i,j并计数而无需初始值:int i, j, count;

新的中间代码是:

void display_repeats(int *a, int n) {
  int i, j, count;

  for (i = 0; i < n; i++) {
    if (a[i] == -1) continue;
    count = 1;
    for(j = i + 1; j < n; j++) {
      if (a[i] == a[j]) {
        count++;
        a[j] = -1;
      }
    }
    if (count > 1) printf("%d occurs %d times\n", a[i], count);
  }
}

使用C99语法

但是,使用C99规范,我们可以做更多的事情:我们可以使用for指令定义一个变量:我们可以编写for (int i = ...)。不再需要以前定义它。因此我们可以避免写int i, j, count;,我们将在初次使用时对其进行定义:

void display_repeats(int *a, int n) {
  for (int i = 0; i < n; i++) {
    if (a[i] == -1) continue;
    int count = 1;
    for(int j = i + 1; j < n; j++) {
      if (a[i] == a[j]) {
        count++;
        a[j] = -1;
      }
    }
    if (count > 1) printf("%d occurs %d times\n", a[i], count);
  }
}

使用逗号C运算符

再次,我们可以做得更好!我们可以使用逗号运算符(,):它是一个二进制运算符,用于评估其第一个操作数,丢弃结果,评估第二个操作数并返回其值。使用逗号运算符,我们可以将count++; a[j] = -1;转换为一条指令:a[j] = (count++, -1)。但是我们可以避免用括号写count++, a[i] = -1。现在,由于只有一条指令,因此对于if语句不需要块。因此,我们可以删除很多括号。

最终代码是:

void display_repeats(int *a, int n) {
  for (int i = 0; i < n; i++) {
    if (a[i] == -1) continue;
    int count = 1;
    for (int j = i + 1; j < n; j++)
      if (a[i] == a[j]) count++, a[j] = -1;
    if (count > 1) printf("%d occurs %d times\n", a[i], count);
  }
}

答案 4 :(得分:0)

谢谢大家,我将其与以上想法结合使用! 这就是我得到的..

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

int main(void) {
 int array_size = 0;
 int *my_array;
 int i = 0;

 printf("Enter the size of the array:\n");
 scanf("%d",&array_size);

 my_array = malloc(array_size * sizeof my_array[0]);
 if(NULL == my_array) {
    fprintf(stderr,"MEMORY ALLOLCATION FAILED \n");
    return EXIT_FAILURE;
    }

    for(i=0;i<array_size;i++){
    my_array[i] = rand()%array_size;
      }
   printf("What's in the array:\n");
   for(i = 0;i<array_size;i++){
    printf("%d ",my_array[i]);
    }
   printf("\n");

  display_repeats(my_array, array_size);
  free(my_array);
  return EXIT_SUCCESS;
 }

 void display_repeats(int *a,int n){
   int *freq;


   freq = malloc(n * sizeof freq[0]);
   int i=0;
   int j=0;
   int count = 0;

   for(i=0;i<n;i++){
   freq[i] = -1;
    }

   for(i=0;i<n;i++){
   count = 1;
    for(j=i+1;j<n;j++){
      if(a[i]==a[j]){
        count++;
        freq[j] = 0;
       }
     }
 if(freq[i]!=0){
    freq[i] = count;
  }
}
for(i=0;i<n;i++){
  if(freq[i]!=1 && freq[i]!=0){
    printf("%d occurs %d times\n",a[i],freq[i]);
  }
 }
free(freq);
}