【问题标题】:ADD elements of an array with a given condition添加具有给定条件的数组元素
【发布时间】:2019-11-27 10:01:33
【问题描述】:

有n个学生的数组(stu[n])。如果性别是男孩,那么我的代码会添加

  • 对于男孩b, 2nd,4th,6th,........数组的偶数位置元素和
  • 对于女孩g, 1st,3rd,5th....数组的奇数位置元素。

1> 男孩的性别用 b 表示。 2> 用g表示女孩的性别。

输入信息>>

  1. 第一行包含 n,表示班级中的学生人数,即数组中元素的数量。
  2. 随后的每一行都包含 n 个学生的分数。
  3. 最后一行包含性别 b/g;

输出信息>>

输出应包含上述标记的所有替代元素的总和。

#include <stdio.h>

int main() {
int n,i;
scanf("%d",&n);//n denotes number of students.
int stu[n],sum=0;


for(i=1;i<=n;++i)
scanf("%d",&stu[i]);//for accepting input in array.

char gen;
scanf("%s",&gen);//for accepting input gender b/g.


 for(i=1;i<=n;i++){
 if(gen=='g' && i%2!=0){ //girl g adds alternate odd position  elements.
sum=sum+stu[i];
printf("%d",sum);
}

else if(gen=='b' && i%2==0){ //boy b adds alternate even position elements.

sum=sum+stu[i];
printf("%d",sum);
}

}
//code
return 0;
}

示例输入

3 3 2 5 b

样本输出 8

解释>> 标记 = [3,2,5] 和性别 = b 所以它将添加 3+5(甚至位置 0,2 替代元素)。如果性别代替 b 是 g 那么它将产生输出 = 2。

我的代码在所有测试用例中显示输出为 0。

【问题讨论】:

  • 你说文件有多行,但你给的样本都在一行。输入中的每个数据点是用换行符还是空格分隔?细节很重要,准确无误也很重要。
  • 由新行分隔
  • 数据用新行分隔。
  • 我应该将 \n 添加到所有 scanf 并检查吗??
  • 如果你用scanf,其实没关系。但是IMO你不应该使用scanf。我在下面给出的解决方案适用于每种情况。

标签: c for-loop scanf variable-length-array


【解决方案1】:

嗯……我稍微修改了你的代码,希望它按照描述运行。

int main() {

       int n, index, sum=0;
       int* stu;
       scanf("%d", &n); // input number of studens

       if(n>0)
          stu = malloc(n*sizeof(int)); // allocate memory
       else
          return 0;

       for(index=0;index<n;index++)
          scanf("%d", &stu[index]);

       char gen;
       scanf("%c", &gen);

       for(index=0; index<n; index++){
          if(gen=='g' && index%2!=0) {
             sum += stu[index];
             printf("%d", sum);
          } else if(gen=='b' && index%2==0) {
             sum += stu[index];
             printf("%d", sum);
          }
       }

       return 0;
    }

【讨论】:

    【解决方案2】:

    您可能不应该使用数组,而只是忽略第一个数据点。使用链表(可能)更容易。或者也许只使用两个列表,在它们之间交替输入。而且我绝对不会使用scanf。如果您是 C 新手,请不要浪费时间学习 scanf 格式字符串语言的弱点。 唯一 scanf 有用的时间是在入门课程中,讲师错误地认为您将能够比花时间学习其他方法更快地获得输入。但事实上,你最终会花费更多时间来学习何时在格式字符串中使用空格,而你没有学习fread。在您介绍了 C 之后,您将(几乎)永远不会使用 scanf。此外,将判别式放在输入末尾似乎是一个可怕的设计。要求和的值(性别)应作为命令行参数给出。也就是说,你可以这样做:

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    FILE *
    xfopen(const char *path, const char *mode)
    {
            FILE *rv;
            if( (rv = fopen(path, mode)) == NULL ) {
                    perror(path);
                    exit(EXIT_FAILURE);
            }
            return rv;
    }
    
    int
    main(int argc, char **argv)
    {
            int i;
            int size;  /* Should probably be size_t.  Skipping that for now. */
            FILE *in = argc > 1 ? xfopen(argv[1], "r") : stdin;
            int sum = 0;
            if( fscanf(in, "%d", &size) != 1 || size <= 0 ) {
                    fprintf( stderr, "invalid input\n" );
                    exit(EXIT_FAILURE);
            }
            int grades[size];
            for( i = 0; i < size; i++ ) {
                    if(fscanf(in, "%d", grades + i) != 1) {
                            fprintf( stderr, "invalid input on line %d\n", i );
                            exit(EXIT_FAILURE);
                    }
            }
            char gender;
            if(fscanf(in, " %c", &gender) != 1) {
                    fprintf( stderr, "invalid input on line %d\n", i );
                    exit(EXIT_FAILURE);
            }
            if(strchr("bBgG", gender) == NULL) {
                    fprintf( stderr, "invalid gender: %c\n", gender);
                    exit(EXIT_FAILURE);
            }
            for( i = tolower(gender) == 'b'; i < size; i += 2 ) {
                    sum += grades[i];
            }
            printf("sum: %d\n", sum);
    }
    

    【讨论】:

    • 感谢这个新方法,但我是 c 语言的初学者。自从我开始使用书籍和 youtube 学习编码以来只有 20 天。我还没有接触过 --c 中的文件管理章节我想你已经用过了。
    • 这里的文件管理非常少。如果您想删除它,只需写FILE *in = stdin,或者在我使用in 的地方直接使用stdin
    • 你能提供一些技巧来学习指针,maalloc,calloc 动态内存,结构联合,我觉得很难吗??有时我会感到困惑和沮丧的天气我应该先看书还是看视频然后解决问题在 hakerank 上。你的快速学习和升级策略是什么。
    • 我认为没有“快速学习”。对我来说,这个过程漫长而艰巨,有很多分段错误。当奇怪的事情发生时,跳进 gdb 并追踪它。不过,大多数情况下,它都是在尝试。您可以通过忽略第一个输入并将数据放入链表或在更多数据到达时根据需要重新分配数组来从这个问题中了解更多信息。
    • 可能是因为你在数组边界之外写。
    【解决方案3】:

    你让事情变得比他们需要的更复杂。您可以这样做:

    #include <stdio.h>
    
    int main(void)
    {
        int mark;
        int b = 0;
        int g = 0;
        char students_marks[5];
    
        for (int i=0; i<5; i++) {
            scanf("%d", &mark);
            students_marks[i] = mark;
        }
        for (int i=0; i<5; i++) {
            if (i%2 == 0) b += students_marks[i];
            if (i%2 == 1) g += students_marks[i];
        }
        printf("Boys: %d\nGirls: %d\n", b, g);
        return 0;
    }
    

    【讨论】:

    • 我们不能添加输入 {4,5,6,7,8} 因为问题说我们必须接受用户使用 scanf 的输入,并且数组大小可以是随机的 n;所以你能建议还有一些改进。我是一个初学者,并试图从几个小时内得到它。
    • 循环遍历 scanf 并将扫描的值添加到您的数组中,您就完成了。
    • 好的,我遍历了 scanf 但仍然 b 和 g 是 char 值,为什么你在 int 中使用它??
    • 请注意,您不需要这些char,因为条件是均匀或不均匀;你选一个,另一个没用。同样在for 循环中嵌套的if-else 条件中,您执行的操作完全相同。
    • 我必须在 haker rank 编译器中写 b 或 g 性别作为输入字符,然后只有 if else 语句会相应地运行为偶数或奇数?你能再读一遍这个问题,请再次帮助我吗?这里是正确解释的链接hackerrank-challenge-pdfs.s3.amazonaws.com/…
    【解决方案4】:

    你的主要问题是

    int n,i;
    int stu[n],sum=0;
    

    这里,n 是一个未初始化的具有自动存储的局部作用域变量,初始值是不确定的。

    现在,由于变量的地址从未被占用,并且它具有可以具有陷阱表示的类型,因此尝试使用该值 (int stu[n]) 将调用未定义的行为。

    您需要先将值扫描到n,然后使用它来定义VLA stu。类似的东西

    int n,i;
    scanf("%d",&n);//n denotes number of students.
     // **Note: please check for errors in input with scanf return value.**
    int stu[n],sum=0;   // here, n has the scanned value.
    

    也就是说,

    char gen;
    scanf("%s",&gen);
    

    也是大错特错,你想扫描char,而不是字符串,并且使用普通char变量的地址,%s转换规范将是UB,再次。您应该使用 %c 并完全丢弃缓冲区中存在的所有空格。

    【讨论】:

    • 即使在编辑后也没有显示输出。请再次帮助。
    • @AYUSHAZAD 您能否在阅读答案后展示您尝试了什么以及它是如何失败的?
    • 我把 scanf 放在了正确的位置,还把 !== 改成了 != 我后来看到了,但编译器仍然没有输出。括号的位置可能是错误的,但我不这么认为。我在代码厨师和极客编译器上运行它。我是一个初学者,我不怎么处理指针,因为我觉得缺乏实践并且太早应用>>比如 int *marks ,所以我使用了 vla 和 for 循环。
    • @AYUSHAZAD 这与指针无关,无论您使用什么,请确保您正确使用它们。
    • 仍然没有显示任何输出(%s 已更改为 %c)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2020-07-11
    相关资源
    最近更新 更多