一、实验内容、实验任务和目的

制作一个菜单程序,运用函数的调用,实现下面功能:

  1. 输出所有水仙花数
  2. 输出斐波那契数列
  3. 输出n内素数
  4. 输出n内完数

二、实验步骤、过程、程序的数据结构和主要算法说明或流程

由于程序逻辑比较简单,可以直接按照程序的运行顺序开始写代码。

首先需要写的是登录页面,由于需要在3次错误后退出程序,故采用ACM常用的倒序循环计次方法while(n--)进行循环判断。

进入系统后可能需要多次接受输入并输出结果,所以利用了while(flag)进行功能模块的多次输入输出,flag表示系统的使用权限。

由于输入的命令格式可能奇奇怪怪,为了保证严谨性可以用string接收输入,为了保证兼容性可以用int接收输入,这里我使用了int

由于退出系统之后需要返回登录界面,所以我将登录的循环与主体的循环放在同级并在外围加上一重while使其尽可能简单地回到登录界面。

由于菜单文字和欢迎文字比较长且多次引用,故定义为常量方便调用。

由于程序要求运用函数调用,故将功能部分模块化成函数进行调用。

三、程序的整体结构

由于flowchart无法正常显示,直接使用flow生成的图片

flowchart

//flowchart代码,由于博客无法正常显示,故贴成代码方便后续修改
st=>start: main
out1=>operation: 输出欢迎界面
in1=>inputoutput: 输入密码
if1=>condition: =="123456"
if2=>condition: =="0"
if3=>condition: 次数超限
out2=>operation: 输出菜单界面
in2=>inputoutput: 输入命令
if4=>condition: <0 || >4|
if5=>condition: ==1
if6=>condition: ==2
if7=>condition: ==3
if8=>condition: ==4
if9=>condition: ==0
sub1=>subroutine: 输出所有水仙花数
sub2=>subroutine: 输出斐波那契数列
sub3=>subroutine: 输出n内素数
sub4=>subroutine: 输出n内完数
ed=>end: Return 0

st->out1->in1->if1
if1(yes)->out2->in2->if4
if1(no)->if2
if2(yes)->ed
if2(no)->if3
if3(yes)->ed
if3(no)->in1
if4(yes)->in2
if4(no)->if5
if5(yes)->sub1(right)->out2
if5(no)->if6
if6(yes)->sub2(right)->out2
if6(no)->if7
if7(yes)->sub3(right)->out2
if7(no)->if8
if8(yes)->sub4(right)->out2
if8(no)->if9
if9(yes)->out1

四、程序的完整代码

#include<iostream>
#include<cmath>
using namespace std;
const string welcome = "\n\
          ----------------------------\n\
          |                          |\n\
          |   欢迎进入数列例题系统   |\n\
          |                          |\n\
          ----------------------------\n\n";
const string menu = "\n\
          ****************************\n\
          |                          |\n\
          |   本系统提供以下功能:   |\n\
          |   1.输出所有水仙花数     |\n\
          |   2.输出斐波那契数列     |\n\
          |   3.输出n内素数          |\n\
          |   4.输出n内完数          |\n\
          |   0.返回主界面           |\n\
          |                          |\n\
          ****************************\n\n";
void narcissisticNumber(){
    for(int i = 1; i <= 9; i++){
        for(int j = 0; j <= 9; j++){
            for(int k = 0; k <= 9; k++){
                if(i * i * i + j * j * j + k * k * k == i * 100 + j * 10 + k)
                    cout << i * 100 + j * 10 + k << "\t";
            }
        }
    }
    cout << endl;
}
void fibonacci(){
    long long a = 1, b = 0, c;
    for(int i = 1; i <= 92; i++){
        c = a + b;
        cout << c << "\t";
        a = b;
        b = c;
    }
    cout << endl;
}
void primeNumber(long long range){
    for(long long i = 2; i <= range; i++){
        bool flag = true;
        for(long long j = 2; j <= sqrt(i); j++){
            if(i % j == 0){
                flag = false;
                break;
            }
        }
        if(flag)
            cout << i << "\t";
    }
    cout << endl;
}
void perfectNumber(long long range){
    for(long long i = 2; i <= range; i++){
        long long sum = 1;
        for(long long j = 2; j <= sqrt(i); j++){
            if(i % j == 0){
                sum += j;
                if(j != i / j)
                    sum += i / j;
            }
        }
        if(sum == i)
            cout << i << "\t";
    }
    cout << endl;
}
int main(){
    bool flag = false;
    while(!flag){
        cout << welcome;
        cout << "退出系统请按0,进入系统请输入密码(3次机会):";
        int times = 3;
        while(times--){
            string password = "";
            cin >> password;
            if(password == "123456"){
                flag = true;
                system("cls");
                break;
            }
            else if(password == "0"){
                cout << "感谢使用!\n";
                system("pause");
                return 0;
            }else if(times == 0){
                cout << "密码错误三次退出系统。\n";
                system("pause");
                return 0;
            }else
                cout << "输入错误,请重新输入:";
        }
        while(flag){
            cout << welcome;
            cout << menu;
            cout << "请输入功能序号(0-4):";
            int cmd = -1;
            cin >> cmd;
            while(cmd < 0 || cmd > 4){
                cout << "功能序号无效,请重新输入:";
                cin >> cmd;
            }
            if(cmd == 1){
                narcissisticNumber();
                system("pause");
                system("cls");
            }else if(cmd == 2){
                fibonacci();
                system("pause");
                system("cls");
            }else if(cmd == 3){
                cout << "请输入n:";
                int n = 0;
                cin >> n;
                primeNumber(n);
                system("pause");
                system("cls");
            }else if(cmd == 4){
                cout << "请输入n:";
                int n = 0;
                cin >> n;
                perfectNumber(n);
                system("pause");
                system("cls");
            }else if(cmd == 0){
                system("cls");
                flag = false;
            }
        }
    }
    return 0;
}

五、测试结果

所有功能皆可正常实现,未发现明显bug。

密码错误界面
菜单页面
输出n内素数
输出n内完数
退出界面

六、分析与讨论

本次课程设计的主要难点可能在如何让菜单能无限次响应,而不是输出了结果就结束。本次课程设计感觉上是主要考察逻辑严谨性,所以我列出了流程图,方便寻找逻辑漏洞。