wujr5 / c-and-cpp-language-learning

C和C++编程语言学习 - 2015级
67 stars 34 forks source link

软件:week6 实验:程序流程图和伪代码 #11

Open ghostbody opened 8 years ago

ghostbody commented 8 years ago

实验二:程序流程图和伪代码

实验目的:当大家学习了程序的控制结构之后,代码就变得复杂起来。在这时,我们解决问题就需要有很严密的逻辑思维。程序流程图和伪代码就是帮助我们去描述我们解决问题的方法(也称为算法)的工具。本次实验在于让大家学习如何使用这些工具,这对大家以后的编程有很大的帮助。

1.Flowchart(程序流程图)

A flowchart is a type of diagram that represents an algorithm, workflow or process, showing the steps as boxes of various kinds, and their order by connecting them with arrows. This diagrammatic representation illustrates a solution model to a given problem. Flowcharts are used in analyzing, designing, documenting or managing a process or program in various fields.

From wikipedia

Detailed Description: flowchat

There is an example:

ab

And this is the flowchart: sample

2.Pseudocode (伪代码)

Pseudocode is an informal high-level description of the operating principle of a computer program or other algorithm.

From wikipedia

There is an example: 1

We can describe this question by this way rather than write a C program immediately:

main {
input two integers height and n
initialize answer = 0
loop for n times {
    input tree_height
    if height >= tree_height:
       answer = answer + 1
  }
print answer
}

Pseudocode is used to express your thought, you do not need to care about the grammar.

Pre Assignment

Learn about Flowchart and Pseudocode.

Assignment 0 (20pts)

Choose one question from soj.me in week6 in our course and then write the Pseudocode.

Assignment 1 (35pts)

option 1

Translate the following flowchart into Pseudocode

option 2

Translate the following flowchart into Pseudocode and C programming language program.

Description

Several surveys indicate that the taller you are, the higher you can climb the corporate ladder. At TALL Enterprises Inc. this "de facto standard" has been properly formalized: your boss is always at least as tall as you are. Furthermore, you can safely assume that your boss earns a bit more than you do. In fact, you can be absolutely sure that your immediate boss is the person who earns the least among all the employees that earn more than you and are at least as tall as you are. Furthermore, if you are the immediate boss of someone, that person is your subordinate, and all his subordinates are your subordinates as well. If you are nobody's boss, then you have no subordinates. As simple as these rules are, many people working for TALL are unsure of to whom they should be turning in their weekly progress report and how many subordinates they have. Write a program that will help in determining for any employee who the immediate boss of that employee is and how many subordinates they have. Quality Assurance at TALL have devised a series of tests to ensure that your program is correct. These test are described below.

May be you can not write out the problem, the only work you will do is write out this program from the following flowchart(Since there are many methods to sort, so you can use one of them, the flowchart does not display in the flow chat, instead a dashed line).

Flowchart

flowchart 2

Simple input and output

Input

2 3 123456 14323 1700000 123458 41412 1900000 123457 15221 1800000 123458 4 200002 12234 1832001 200003 15002 1745201 200004 18745 1883410 200001 24834 1921313 200002

Output

(0,2) (200004,0)

Assignment 2 (35pts)

Draw a flowchart from the following C language program which instruct the movement of a robot going on patrol along the wall.

#include <stdio.h>

/* this program is used for a robot to walk along
   a wall next to him.
*/

/* Note that if the robot's eyes get something 
   whose distance is less than 40cm, there must
   be an obstacle(wall).
*/
const int SENSOR_DISTANCE = 40; // 40 cm

/*
  predifined methods:
  1. void lookLeft() and void lookRight()
  function: Let the robot to look at the left or right side.
  2. void lookForward()
  function: let the robot to look forward.
  3. int getDistance()
  function: get a distance from the eye to another.
  object if there is one.
  4. void moveStraight()
  function: go straight for some distance.
  5.int shutDown()
  function: shut down the robot.
*/

int main() {
  /* we assume that for the initial state, either 
     the robot's left side or the right side is 
     toward the wall.

     wall = 0 means that the wall is at the left side
     wall = 1 means that the wall is at the right side
  */
  int wall;

  lookLeft();
  if(getDistance() < SENSOR_DISTANCE) {
    wall = 0;
  } else {
    lookRight();
    wall = 1;
  }

  if(wall == 0) {
    while(shutDown() != 1) {
      moveStraight();
      while(1) {
        lookLeft();
        if(getDistance() < SENSOR_DISTANCE) {
          lookForward();
          if(getDistance() < SENSOR_DISTANCE) {
            turnRight();
          } else {
        break;
      }
        } else {
      turnLeft();
        }
      }
    }
  } else {
    do {
      moveStraight();
      while(1) {
        lookRight();
        if(getDistance() < SENSOR_DISTANCE) {
          lookForward();
          if(getDistance() < SENSOR_DISTANCE) {
            turnLeft();
          } else {
        break;
      }
        } else {
      turnRight();
        }
      }
    } while (shutDown() != 1);
  }

  return 0;
}

Extended Assignment (10pts)

option 1

Draw a flowchart and write Pseudocode as well as a C language program for the following description. extend

option 2

Simplify the logic in Assignment 2 and then draw a new flowchart and rewrite the C code.(Reduce at least one level of logic nesting)

Discussion,Cooperation and Summary (15pts)

In this part, you will have some options, if you do more options, you will learn more and get more marks. You should note this part in your report

option 1: Github Discussion

Comment at this issue and decribe a problem that you meet and how you solve detailedly.

Notice that

  1. you should not copy and paste your personal report simply.
  2. you should not write a very simple one and your comment will be deleted if you do that.
  3. you should not post meaningless questions.

    option 2: Simple Presentation

Have a simple presentation in the lab class on Monday (4 persons limited). And after the presentation, everyone is encouraged to ask questions and you can get bonus by asking good questions.

Notice that

  1. The presentation is no more than 5 minutes and there will be 5 extra minutes for discussion.
  2. You should prepare much for it.
  3. First come, first get the opportunity.

    option 3: Helping others

You can help others to slove any problems the will meet. Detailedly decribe the quesion, the solution and your personal experience as well.

Notice that

  1. it's no need to consult with others that I help you, you help you to get marks. You can simply send email to me and I will give you the marks.

    option 4: Personal Summary

    Write personal summary for yourself. List at least 10 problems that you have met in your learning in c language and decribe the solution as well.

Notice that

  1. you should not have ten very simple problems, you must let me know your learning method and also the method to solve problems.

    Report(50% pts for your project ducumenting):

There will be no Report Template this time which means it's all depends on yourself.

Notice that

  1. the report is the most important document for your project, you should pay more attention to it.
  2. you are supposed to write a report that is friendly to your 'users', which means that you need to consider about the typesetting, the logical structure of the content.
  3. There should contain one item, self grading that you should give a score to evaluate your job as well as a reason.

For example: sinew

Flowchart Tool: Process On

Process on is a good tool for drawing flowchart. link

Submit List

2

Notice that: 13331314 means your student id. the first assignment need to name your file with your chosen problem id.

Deadline and how to submit:

18:00 on Nov 7th, 2015

学习委员整理好发到邮箱:423093883@qq.com 不接受作业单独发到邮箱

Notification:

  1. Submit after deadline will cause a 30% penalty.
  2. If your file structure of filename is wrong, you will probably get 0 in that part.
  3. Any questions, you can ask us and email is better.
  4. Full mark will be 100, but you may get more than 100 within this project.
  5. You can use any tool include word, process on to draw a flowchart. You can use any form to write your Pseudocode but should be of high readability. If TA can not understand your Pseudocode clearly, you will get low points.(you can use Chinese to write Pseudocode if you like).
CN96 commented 8 years ago
#include<stdio.h>
#include<string.h>
int main() {
    char c[20], name[20], j, k;
    int N, a, b, l, i, sum, max, all;
    scanf("%d", &N);
    all = 0;
    for(i = 1; i <= N; i++) {
        scanf("%s%d%d%c%c%d", &c, &a, &b, &j, &k, &l);
        sum = 0;
        if((a > 80) && (l >= 1)) {
            sum = sum+8000;
        }
        if((a > 85) && (b > 80)) {
            sum = sum+4000;
        }
        if(a > 90) {
            sum = sum+2000;
        }
        if((a > 85) && (k == 'Y')) {
            sum = sum+1000;
        }
        if((b > 80) && (j == 'Y')) {
            sum = sum+850;
        }
        all = sum+all;
        if(max < sum) {
            max = sum;
            strcpy(name, c);
        }
    }
    printf("%s\n%d\n%d\n", name, max, all);
    return 0; 
}

奖学金那道题求助,输出的计算结果总是错的,那个8000和850总加不上去

8652 commented 8 years ago

http://www.cppblog.com/sleepwom/archive/2010/12/31/137810.html见“缓冲区问题”……我当时也是跪在这里【泪

------------------ 原始邮件 ------------------ 发件人: "yyh15331026";notifications@github.com; 发送时间: 2015年11月2日(星期一) 晚上11:52 收件人: "wujr5/c-and-cpp-language-learning"c-and-cpp-language-learning@noreply.github.com;

主题: Re: [c-and-cpp-language-learning] 软件:week6 实验题 (#11)

include

include

int main() { char c[20], name[20], j, k; int N, a, b, l, i, sum, max, all; scanf("%d", &N); all = 0; for(i = 1; i <= N; i++) { scanf("%s%d%d%c%c%d", &c, &a, &b, &j, &k, &l); sum = 0; if((a > 80) && (l >= 1)) { sum = sum+8000; } if((a > 85) && (b > 80)) { sum = sum+4000; } if(a > 90) { sum = sum+2000; } if((a > 85) && (k == 'Y')) { sum = sum+1000; } if((b > 80) && (j == 'Y')) { sum = sum+850; } all = sum+all; if(max < sum) { max = sum; strcpy(name, c); } } printf("%s\n%d\n%d\n", name, max, all); return 0; }奖学金那道求助,算出的结果总是错的

— Reply to this email directly or view it on GitHub.

ghostbody commented 8 years ago

@yyh15331026 因为%c会吸收输入的空格和回车符号,这是一个很著名的问题。解决办法有很多种,其中有一种是使用%1s,其他方法可以自行搜索。

CN96 commented 8 years ago

谢谢你们,最后我在%c前面加个空格就可以了,这样可以使其略去前面输入的空白字符。可以看一下scanf函数的百度百科

DengXj95 commented 8 years ago

我之前也一直是这样的。建议别用字符j,k了。也许“ %c”(加空格的%c)在Sicily读取的时候还是有问题。你换成字符数组用%s读入试试,用strcmp比较j,k,与“Y”就好了。

CN96 commented 8 years ago
#include<stdio.h>
#include<string.h>
int main() {
    char c[20], name[20], j, k;
    int N, a, b, l, i, sum, max, all;
    scanf("%d", &N);
    all = 0;
    for(i = 1; i <= N; i++) {
        scanf("%s%d%d %c %c%d", &c, &a, &b, &j, &k, &l);
        sum = 0;
        if((a > 80) && (l >= 1)) {
            sum = sum+8000;
        }
        if((a > 85) && (b > 80)) {
            sum = sum+4000;
        }
        if(a > 90) {
            sum = sum+2000;
        }
        if((a > 85) && (k == 'Y')) {
            sum = sum+1000;
        }
        if((b > 80) && (j == 'Y')) {
            sum = sum+850;
        }
        all = sum+all;
        if(max < sum) {
            max = sum;
            strncpy(name, c, 20);
        }
    }
    printf("%s\n%d\n%d\n", name, max, all);
    return 0;
}

这样还是WRONG ANSWER,然而在电脑上是对的,然后我发现把字符串的20改成22就过了

DengXj95 commented 8 years ago

恭喜了。我好像是定义成23的。 = =

CN96 commented 8 years ago

嗯好像是因为字符串最后有一个结束符,但是我21还是过不了,要22才能过,好像跟strncpy有关。 最后发现这样能过。c[21],strncpy()里也是21,然后name[22]弄成22就好了。

#include<stdio.h>
#include<string.h>
int main() {
    char c[21], name[22], j, k;
    int N, a, b, l, i, sum, max, all;
    scanf("%d", &N);
    all = 0;
    for(i = 1; i <= N; i++) {
        scanf("%s%d%d %c %c%d", &c, &a, &b, &j, &k, &l);
        sum = 0;
        if((a > 80) && (l >= 1)) {
            sum = sum+8000;
        }
        if((a > 85) && (b > 80)) {
            sum = sum+4000;
        }
        if(a > 90) {
            sum = sum+2000;
        }
        if((a > 85) && (k == 'Y')) {
            sum = sum+1000;
        }
        if((b > 80) && (j == 'Y')) {
            sum = sum+850;
        }
        all = sum+all;
        if(max < sum) {
            max = sum;
            strncpy(name, c, 21);
        }
    }
    printf("%s\n%d\n%d\n", name, max, all);
    return 0;
}
ghostbody commented 8 years ago

1、注意一个问题,输入字符数组(字符串的时候),后面的参数&c的取地址符号是没有的,请仔细看书,这个和指针相关知识有关,如果加上取地址符号,就会有不可控制的效果。 2、请阅读一下mark怎么展示c代码的,直接贴上来看挺不舒服的。 mark down

ReganFan commented 8 years ago

看了你们的讨论,真是获益匪浅,我的问题也解决了。

HillCJL commented 8 years ago

@ghostbody 学长,假设声明数组a[n],a和&a同样表示指向第一项地址的指针,他这么写没有问题。这个“不可控制的效果”是什么鬼。。。

ghostbody commented 8 years ago

@LinTheLegend a和&a同样表示指向第一项地址的指针,这两个地址值确实是一样的。 1

scanf接收一长串字符后,都按这个地址一一往后填字符,a[1000]对应的字符就是相同的。

但是a和&a的区别在于地址偏移上&a+1是数组首地址+sizeof(a),也就是指向a数组a[1000]的后面了,而a+1指a[0]+1也就是a[1]代表的地址。 2

HillCJL commented 8 years ago

我之前都没这么用过,学到了。谢谢学长!还有学长你用的编程程序是什么?

ghostbody commented 8 years ago

@LinTheLegend sublime text 3

JerryChan31 commented 8 years ago

实验题里机器人那一题,有一行我看不懂 while(shutDown() != 1) { 而前面又有 5.void shutDown() function: shut down the robot. shutDown不是返回空值吗。。。为什么会有shutDown()!=1。。。

ghostbody commented 8 years ago

@JerryChan31 函数原型写错了,返回的是int类型。

JerryChan31 commented 8 years ago

@ghostbody 那有什么返回值。。。代表什么意思。。。

ghostbody commented 8 years ago

@JerryChan31 首先,这个题目是让你搞懂整个while,if这些分支的嵌套关系,你纠结他的返回值没有意义,不利于梳理整个流程的逻辑。其次,shutdown在注释中有说明指的是机器人关机,而且后面的逻辑判断也给出了shotdown!=1的判断,这样的判断可以去猜测就是一个逻辑判断。如果学习留心的话会发现,scanf的返回值也是int类型。具体可以等学完自定义函数后再理解。

JerryChan31 commented 8 years ago

@ghostbody 。。。好吧我理解错了。。。我以为shutdown是像一个状态一样的东西【比如0就是开机1就是关机这样。。。好了现在没事了。。。谢谢学长>///<

HillCJL commented 8 years ago

@ghostbody 学长,公司那道题floatchar给出的算法有误, image 不止加1,应该还加上下属的下属人数才对。

ghostbody commented 8 years ago

@LinTheLegend 什么问题。

HillCJL commented 8 years ago

@ghostbody 更改已发

HillCJL commented 8 years ago

按照流程图写完程序后跑了一遍发现下属人少了,才发现流程图算法有误。 还有学长关于 image 这一步骤,具体的实现方法和变量命名可以自己定么(显然员工的数据不可能只用一个变量储存,我是用了结构体存的)

ghostbody commented 8 years ago

@LinTheLegend 可以

MarshallW906 commented 8 years ago

实现方式是一定要按照流程图来吗,我想到了自己的做法 @ghostbody

ghostbody commented 8 years ago

@MarshallW906 可以用自己方法,请把你自己方法的流程图画出来

yyh14313081 commented 8 years ago

image 求助 为什么没有输出啊

HillCJL commented 8 years ago

@yyh14313081 这....你的c是什么,我都不知道你怎么能输出....请在每次用完c之后将c初始化为0好不好

ghostbody commented 8 years ago

@yyh14313081 变量名乱用,实在不想猜你的程序的意思。没有输出就说明x永远不等于c,你自己好好整理下逻辑。代码风格请注意。

EdwardChan1996 commented 8 years ago

image 求助,本周西西里的prime number,为什么这样是WA image 这样就AC了? 随机抽了几个数,第一个程序的输出都是正确的。而输入“1”的时候第二个程序反而会显示“No\nYes",然而它却AC了?

LGA1150 commented 8 years ago

本地正常,提交上去后Runtime Error是怎么回事?原来的" %c"换成了"%1s"了,难道Sicily不能这样定义字符串数组?

#include<stdio.h>

int main() {

    int n, i, scp, total, sc[200], qm[200], py[200], art[200];
    char name[30][200];
    char mo[200], we[200];
    //Init:
    total = 0;
    scp = 0;
    //Read n:
    scanf("%d", &n);

    for (i = 0; i < n; i++) {
        //Read data:
        scanf("%s%d%d%1s%1s%d", &name[i], &qm[i], &py[i], &mo[i], &we[i], &art[i]);
        //Init:
        sc[i] = 0;
        //Calculate:
        if ((qm[i] > 80) && art[i]) sc[i] += 8000;
        if ((qm[i] > 85) && (py[i] > 80)) sc[i] += 4000;
        if (qm[i] > 90) sc[i] += 2000;
        if ((qm[i] > 85) && (we[i] == 'Y')) sc[i] += 1000;
        if ((py[i] > 80) && (mo[i] == 'Y')) sc[i] += 850;
        //Sum:
        total += sc[i];
    }
    //Find max:
    for (i = 0; i < n; i++) {
        if (sc[scp] < sc[i]) scp = i;
    }
    //Output:
    printf("%s\n%d\n%d\n", name[scp], sc[scp], total);

    return 0;
}
ghostbody commented 8 years ago

15331027Chan 第一个程序没考虑2的情况。第二个程序逻辑混乱,请自行改过来。

ghostbody commented 8 years ago

@LGA1150 这是典型没听课,说了这个题目不需要用这么多数组。其中,name数组的第一维和第二维搞错了。而且问题描述不清,代码风格有待加强,变量意义不明。

edwincai commented 8 years ago

本周sicily上面关于判断是否质数的一个题,我的想法是,输入一个数之后,从2开始逐个递加,做取模运算。如果出现余数为0的情况,则跳出循环,输出No。如果是质数,跳出循环以后,做一个简单的判断,输出Yes..然而实际运行的时候,发现yes不能输出,结果只是空格。求指教 qq 20151105003045

zhongjh97 commented 8 years ago

楼上的小伙伴。。假如p是质数,跳出for循环时i=p,这个时候p%i=0啊。。。

edwincai commented 8 years ago

@15336256 后面把令 t = i - 1,然后p%t !=0 ;还是没有输出诶。。怎么办

15331014 commented 8 years ago

是不是字符串一定要加[]这个啊 为什么我输出printf("%s", ch);如果定义的时候不加[]就会提示非法啊..是不是数组要自学才能做题啊!....

czjcssy commented 8 years ago

大神求救!T T default

这是assignment 2的那道流程图转代码的 我的代码中的一部分。 这一部分我是想让正在处理的职员序号为m 然后升序向后测试,然后他的潜在上司就是n,让n=m+1,一个个往后推就可以了。然后把他后面所有的人都测一遍就不会把下属的下属漏掉。 然而我发现了个问题 就是如果我这样一直往后退,那么他的BOSS就会变成不是直属上司而是后面的工资更高的,这样输出的结果就不对了。 所以我把程序改成了这样 default

让n = e_num;n <= m + 1;n-- 就是潜在上司倒着来,让最后一个先测,这样每一个都会测到并且不会漏掉任何一个下属,并使得最后的BOSS是他的直属上司。 然而这个程序在我输入完所有信息,按了回车准备把我想搜索的id输进去的时候,程序就崩了...崩了...崩....了。。。。如下图.... error

然后我再把它改回原来那样...程序又好了...又好了...又好了... 但是输出的答案是错的你们懂的← ←....为什么...因为这样编译不行吗?!已经坏到它要崩掉了吗ORZ T T求救求救。

HillCJL commented 8 years ago

@15331048 估计是溢出了。检查下下标有没爆。

czjcssy commented 8 years ago

ORZ...下标爆了的意思是我设的组不够大还是...?? 我测试的时候输入的e_num是3啊。。。 就算从最后一个开始 不也应该是从a[3]开始倒着来吗... 是说我设的组过小 过大 还是说e_num...?? 顺便说一下 我设的结构体的个数是10000个...

HillCJL commented 8 years ago

假如是你输入之后崩了,麻烦看下有没加取地址符

HillCJL commented 8 years ago

正常崩溃通常是内存冲突,可能是溢出,数组下标爆,以及没加取地址符

czjcssy commented 8 years ago

@LinTheLegend 我看了一下我每个scanf都有加取地址符.. 是在每次输入完所有员工的信息之后 按回车就崩了 还来不及scanf我要搜索的id... 而且我输入所有员工信息的时候是一行回车 有一句话输出 再一行的输入的 所以这个scanf循环应该是没有问题的... 在两次scanf中间的代码就是我截图的那部分 正序比较跟倒序比较求出上司跟下属的代码部分.. 正序的时候程序是正常运行的 能输出最后结果 改成从输入的数据中的最后一个开始比较 就崩了...

ghostbody commented 8 years ago

@15331048 能不能给个不是图片的代码。请学习使用markdown添加代码。

runtime error 运行是错误,一般就是非法内存访问。

czjcssy commented 8 years ago

@ghostbody

#include<stdio.h>

struct employee {
    long id, salary, height, boss, subordinate;
};
int main() {
    struct employee a[10000], temp, current_deal, potential_boss, search;
    int total_test, current_test, current_e, e_num, id_search;
    int i, k, j, m, n, t, u;
    for (u = 1;u <= 10000;u++) {
        a[u].subordinate = 0;
        a[u].boss = 0;
        a[u].height = 0;
        a[u].id = 0;
        a[u].salary = 0;
    }
    printf("How many test do you want to have?\n");
    scanf("%d", &total_test);
    current_test = 1;
    while (current_test <= total_test) {
        printf("please input the number of employees\n");
        scanf("%d", &e_num);
        current_e = 1;
        for (i = 1;current_e <= e_num;i++) {
            printf("please input No.%d empolyees' id, salary, height(seperated by space)\n", i);
            scanf("%d %d %d", &a[i].id, &a[i].salary, &a[i].height);
            current_e ++;
        }  for (k = 1;k <= (e_num - 1);k++) {
            for(j = 1;j <= (e_num - 1);j++) {
                if(a[j].salary > a[j+1].salary) {
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp; 
                }
            }
        }   

             for (m = 1;m <= e_num;m++) {
                     current_deal = a[m];
                for(n = e_num;n <= (m + 1);n--) {
                            potential_boss = a[n];
                    if(current_deal.height <= potential_boss.height) {
                        a[m].boss = potential_boss.id;
                        a[n+1].subordinate += 1;
                     }
                 }  
             }
             printf("please input the id you want to search for its boss and subordinates\n");
             scanf("%d", &id_search);
             for (t = 1;t <= e_num;t++) {
                if (id_search == a[t].id) {
                    search = a[t];
                 }
             }
             printf("(%d,%d)\n", search.boss, search.subordinate);
             current_test ++;

    }    
        return 0;
}
ghostbody commented 8 years ago

@15331048 1

41行出现非法下标,导致非法内存访问,自己看看吧

czjcssy commented 8 years ago

@ghostbody 谢谢学长ORZ...我盯着看了很久很久 搜了很久...才发现了一个很低级的错误... 我把从升序比较 改成 降序比较之后 没有把循环的条件反过来...一直n--一直减下去就变成了负数ORZ...肯定非法访问了。。谢谢学长!不好意思= =|||

HillCJL commented 8 years ago

@15331048 还说下标没爆。。。。

PULSARE commented 8 years ago

我终于ac了奖学金那题。。。。== 首先是数组输入的问题,看上面的讨论把"%c"改成了" %c",解决 == 。。我问了同学用%*c%c代替%c好像也能解决。 最后发现一直WA的原因是,在初始化sum的时候没有放进for循环里。(好无语) 还有我有问题为什么我的vs2013一碰到%s就会崩 == 求解答,谢谢!~

ghostbody commented 8 years ago

@PULSARE 请带上具体程序,%s具体是怎样的,请描述清楚问题。