软件工程课堂训练——结对开发之环数组最大和

本文详细介绍了如何在环形数组中找到最大子数组的和及其位置,通过两次遍历实现了问题的解决。对于仅有负数的情况,文章提供了特殊的处理方式。最后,作者分享了实现过程中的心得与体会。

一、题目及要求:

      题目:返回一个整数数组中最大子数组的和

      要求(新加):①如果数组A[0]...A[j-1]首尾相邻,允许A[i-1]...A[n-1],A[0]...A[j-1]之和最大;②同时返回最大子数组的位置。

      结对人员:胡亚宝  焦燕

二、设计思路:

      我们要解决两个问题:求出环数组中最大的子数组;并且定位出该子数组的位置,把它们的名称输出来。要解决这两个问题,我们从以下两个方面入手:

      ①求出最大子数组:将数组数值按顺序排好称为“一趟”,每求出一趟的最大子数组后,将第一个数值放到最后一个,排成新的一趟,以此类推,直到遍历完成,求出最大环子数组。

      ②定位子数组:判断出当前求的和值为负数时,将之舍去,并将该数的下一个数的位置存起来作为最大子数组的头。当求出最大值后,该数的位置存起来作为子数组的尾。最后输出将子数组的名称。

三、源代码:

1 //结对开发——胡亚宝 焦燕 
 2 
 3 #include "stdafx.h"
 4 
 5 
 6 int _tmain(int argc, _TCHAR* argv[])
 7 {
 8     int i,j,k,m,n,o,a[5]; 
 9     int Sum,Max,flag,flag1=0,flag2,flag4;
10     
11     printf("请输入5个整数:\n");
12     for(k=0;k<5;k++)
13     {
14         scanf("%d",&a[k]);
15     }
16     Max = a[0];
17     for (m=0;m<5;m++)
18     {
19         for(i=0;i<5;i++)  
20         {  
21             Sum = 0;             
22             for(j=i;j<5;j++)  
23             {  
24                 Sum =Sum+ a[j];
25                 if(Sum<=0)
26                 {
27                     Sum=0;
28                     flag1=(j+1+m)%5;
29                 }
30                 if(Sum > Max)  
31                 {
32                     Max =Sum;  
33                     flag2=j+m;    
34                 }
35             }  
36         }  
37         flag=a[0];
38         for(n=0;n<5;n++)
39         {
40             a[n]=a[n+1];
41         }
42         a[4]=flag;
43     }
44     if(Sum==0)
45     {
46         
47         Max=a[0];
48         for(int e=0;e<5;e++)
49         {
50             if(a[e]>=Max)
51             {
52                 Max=a[e];
53                 flag4=e;
54             }
55         }
56         
57     }
58     printf("最大连续环子数组的和为:%d\n",Max);
59     printf("该最大连续环子数组为:");
60 
61     if(Sum==0)
62     {
63         printf("a[%d]",flag4);
64     }
65     else
66     {
67         int flag3=flag2-flag1;
68         for(o=0;o<=flag3;o++)
69         {
70             printf("a[%d]\t",flag1);
71             flag1++;
72             if(flag1>4)
73                  flag1=0;
74         }
75     }
76     printf("\n");
77     return 0;
78 }

四、测试及运行结果:

测试数据:

3 6 -9 0 7(有正数、负数、零)

7 9 3 2 8 (只有正数)

-3 -6 -9 -2 -5(只有负数)

运行结果:

五、心得体会:

      这次实验我们听了老师的要求后,两个人都各自想实现的方法,然后各自说出自己的方法给对方听,结果两人说着说着就知道自己的算法错误在哪,缺点在哪。最后我们决定采用张世通同学的方法。

     利用原来的代码使每求出一趟的最大子数组后,利用for循环将第一个数值放到最后一个,排成新的一趟,以此类推,直到遍历完成,求出最大环子数组;但是在定位时,我们遇到了困难,胡亚宝和我在周六试了一下午才实现。当时特别有成就感,虽然方法是胡亚宝想出来的,但当时特别有成就感。

工作照:

转载于:https://www.cnblogs.com/123jy/p/4376681.html

<think>我们正在讨论约瑟夫问题,用户希望看到用数组实现约瑟夫的代码或算法。根据引用内容,我们有多个不同语言的实现示例(包括C、C++和Objective-C),但用户没有指定语言,因此我们可以选择一个通用且易于理解的版本,并给出详细解释。约瑟夫问题描述:n个人围成一圈,从第一个人开始报数,数到m的人出列,然后由下一个人重新报数,直到所有人出列。求最后剩下的人(或出列顺序)。数组实现的基本思路:1.创建一个数组,用于标记每个人是否出列(也可以用两个数组,一个存储编号,一个用于标记状态)。2.使用一个计数器记录当前报数,当报数达到m时,将当前人标记为出列,并重置计数器。3.循遍历数组(模拟形),直到所有人出列。我们将参考引用[2]和[4]中的C语言实现,因为C语言实现较为基础且易于理解。同时,我们也可以参考引用[3]中的C++向量实现,但为了简单,这里使用C语言数组实现。下面是一个使用C语言数组实现的约瑟夫算法代码,并附有详细注释:</think>### 使用数组实现约瑟夫的算法 约瑟夫问题是一个经典数学问题:$n$ 个人围成一圈,从第 $1$ 个人开始报数,每数到 $m$ 的人出列,然后从下一个人重新报数,直到所有人出列。以下是使用数组实现的完整算法和代码: #### 算法核心思路 1. **状态标记数组** 创建数组 `arr` 存储人员编号($1$ 到 $n$),数组 `alive` 标记人员状态($0$=已出列,$1$=在圈中)。 2. **循报数机制** - 初始化计数器 `count = 0`(当前报数值) - 遍历数组模拟形结构:当索引 $i$ 到达末尾时重置为 $0$ - 若当前人在圈中(`alive[i] == 1`),则 `count++` - 当 `count == m` 时: ✓ 标记该人出列(`alive[i] = 0`) ✓ 记录出列顺序 ✓ 重置计数器 `count = 0` 3. **终止条件** 当出列人数等于 $n$ 时结束循。 #### C语言实现代码 ```c #include <stdio.h> #define MAX_SIZE 100 // 最大人数限制 int main() { int n, m; // n=总人数, m=报数上限 printf("输入总人数n和报数上限m: "); scanf("%d%d", &n, &m); int arr[MAX_SIZE]; // 存储人员编号 int alive[MAX_SIZE] = {0}; // 状态标记数组(0:出列, 1:在圈) // 初始化人员编号 for (int i = 0; i < n; i++) { arr[i] = i + 1; alive[i] = 1; // 初始所有人均在圈中 } int outCount = 0; // 已出列人数 int count = 0; // 当前报数值 int index = -1; // 当前遍历索引 printf("出列顺序: "); while (outCount < n) { index = (index + 1) % n; // 形遍历 if (alive[index] == 1) { count++; // 在圈中者报数 // 报数达到m时出列 if (count == m) { printf("%d ", arr[index]); // 输出出列者 alive[index] = 0; // 标记出列 outCount++; // 更新出列人数 count = 0; // 重置计数器 } } } return 0; } ``` #### 关键逻辑说明 - **形遍历**:`index = (index + 1) % n` 实现数组形访问,模拟循队列。 - **时间复杂度**:$O(n \times m)$,最坏情况下需遍历 $n \times m$ 次。 - **空间复杂度**:$O(n)$,仅需两个长度为 $n$ 的数组。 #### 示例运行 ``` 输入总人数n和报数上限m: 5 3 出列顺序: 3 1 5 2 4 ``` #### 算法优化方向 1. **动态跳过无效位置**:当 $m$ 较大时,可计算有效步长跳过已出列者。 2. **数学公式推导**:直接通过递推公式 $f(n,m) = [f(n-1,m) + m] \mod n$ 求解最后幸存者(需递归实现)。 此实现直观展示了数组模拟约瑟夫的核心逻辑,适用于教学和小规模场景[^1][^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值