在数组和循环方面需要帮助

Posted

技术标签:

【中文标题】在数组和循环方面需要帮助【英文标题】:Need help with arrays and loops 【发布时间】:2011-07-18 03:44:58 【问题描述】:

使用单下标数组解决以下问题: 读入 20 个数字,每个数字都在 10 到 100 之间,包括 10 到 100。在读取每个数字时,仅当它不与已读取的数字重复时才打印它。提供所有 20 个数字都不同的“最坏情况”。使用尽可能小的数组来解决这个问题。

这是我目前所拥有的:

#include <stdio.h>
#define SIZE 20

int duplicate (int num[] );
int main ()

    int i, numbers[ SIZE ];
    printf( " Enter 20 numbers between 10 and 100:\n " );
    scanf_s( "%d\n" );

    for (int i = 0; i < SIZE  - 1; i++ ); 
    


int duplicate( int num[] )

    int i, hold;

    for ( i = 0; i <= SIZE - 1; i++ )
        if ( num[i] == num[i=1] )
            hold = num[i];
            else
                hold = num[i+1];
        

    printf( "%3d\n," num[ i ] );

【问题讨论】:

欢迎堆栈溢出。到目前为止,你有什么问题?它是否运行,但产生不正确的结果?它会因一些错误而中止吗?是不是编译失败了? @Angela 发布的代码存在一些明显的问题:(1)第一个 for 循环没有做任何事情,因为它在开头 之前有一个分号 - 即有循环中没有代码; (2) 中间的if ( num[i] == num[i=1] ) 语句有[i=1] 但应该有[i+1](除非你想要无限循环); (3)if后面的三行括在if 括号内包括对应的else声明(我假设赢了'不编译); (4) 您正在为 hold 分配一个值,但从不使用该值。 我尝试重新格式化代码以使其更易读,尽管它涉及一些猜测工作,因为有一些不匹配的大括号,并且似乎有两个不完整的函数定义 (@987654332 @ 和 duplicate)。 【参考方案1】:

不幸的是,您的教授可能不够聪明,无法解决他自己的问题。此问题的最小可能数组大小为 2(假设 64 位数据类型,这是标准提供的最大数据类型。对于 32 位整数,它需要三个元素,而对于 128 位整数,只需 1 个)。

#include <stdint.h>
#include <stdio.h>
int main(void)

    int_fast64_t visited[2] =  0 ;
    int inputs_left = 20;
    do 
        int input, slot;
        int_fast64_t mask;
        puts("Enter an integer between 10 and 100: ");
        if (!scanf("%d", &input)) 
            puts("That's not a number!\n");
            continue;
        
        if (input < 10 || input > 100) 
            puts("Out of range!\n");
            continue;
        
        slot = (input - 10) >> 6;
        mask = 1 << ((input - 10) & 0x3F);
        if (visited[slot] & mask) 
             puts("Already seen, it is a duplicate.\n");
        
        else 
            visited[slot] |= mask;
            printf("%d is new\n", input);
        
        inputs_left--;
     while (inputs_left);
    return 0;

如果您能够正确解释其工作原理,欢迎您在作业中使用此代码(希望您的教授教您如何编写 cmets)。

【讨论】:

^ +1。数组大小将取决于您采用的类型。如果您使用long longdouble,您还可以管理2 大小的数组。 我不够聪明,无法理解您的解决方案,至少在将 20 个(或前 19 个)数字存储在数组大小为 3 时。您假设信息未在问题,即输入的数字必须是整数。如果您要“聪明”并使用按位运算在数组的每个插槽中存储多个数字,我建议所需的最小可能数组大小是一个元素数组(其中一个元素是,例如,每个数字都有一个字段的对象)。 +1 位旋转的好例子。 @nnnnnn:似乎这个问题是在考虑整数的情况下形成的。我同意它没有明确给出,但似乎这就是所提供的代码所要给出的。 干得好,但你应该修改代码以支持 10 到 19 之间的数字,否则不能满足教授的要求。 @NRS:在您发表评论的同时,我编辑了使用更大整数的可能性。另外,double 上不能使用按位运算。【参考方案2】:

这是我想出来的,谢谢大家的帮助:

  #include <stdio.h>
  #define MAX 20

  int main()
  
int a[ MAX ] =  0 ;  /* user input */
int i;                 /* counter */
int j;                 /* counter */
int k = 0;             /* number of integers entered */
int duplicate;         /* notify of duplicates */   
int value;              

printf( "Enter 20 numbers between  10 - 100;\n" );

      /* ask user for 20 numbers */
      for ( i = 0; i <= MAX - 1; i++ )

    duplicate = 0;
    scanf( "%d", &value);

     /* decide if integer is duplicate */
    for ( j = 0; j < k; j++ ) 

     /* notify and stop loop if duplicate */
        if ( value == a[ j ] ) 
        duplicate = 1;
        break;
         /* end if */



     /* enter number into array if it's not a duplicate */
        if ( !duplicate )
        a[ k++ ] = value;

 /* end if */

【讨论】:

【参考方案3】:

您的代码存在一些问题:

duplicate 函数在 main 函数中。 i 被多次声明 第一个 for 循环后不应有分号。 hold 变量没有被用于任何事情。它只是被分配了一个值。 num[i=1] - 不确定您要在这里做什么,但 i=1 将 i 设置为 1。 在您的第一个 for 循环中,您的条件是 i

您的 if 语句应该为每个 if/else 使用大括号 (),或者根本不使用。

if (test) 
    // code

else 
    // code

if (test)
    // code
else
    // code

至于逻辑:

你只得到一个整数,你没有把它放在数字数组中。每次用户输入数字时,您都需要一个一个地获取 20 个整数并检查数组。 duplicate 函数可能应该采用第二个参数,即您要检查的数字。 if 语句将检查 num[i] 是否等于您要查找的数字。 记得初始化数组值并且只检查你设置的值。例如,当用户输入第三个数字时,您只需检查数组中的前 2 个数字,看看它是否已经存在。

PS:请尝试正确缩进您的代码。如果缩进不正确,很多人甚至不会尝试提供帮助。

【讨论】:

【参考方案4】:

我的 C 很生锈,所以这里有一个伪代码解决方案(因为这个作业你应该自己做一些):

print initial prompt;

declare nums[ array size 20 ]; // I later assume a 0-based index
declare boolean found;

for (i=0; i < 20; i++) 
  // prompt for next number if desired
  read next number into nums[i];
  found = false;
  // compare against all previously read numbers
  for (j=0; j < i; j++) 
    if (nums[j] == nums[i]) 
      found = true;
      break;
    
  
  if (!found) 
    print nums[i];
  

注意:上述问题并不是说数字必须是整数。此外,它说“使用最小可能的数组” - 如果您为当前数字引入非数组变量,您可以使用 19 元素数组来执行此操作(因为第 20 个读取的数字只需要与前 19 个进行检查,而不是对自己不利),但这会使代码更加复杂。

另请参阅我在上面发布的评论,其中提到了您的代码存在的一些特定问题。并检查所有括号是否匹配。

【讨论】:

以上是关于在数组和循环方面需要帮助的主要内容,如果未能解决你的问题,请参考以下文章

如何帮助编译器消除循环和数组?

需要帮助在 perl 中对数组进行排序

需要帮助打印出2d数组中的字符串[重复]

在 XSLT 1.0 和分组方面需要帮助

暑假学习第二周

帮助将 SQL 语句转换为 LINQ Lambda(在 group by 和 sum 方面需要帮助)