【Coursera公开课】计算机程序设计 编程作业

Homework 1_表面積與體積

寫一個程式讀入五個整數 a, b, c, d 及 e,計算中物體的體積及表面積。你可以想像該物體是一個長寬高為 a, b, c 的長方體,每一面中央都是凹進去的,而凹進去的深度為 d,沒凹進去的邊框寬度為 e。

【Coursera公开课】计算机程序设计 编程作业_第1张图片

輸入範例

6
8
10
1
2

輸出範例

請務必依照範例格式填寫,兩個數字之間空半格,否則系統無法準確判定答案是否正確。

472 392
 
  
代码略,直接公式计算即可!

Homework 2_卡車位置

有一輛卡車行駛在沙漠中,我們想知道它最後的位置。卡車最初 (時間為 0) 是在位置 (0, 0) 以每小時 10 公里的速度向北移動。卡車會收到一系列依照時間戳記排序的命令,1 表示「向左轉」,2 表示「向右轉」,3 表示「停止」。每個命令的前面有一個時間戳記,所以我們知道該命令是何時發出的。最後一個命令一定是「停止」。我們另外還假設,這輛卡車非常靈活,所以它可以在瞬間轉彎。

以下列輸入為例。卡車在時間為 5 的時候收到一個「向左轉」的命令 1,在時間 10 收到一個「向右轉」的命令 2,在時間 15 收到一個「停止」的命令 3。那麼最後在時間 15 的時候,卡車的位置將在 (-50, 100)。程式只需要輸出卡車的最後位置。第一個數字是 x 坐標,第二個數字是 y 坐標。

輸入範例

5
1 
10 
2 
15 
3

輸出範例

請務必依照範例格式填寫,兩個數字之間空半格,否則系統無法準確判定答案是否正確。

-50 100
#include 
int main()
{
    int timebefore = 0, timenow = 0, choice;
    int x = 0, y = 0;
    int direction_x = 0, direction_y = 1;
    
    do 
    {
        //记录上一次转弯的时间
        timebefore = timenow;
        scanf("%d\n%d", &timenow, &choice);
        
        //向前开车 
        if (direction_x == 0 && direction_y == 1)
        {
            y += 10 * (timenow - timebefore);
            switch (choice)
            {
                case 1:
                    direction_x = -1;
                    direction_y = 0;
                    break;
                case 2:
                    direction_x = 1;
                    direction_y = 0;
                    break;
                default:
                    break;
            }
        }
        //向后开车 
        else if (direction_x == 0 && direction_y == -1)
        {
            y -= 10 * (timenow - timebefore);
            switch (choice)
            {
                case 1:
                    direction_x = 1;
                    direction_y = 0;
                    break;
                case 2:
                    direction_x = -1;
                    direction_y = 0;
                    break;
                default:
                    break;
            }
        }
        //向左开车 
        else if (direction_x == -1 && direction_y == 0)
        {
            x -= 10 * (timenow - timebefore);
            switch (choice)
            {
                case 1:
                    direction_x = 0;
                    direction_y = -1;
                    break;
                case 2:
                    direction_x = 0;
                    direction_y = 1;
                    break;
                default:
                    break;
            }
        }
        //向右开车 
        else if (direction_x == 1 && direction_y == 0)
        {
            x += 10 * (timenow - timebefore);
            switch (choice)
            {
                case 1:
                    direction_x = 0;
                    direction_y = 1;
                    break;
                case 2:
                    direction_x = 0;
                    direction_y = -1;
                    break;
                default:
                    break;
            }
        }
    } while (choice != 3);   
 
    printf("%d %d", x, y); 
    
    system("pause");
    return 0;
}

Homework 3_鏡子房間

寫一個程式模擬鏡子反射。給定一個房間,其寬度為 w,長度為 d。你可以想像房間是由 w * d 個格子所組成。房間裡有許多鏡子,而一個鏡子就放在一個房間格子中,以 45 度角或是 -45 度角放置。鏡子是雙面,兩面都可以反射光線。房間的周圍有 2(w + d) 個窗口。窗口的編號由 0 到 2(w + d) - 1。每一個窗口都可以向房間內部檢視。如果我們站在窗口 0 檢視,我們將會看到窗口 8。請參考下圖。

【Coursera公开课】计算机程序设计 编程作业_第2张图片

參數規範

  • 0 < w <= 20
  • 0 < d <= 20

輸入格式

輸入第一行是房間的寬度 w 與長度 d。以下 d 行每一行有 w 個 0 ,1,或 2,分別代表該位置沒有鏡子,有一面 45 度角鏡子,或是有一面 -45 度角鏡子。

輸入範例

5 4
0 1 0 0 0
0 2 0 2 0
1 0 0 1 1
0 1 1 0 0

輸出格式

輸出共有 2(w + d) 個數字,每個數字是站在該窗口向房間內檢視時所會看到的窗口編號。

輸出範例

請務必依照範例格式填寫,兩個數字之間空半格,否則系統無法準確判定答案是否正確。

8 11 5 9 6 2 4 10 0 3 7 1 14 16 12 17 13 15
 
  
#include 

int main()
{
    int w, d, i, j, k, num, i_direction, j_direction;
    scanf("%d %d", &w, &d);
    int a[d][w];
    for(i = 0; i < d; i++)
        for(j = 0; j < w; j++)
            scanf("%d", &a[i][j]);
    
    //遍历每一个编号,由于两两相对应,其实只需计算一半的就可以了,
    //用数组存储每一个编号,值为另一个编号,先都初始化为-1,
    //每计算一个,就可以到另一个编号下把这个编号作为值存储,
    //当到达那个编号时,判断值不为-1,就说明已经找到该对了,不必去计算了,
    //这里偷个小懒,就没有实现该步,思路在这里说明一下,因为还是很容易实现的。 
    for(k = 0; k < 2 * (w + d); k++)
    {
        //计算编号对应的i、j
        if(k / (w + d) == 0)
        {
            //最下方,向上走 
            if(k / w == 0)
            {
                i = d - 1;
                j = k; 
                i_direction = -1;
                j_direction = 0;
            }
            
            //最右方,向左走 
            else
            {
                i = w + d - 1 - k;
                j = w - 1; 
                i_direction = 0;
                j_direction = -1;
            }
        }
        else
        {
            //最上方,向下走 
            if((k - w - d)/ w == 0)
            {
                i = 0;
                j = 2 * w + d - 1 - k; 
                i_direction = 1;
                j_direction = 0;
            }
            
            //最左方,向右走 
            else
            {
                i = k - 2 * w - d;
                j = 0; 
                i_direction = 0;
                j_direction = 1;
            }
        }
        
        //找到另一边时跳出循环 
        while(1)
        { 
            //出口在上边 
            if(i < 0)
            {
                //计算对应的编号
                num = 2 * w + d - j - 1;
                break; 
            }
            
            //出口在下边 
            else if(i > d - 1)
            {
                 //计算对应的编号
                 num = j;
                 break;
            }
            
            //出口在左边 
            else if(j < 0)
            {
                 //计算对应的编号
                 num = 2 * w + d + i;
                 break;
            }
            
            //出口在右边 
            else if(j > w - 1)
            {
                 //计算对应的编号
                 num = w + d - i - 1;
                 break;
            }
            
            //还在内部 
            else
            {
                //45度角镜子,向上变向右,向右变向上,向下变向左,向左变向下 
                if(a[i][j] == 1)
                {
                    if(i_direction == -1 && j_direction == 0)
                    {
                        i_direction = 0;
                        j_direction = 1;
                    }
                    else if(i_direction == 0 && j_direction == 1)
                    {
                        i_direction = -1;
                        j_direction = 0;
                    }
                    else if(i_direction == 1 && j_direction == 0)
                    {
                        i_direction = 0;
                        j_direction = -1;
                    }
                    else if(i_direction == 0 && j_direction == -1)
                    {
                        i_direction = 1;
                        j_direction = 0;
                    }
                }
                
                //-45度角镜子,向上变向左,向左变向上,向下变向右,向右变向下 
                else if(a[i][j] == 2)
                {
                    if(i_direction == -1 && j_direction == 0)
                    {
                        i_direction = 0;
                        j_direction = -1;
                    }
                    else if(i_direction == 0 && j_direction == -1)
                    {
                        i_direction = -1;
                        j_direction = 0;
                    }
                    else if(i_direction == 1 && j_direction == 0)
                    {
                        i_direction = 0;
                        j_direction = 1;
                    }
                    else if(i_direction == 0 && j_direction == 1)
                    {
                        i_direction = 1;
                        j_direction = 0;
                    }
                } 
                //else if(a[i][j] == 0),方向不变,无需处理
                
                //走到下一步 
                i += i_direction;
                j += j_direction;
            }
        }
        printf("%d ", num);
    }
    
    system("pause");
    return 0;
}

Homework 4_統一發票兌獎

寫一個程式計算統一發票獎金。統一發票收執聯是 8 位數。每一期會有三個特獎號碼及三個頭獎號碼。獎金的算法如下。

  • 收執聯 8 位數號碼與特獎號碼相同者為特獎 200 萬元。
  • 收執聯 8 位數號碼與頭獎號碼相同者為頭獎 20 萬元。
  • 收執聯末 7 位數號碼與頭獎中獎號碼末 7 位相同者為二獎 4 萬元。
  • 收執聯末 6 位數號碼與頭獎中獎號碼末 6 位相同者為三獎 1 萬元。
  • 收執聯末 5 位數號碼與頭獎中獎號碼末 5 位相同者為四獎 4 千元。
  • 收執聯末 4 位數號碼與頭獎中獎號碼末 4 位相同者為五獎 1 千元。
  • 收執聯末 3 位數號碼與頭獎中獎號碼末 3 位相同者為六獎 2 百元。

範例介面

請練習使用下列函式介面計算獎金。

int prize(int specialPrizeNumbers[3], int firstPrizeNumbers[3], int myNumber);

相對應的主程式範例如下。

int main()
{
  int i;
  int specialPrizeNumbers[3];
  int firstPrizeNumbers[3];
  int myNumber;
  int totalPrize = 0;

  for (i = 0; i < 3; i++)
    scanf("%d", &(specialPrizeNumbers[i]));
  for (i = 0; i < 3; i++)
    scanf("%d", &(firstPrizeNumbers[i]));

  while (scanf("%d", &myNumber) != EOF)
    totalPrize += prize(specialPrizeNumbers, firstPrizeNumbers, myNumber);

  printf("%d\n", totalPrize);
  return 0;
}  

輸入格式

輸入前三行為特獎號碼,後三行為頭獎號碼,之後每一行為我們收集的發票收執聯號碼。程式必須處理所有的輸入直到 EOF (end of file)。

輸入範例

55138690
14764045
41175733
68787608
77978391
11071074
12378391
68787608

輸出格式

輸出為所得獎金總額。

輸出範例

204000

 
  
#include 

int prize(int specialPrizeNumbers[3], int firstPrizeNumbers[3], int myNumber)
{
    int i;
    for (i = 0; i < 3; i++)
        if (myNumber == specialPrizeNumbers[i])
            return 2000000;
    for (i = 0; i < 3; i++)
        if (myNumber == firstPrizeNumbers[i])
            return 200000;
    for (i = 0; i < 3; i++)
        if (myNumber % 10000000 == firstPrizeNumbers[i] % 10000000)
            return 40000;
    for (i = 0; i < 3; i++)
        if (myNumber % 1000000 == firstPrizeNumbers[i] % 1000000)
            return 10000;
    for (i = 0; i < 3; i++)
        if (myNumber % 100000 == firstPrizeNumbers[i] % 100000)
            return 4000;
    for (i = 0; i < 3; i++)
        if (myNumber % 10000 == firstPrizeNumbers[i] % 10000)
            return 1000;
    for (i = 0; i < 3; i++)
        if (myNumber % 1000 == firstPrizeNumbers[i] % 1000)
            return 200;
    return 0;
}

int main()
{
    int i;
    int specialPrizeNumbers[3];
    int firstPrizeNumbers[3];
    int myNumber;
    int totalPrize = 0;
    
    for (i = 0; i < 3; i++)
        scanf("%d", &(specialPrizeNumbers[i]));
    for (i = 0; i < 3; i++)
        scanf("%d", &(firstPrizeNumbers[i]));
    
    //按ctrl+c(退出)或ctrl+z(停止)会返回EOF
    while (scanf("%d", &myNumber) != EOF)
        totalPrize += prize(specialPrizeNumbers, firstPrizeNumbers, myNumber);
        
    printf("%d\n", totalPrize);
    system("pause");
    return 0;
}

Homework 5_矩陣求解

寫一個程式解線性系統 Ax = y。其中 A 是 n 乘 n 方陣,x 及 y 都是 n 乘 1 的向量。給定 A 及 y 時求解 x。為求簡單起見,給定的 A 一定是上三角矩陣。

void upper_solver(double *A, double *x, double *y, int n);
  • 函式 upper_solver 的第一個參數式指向 A 的指標。注意,為了節省記憶體我們只存 A 的上三角部分,而且存成一維陣列,請參考下方的主程式。
  • upper_solver 的第二個參數是指向 x 的指標。upper_solver 必須將 x 的解放在這裡。
  • upper_solver 的第三個參數是指向 y 的指標。
  • upper_solver 的第四個參數是矩陣大小 n。

我們提供了主程式,請你實作函式 upper_solver。

#include 
#define N 256

void upper_solver(double *A, double *x, double *y, int n);
int main(void)
{
    int i, j;
    int n; 
    double A[N * (N + 1) / 2];
    double *aptr = A;
    double x[N];
    double y[N];
    scanf("%d", &n);
    for ( i = 0 ; i < n ; i++ )
        for ( j = i ; j < n ; j++ ) {
            scanf("%lf", aptr);
            aptr++;
        }
    for ( i = 0 ; i < n ; i++ )
        scanf("%lf", &(y[i]));
    upper_solver(A, x, y, n);

    for ( i = 0 ; i < n ; i++ )
        printf("%lf ", x[i]);

    return 0;
}

參數規範

0 < n <= 256

輸入範例

3
1.000 2.000 3.000
      2.000 1.000
            4.000
2.000
3.000
-4.000

輸出範例

1.000000 2.000000 -1.000000
#include 
#define N 256

// A * x = y,x的解即A-1 * y,使用初等行变换法:( A | y ) -> ( E | A-1 * y )
void upper_solver(double *A, double *x, double *y, int n)
{   
    // 上三角矩阵每行第一个不为0的数值都变为1.000,即二维数组的[0][0],[1][1]...[n - 1][n - 1],对应到A的[0],[n],[n + n-1],[2*n-1 + n-2],[3*n-3 + n-3]...[]
    // 即每一行上的数据都除以该行第一个不为0的数,注意,y中数据对应行的值也要相应的被除。
    int i, j, control, first, second, k, find;
    double multiple;
    
    for (i = 0, control = n, first = 0; i < n; i++)
    {
        // 记录倍数 
        multiple = A[first]; 
        for (j = 0; j < control; j++)
        {
            A[first + j] /= multiple;
        }
        y[i] /= multiple;
        // 定位到每行第一个不为零的位置 
        first += control;
        control--;
    }
    // 打印数组A出来观察 
    k = 0;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < i; j++)
            printf("\t");
        for (j = 0; j < n - i; j++)
            printf("%8.3lf", A[k++]);
        printf("\n");
    }
    
    // 循环,从下往上,让每一行的第二、三...到最后一个数字通过减去下一行、下两行...下最后一行的某一个倍数来变为0
    // 从n-2行,即倒数第二行开始往上到0行,分别有一列、两列...n-1列需要去减下面的行的倍数来变为0 
    
    // 起始为n - 2行(倒数第二行)第二个不为零的位置
    second = (n + 3) * (n - 2) / 2 + 1;
    control = 3;
    for (i = n - 2; i >= 0; i--)
    {
        // i行共n-i列非零,有后n-i-1列(第二个值不为零的列开始到最后一列)需要减为0
        for (j = 0; j < n - i - 1; j++)
        {
            // 对于i行后n-i-1列(0,1...n-i-2)中的某列,例如k列,关键在于找到以它为0行往下数到的k+1行该列的值,减去倍数变成0即可
            // 由于是从下往上的,所以下面的行都已经处理好了,每行都只有一列有非零值了,做减法的时候,其他列减去的都会是零,不会出问题
            // 当前需要减为零的位置:second + j,值A[second + j],在i行,(0,1...n-i-2)中的j列,
            // 需要到i + j+1行,(0,1...n- (i + j+1) -2)中的0列(即第一个非零值,也是唯一的非零值)找到要减去的值,再算出来倍数,把A[second + j]减为零即可,
            // 注意,y中数据对应行的值也要相应的被减,即y[i] -= y[i + j+1] * 倍数。
            
            // 先到本行末尾,即i行,(0,1...n-i-2)中的n-i-2列对应的位置 
            find = second + n - i - 2;
            // 经过中间行,到达目标行前一行末尾
            for (k = 0; k < j; k++)
            {
                find += n - (i + 1 + k);
            }
            // 到达目标行对应列位置,即该行第一个也是唯一一个非零值所在列(下面的行都处理好了,所以只有对角线上的这一列有非零值) 
            find += 1;
            // 算出倍数 
            multiple = A[second + j] / A[find];
            // 修改A中的值和y中的值
            // 等价于"A[second + j] -= A[find] * multiple;"但直接赋值为0更省时间,也更准确(浮点数除法得到multiple除不尽等问题很可能导致结果不准确)
            A[second + j] = 0;
            y[i] -= y[i + j + 1] * multiple;
        }
        // 定位到每行第二个不为零的位置
        second -= control;
        control++; 
    }
    
    // 最后A变成了E,y变成了A-1 * y
    // 打印数组A出来观察,并把现在数组y中的值,即结果A-1 * y存到x中 
    k = 0;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < i; j++)
            printf("\t");
        for (j = 0; j < n - i; j++)
            printf("%8.3lf", A[k++]);
        printf("\n");
        x[i] = y[i];
    }
}

int main(void)
{
    int i, j;
    int n; 
    double A[N * (N + 1) / 2];
    double *aptr = A;
    double x[N];
    double y[N];
    scanf("%d", &n);
    for ( i = 0 ; i < n ; i++ )
        for ( j = i ; j < n ; j++ ) {
            scanf("%lf", aptr);
            aptr++;
        }
    for ( i = 0 ; i < n ; i++ )
        scanf("%lf", &(y[i]));
    upper_solver(A, x, y, n);

    for ( i = 0 ; i < n ; i++ )
        printf("%lf ", x[i]);

    system("pause");
    return 0;
}

另一种更简单的解题方法:

【Coursera公开课】计算机程序设计 编程作业_第3张图片

【Coursera公开课】计算机程序设计 编程作业_第4张图片

Homework 6_Basic Interpreter

試寫一個簡易 BASIC 編譯器。一個簡易 BASIC 程式碼 [註]包含兩個部分 -- 變數宣告以及執行語句。變數宣告一定會出現在程式碼的第一行 (line 0);當中包含:所有的變數、變數的初始值(所有變數都會有初始值),最後以 "END" 表示宣告結束。下列為一個變數宣告的範例,宣告了八個變數,以及變數各自的初始值:

N = 2 F = 2 ONE = 1 TWO = 2 R = 0 S = 0 ZERO = 0 HUNDRED = 100 END

[註] BASIC: Beginner's All-purpose Symbolic Instruction Code 初學者的全方位符式指令代碼,可參考維基百科 BASIC


除了 line 0 以外,其餘的簡易 BASIC 程式碼都是執行語句,從 line 1 開始,一行 (line) 為一個執行語句。共有五種合法的執行語句:

  • GOTO 會讓執行序跳至某行,並從該行開始執行。
    GOTO 格式為 "GOTO num",num 為一數字。
    下列範例將會使執行序跳至 line 1
    GOTO 1
  • IF 中的判斷句為真時,會讓執行序跳至某行;若判斷句為假,則執行下一行。
    IF 格式為 "var1 op var2",var1 及 var2 為變數;op 是判斷元,合法的判斷元包括 "=="、"!="、">"、"<"、">=" 及 "<="。
    下列範例中,若 N 大於 HUNDRED,執行序將會跳至 line 11。
    IF N > HUNDRED GOTO 11
  • = 會把值指定給變數。
    = 格式為 "var = var1 op var2",var、var1 及 var2 為變數;op 是運算元,合法的運算元包括 "+"、"-"、"*"、"/" 及 "%"。
    下列範例中,= 將 N 與 ONE 的和指定給變數 N、將 B 與 C 的積指定給變數 A。
    N = N + ONE
    A = B * C
    
  • PRINT 會印出變數的值。
    PRINT格式為 "PRINT var",var 為一變數。
    下列範例將會印出變數 N 的值。
    PRINT N
  • STOP 代表簡易 BASIC 程式碼的結束。

輸入內容

一個簡易 BASIC 程式碼。

輸出內容

執行語句 PRINT 所印出的內容。

參數規範

每行 char 數量 < 150
總行數 < 50

輸入範例

N = 2 F = 2 ONE = 1 TWO = 2 R = 0 S = 0 ZERO = 0 HUNDRED = 100 END
IF N > HUNDRED GOTO 11 
F = TWO + ZERO 
R = N % F 
IF R == ZERO GOTO 9 
F = F + ONE 
S = F * F 
IF S <= N GOTO 3 
PRINT N 
N = N + ONE 
GOTO 1 
STOP

輸出範例

3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
 
  
#include 
#define MAX_VAR_NUM 15
#define MAX_VAR_LENGTH 10
#define MAX_SENTENCE_NUM 50
#define MAX_SENTENCE_LENGTH 150

int main()
{
    // var和value存储所有变量和对应的值 
    char var[MAX_VAR_NUM][MAX_VAR_LENGTH], input[MAX_SENTENCE_LENGTH];
    memset(var, 0, sizeof(var));
    int value[MAX_VAR_NUM], var_num = 0;
    scanf("%s", input);
    // 不为"END",则继续读取 
    while (strcmp(input, "END"))
    {
        // 存储变量值 
        strcpy(var[var_num], input);
        // 跳过等号 
        scanf("%s", input);
        // 读取变量值 
        scanf("%d", &(value[var_num]));
        // 变量个数累加 
        var_num++;
        scanf("%s", input);
    }
    /*
    int i = 0;
    for (i = 0; i < var_num; i++)
        printf("%s = %d ", var[i], value[i]);
    printf("\n");
    */
    
    // sentence存储每行语句,sentence_num存储语句行数(从1开始) 
    char sentence[MAX_SENTENCE_NUM][MAX_SENTENCE_LENGTH];
    memset(sentence, 0, sizeof(sentence));
    // 从行一开始!
    int sentence_num = 1;
    // 把行0,即变量定义那一行的语句最后的'\n'读走跳过 
    fgets(input, MAX_SENTENCE_LENGTH, stdin);
    // 读取一行,到换行或者MAX_SENTENCE_LENGTH截止,这里都是读到换行为止 
    fgets(input, MAX_SENTENCE_LENGTH, stdin);
    // 结尾的'\n'换成'\0' 
    input[strlen(input) - 1] = '\0';
    // 若结尾有多余的空格,注意置为'\0' 
    while (input[strlen(input) - 1] == ' ')
    {
        input[strlen(input) - 1] = '\0';
    }
    // 不为"STOP",则继续读取
    while (strcmp(input, "STOP"))
    {
        // 存储变量值 
        strcpy(sentence[sentence_num], input);
        // 语句行数累加 
        sentence_num++;
        fgets(input, MAX_SENTENCE_LENGTH, stdin);
        // 结尾的'\n'换成'\0'
        input[strlen(input) - 1] = '\0';
        while (input[strlen(input) - 1] == ' ')
        {
            input[strlen(input) - 1] = '\0';
        }
    }
    // 最后一行语句也要加上! 
    strcpy(sentence[sentence_num], "STOP");
    /*
    int i;
    for (i = 1; i <= sentence_num; i++)
        printf("%s\n", sentence[i]);
    */
    
    int line_now = 1; // 存储当前执行到的语句行数,从1开始计数 
    // 只要当前没有执行到"STOP"语句 
    while (line_now != sentence_num)
    {
        // 解析当前语句
        // GOTO 语句 
        if (sentence[line_now][0] == 'G' && sentence[line_now][1] == 'O' && sentence[line_now][2] == 'T' && sentence[line_now][3] == 'O')
        {
            int num = 0, pos = 5;
            while (sentence[line_now][pos] != '\0')
            {
                num = num * 10 + sentence[line_now][pos] - '0';
                pos++;
            }
            line_now = num;
        }
        // IF 语句 
        else if (sentence[line_now][0] == 'I' && sentence[line_now][1] == 'F')
        {
             int pos = 3, i = 0, op, value1 = 0, value2 = 0, condition_flag = 0;
             char var1[MAX_VAR_LENGTH], var2[MAX_VAR_LENGTH];
             memset(var1, 0, sizeof(var1));
             memset(var2, 0, sizeof(var2));
             // 获取第一个变量名 
             while (sentence[line_now][pos] != ' ')
             {
                 var1[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             pos++;
             // 获取判断元 
             if (sentence[line_now][pos] == '=' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
             {
                 op = 0;
                 pos += 2;
             }
             else if (sentence[line_now][pos] == '!' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
             {
                 op = 1;
                 pos += 2;
             }
             else if (sentence[line_now][pos] == '>' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 2;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '<' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 3;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '>' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
             {
                 op = 4;
                 pos += 2;
             }
             else if (sentence[line_now][pos] == '<' && sentence[line_now][pos + 1] == '=' && sentence[line_now][pos + 2] == ' ')
             {
                 op = 5;
                 pos += 2;
             }
             pos++;
             // 获取第二个变量名
             i = 0;
             while (sentence[line_now][pos] != ' ')
             {
                 var2[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             pos++;
             // 根据第一个变量名找到它对应的值大小
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var1) == 0)
                 {
                     value1 = value[i];
                     break;
                 }
             }
             // 根据第二个变量名找到它对应的值大小
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var2) == 0)
                 {
                     value2 = value[i];
                     break;
                 }
             }
             // 根据两个变量的值和判断元来看判断句是对还是错 
             switch (op)
             {
                 case 0:
                     if (value1 == value2)
                         condition_flag = 1;
                     break;
                 case 1:
                     if (value1 != value2)
                         condition_flag = 1;
                     break;
                 case 2:
                     if (value1 > value2)
                         condition_flag = 1;
                     break;
                 case 3:
                     if (value1 < value2)
                         condition_flag = 1;
                     break;
                 case 4:
                     if (value1 >= value2)
                         condition_flag = 1;
                     break;
                 case 5:
                     if (value1 <= value2)
                         condition_flag = 1;
                     break;
                 default:
                     break;
             }
             // 判断句正确,则会执行后面的 GOTO 语句,跳转到指定行 
             if (condition_flag)
             {
                 pos += 5;
                 int num = 0;
                 while (sentence[line_now][pos] != '\0')
                 {
                     num = num * 10 + sentence[line_now][pos] - '0';
                     pos++;
                 }
                 line_now = num;
             }
             // 判断句错误,则执行下一行 
             else
                 line_now++;
        }
        // PRINT 语句 
        else if (sentence[line_now][0] == 'P' && sentence[line_now][1] == 'R' && sentence[line_now][2] == 'I' && sentence[line_now][3] == 'N' && sentence[line_now][4] == 'T' && sentence[line_now][5] == ' ')
        {
             int pos = 6, i = 0, value1 = 0;
             char var1[MAX_VAR_LENGTH];
             memset(var1, 0, sizeof(var1));
             // 获取变量名 
             while (sentence[line_now][pos] != '\0')
             {
                 var1[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             // 根据变量名找到它对应的值大小
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var1) == 0)
                 {
                     value1 = value[i];
                     break;
                 }
             }
             printf("%d ", value1);
             line_now++;
        }
        // = 赋值语句 
        else
        {
            int pos = 0, i = 0, op, index = 0, value2 = 0, value3 = 0;
             char var1[MAX_VAR_LENGTH], var2[MAX_VAR_LENGTH], var3[MAX_VAR_LENGTH];
             memset(var1, 0, sizeof(var1));
             memset(var2, 0, sizeof(var2));
             memset(var3, 0, sizeof(var3)); 
             // 获取第一个变量名 
             while (sentence[line_now][pos] != ' ')
             {
                 var1[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             pos = pos + 3;
             // 获取第二个变量名
             i = 0;
             while (sentence[line_now][pos] != ' ')
             {
                 var2[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             pos++;
             // 获取运算元 
             if (sentence[line_now][pos] == '+' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 0;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '-' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 1;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '*' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 2;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '/' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 3;
                 pos += 1;
             }
             else if (sentence[line_now][pos] == '%' && sentence[line_now][pos + 1] == ' ')
             {
                 op = 4;
                 pos += 1;
             }
             pos++;
             // 获取第三个变量名
             i = 0;
             while (sentence[line_now][pos] != '\0')
             {
                 var3[i] = sentence[line_now][pos];
                 i++;
                 pos++;
             }
             // 根据第二个变量名找到它对应的值大小
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var2) == 0)
                 {
                     value2 = value[i];
                     break;
                 }
             }
             // 根据第三个变量名找到它对应的值大小
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var3) == 0)
                 {
                     value3 = value[i];
                     break;
                 }
             }
             // 根据第一个变量名找到它对应的索引 
             for (i = 0; i < var_num; i++)
             {
                 // 找到相同的变量名,strcmp返回值为0 
                 if (strcmp(var[i], var1) == 0)
                 {
                     index = i;
                     break;
                 }
             }
             // 根据后两个变量的值和运算元来看给第一个变量赋值 
             switch (op)
             {
                 case 0:
                     value[index] = value2 + value3;
                     break;
                 case 1:
                     value[index] = value2 - value3;
                     break;
                 case 2:
                     value[index] = value2 * value3;
                     break;
                 case 3:
                     value[index] = value2 / value3;
                     break;
                 case 4:
                     value[index] = value2 % value3;
                     break;
                 default:
                     break;
             }
             line_now++;
        }
    }
    
    system("pause");
    return 0;
}

你可能感兴趣的:(公开课,ACM,C)