连续1的个数算法----java版1.0

本文介绍了一个使用Java实现的连通域计数算法,该算法通过递归检查二维数组中的连通区域,并记录每个连通域的大小。通过对预定义的二维数组进行遍历,统计出所有连通域的数量及各自包含的元素数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据C版翻译成java版[@more@]

package cn.withe;

public class Count {
public static int staticpoint=0;
public static int points[]=new int[11];
public final static int MAXCOL=10;
public final static int MAXROW=10;

public static int[][] number={

{1,1,1,1,1,0,0,0,0,0},
{1,1,1,0,0,0,1,1,1,1},
{0,0,1,1,0,0,0,0,0,0},
{1,1,0,1,1,0,1,1,0,1},
{0,1,0,1,0,1,1,0,0,1},
{1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0},
{1,1,0,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,0,1,1}
};

public static void check(int row,int col)
{
if(number[row][col]==0) return;
else
{
points[staticpoint]++;
number[row][col]=0;
if(row>0) check(row-1,col);
if(row if(col>0) check(row,col-1);
if(col }
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

for(int i=0;i for(int j=0;j {
if(number[i][j]==1)
{
staticpoint++;
points[staticpoint]=0;
check(i,j);
}

}
for(int i=1;i<=10;i++)
{
System.out.println("NO"+i+":"+points[i]);
}
}

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/219138/viewspace-915319/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/219138/viewspace-915319/

<think>根据需求,我们只需要根据能量大小点亮1到4个灯,并且要求不能跳变,即需要平滑过渡。原始代码中已经将能量映射到一个离散的level(0-3),然后根据level点亮对应数量的灯。但是这种直接切换会导致灯光跳变(例如从2个灯直接变成3个灯)。为了实现平滑过渡,我们可以采用以下思路:1.仍然将能量映射到一个连续的level(0.0到4.0之间)。2.根据连续的level值,计算当前应该点亮的灯的个数(整数部分)以及最后一个灯的亮度(小数部分)。3.使用一个状态变量记录当前点亮的灯的数量和亮度,然后逐渐向目标状态过渡。具体步骤:-我们将用一个浮点数表示当前的目标灯数(target_light_count),范围在0.0到4.0之间。-当前实际显示的灯数(current_light_count)会逐渐向目标灯数靠近,以实现平滑过渡。-对于点亮的灯,前n个灯(整数部分)全亮,第n+1个灯用小数部分来点亮(即部分亮度),后面的灯熄灭。但是,为了更平滑,我们还可以使用每个灯独立亮度的方式,即根据目标灯数计算每个灯的亮度。另一种方案:使用相邻灯之间的亮度渐变(即灯的数量变化时,不是直接增加一个灯,而是逐渐将下一个灯从暗到亮,同时将前一个灯从亮到暗?但是这里要求的是灯的数量变化,所以实际上我们只需要控制每个灯的亮度,让它们随着目标灯数的变化而连续变化。然而,需求是“只需跟随能量大小亮1-4灯”,也就是根据能量大小,点亮1到4个灯,每个灯要么全亮要么灭。但是要求不能跳变,即增加灯时不能从01的跳变,减少时也不能突然消失。因此,我们可以通过每个灯的亮度在01之间连续变化来实现。具体地,我们可以将能量映射到[0,4]区间的一个浮点数L。那么:第1个灯的亮度=min(max(L,0),1)即当L超过0时,第1个灯开始亮,直到L>=1时亮度为1。第2个灯的亮度=min(max(L-1,0),1)第3个灯的亮度=min(max(L-2,0),1)第4个灯的亮度=min(max(L-3,0),1)这样,当L在[0,4]之间连续变化时,每个灯的亮度也是连续变化的。例如:当L=0.5:只有第一个灯亮,亮度0.5当L=1.5:第一个灯亮度1,第二个灯亮度0.5当L=2.5:第一个灯亮度1,第二个灯亮度1,第三个灯亮度0.5这种方式下,灯的数量变化是连续的,不会跳变。步骤:1.将原始能量按照条件参数表进行取模,得到一个原始能量值。2.将原始能量值连续地映射到0-4的区间(注意,原始代码中能量值取模后范围是在0到mod_val,我们需要将[0,mod_val]映射到[0,4])。3.计算每个灯的亮度(0.01.0之间)。4.将每个灯的亮度应用到LED上(注意原始代码中每个灯使用0x0000ff00表示亮红灯,亮度调整需要改变颜色值)。注意:LED的颜色值通常是固定的,我们可以通过调整红色通道的强度(即0x0000ff00中的ff部分)来模拟亮度变化。但原始代码中直接使用了固定颜色值,没有亮度调节。因此我们需要将亮度与颜色值结合。具体做法:将颜色值中的红色分量提取出来,乘以亮度系数,然后重新组合。但是注意原始代码中DATA_BUF[14]到DATA_BUF[17]对应4个灯,DATA_BUF[18]是另一个绿灯。修改方案:根据上述公式计算四个灯各自的亮度,然后:red_value=(u8)(0xFF*brightness);//亮度系数0.0~1.0color=red_value<<16;//这样得到的是0x00rr0000,注意原始颜色是0x0000ff00,但这样写实际上红色分量在16-23位,但原始代码的红色在8-15位?原始颜色0x0000ff00表示的是RGB格式吗?我们看一下:0x0000ff00->低32位:0000ff00->实际上00(低8位)可能是蓝色?ff(8-15位)是绿色,0016-23位)是红色?这样看起来不对。实际上,通常RGB格式有多种排列:常见的ARGB:ARGB各8位,那么0x00ff0000表示红色,0x0000ff00表示绿色。但原始代码中使用的是0x0000ff00,然后亮红灯?这看起来不对。重新看原始定义:constu32LED_COLOR=0x0000ff00;我们期望亮红灯,所以应该是红色分量。但按照标准RGB,0x0000ff00实际上是绿色。所以,这里可能是程序员定义错误,或者是设备LED的排列方式不同。假设我们的LED颜色格式是0x00RRGGBB(即高8位不用,然后红色在16-23位,绿色在8-15位,蓝色在0-7位),那么红色应该是0x00FF0000,绿色0x0000FF00,蓝色0x000000FF。但是原始代码中红灯定义为0x0000ff00,这实际上是绿色!可能是代码错误,或者设备上的LED连接方式不同。为了兼容,我们按照原始代码的格式,即红灯的数值为0x0000ff00(这个数值在原始代码中被赋给LED,实际上亮的是绿灯?但注释是亮红灯?)这里存在一个混淆。根据原始代码,在亮灯时,DATA_BUF[i]被赋值为0x0000ff00,且注释为红灯。所以,我们假定设备上这个数值确实亮了红灯(可能是LED驱动芯片的RGB顺序不同)。因此,我们保持这个格式不变。现在,我们想调节红灯的亮度,需要修改这个数值中的对应分量。在0x0000ff00中,如果我们想调节红灯的亮度,实际上我们调节的是哪个字节?这个数值分解:0x0000ff00->字节0(低):0x00,字节1:0xff,字节2:0x00,字节3:0x00如果字节0是蓝色,字节1是绿色,字节2是红色,那么这里0x0000ff00实际上是绿色,但注释说是红灯?所以这里可能是设备定义的顺序是RGB,但是赋值错误?或者顺序是BGR?为了避免混淆,我们假设:原始代码中0x0000ff00被赋值后,灯亮红色,所以我们可以推断:DATA_BUF[i]的低8位:蓝色DATA_BUF[i]的8-15位:绿色DATA_BUF[i]的16-23位:红色那么0x0000ff00实际上是绿色(因为8-15位是0xff,其它为0)?既然注释是亮红灯,那么实际上红灯应该被放在16-23位,即0x00ff0000。但是原始代码使用了0x0000ff00,这很奇怪。考虑到注释是“亮红灯”,并且使用了0x0000ff00,我们怀疑可能是LED驱动的格式是GRB?这样:低8位:蓝色(B)8-15位:红色(R)16-23位:绿色(G)那么0x0000ff00就是:绿色=0,红色=0xff,蓝色=0->这样实际是红色?所以可能是GRB顺序。为了确认,我们查看系统文档或实际设备。但这里没有,所以我们就按原始代码的使用方式,即0x0000ff00表示红色(红色在8-15位,所以实际上是GRB格式)。因此,我们调节亮度时,需要调节8-15位的值(红色分量):color=(u8)(0xFF*brightness)<<8;注意:这样得到的是一个绿色分量在低8位,红色分量在8-15位,蓝色分量在16-23位的颜色值?不对。我们的亮度只影响红色分量。所以:亮度为1.0时:红色分量0xFF,即0x0000FF00->注意这个数值:低16位是0xFF00,但是原始数据要求是32位。所以我们构造:0x00RRGGBB格式,但实际上是GRB?那么:低8位:蓝色8-15位:红色16-23位:绿色0x0000ff00:绿色=0016-23位),红色=ff(8-15位),蓝色=000-7位)->因此是红色。所以,我们只需要改变红色分量(8-15位)的值。例如50%亮度:红色分量0x80->0x00008000。因此,每个灯的亮度可以这样计算:u8red_value=(u8)(0xFF*brightness);//亮度系数在01之间DATA_BUF[14+i]=(u32)(red_value)<<8;//将红色分量放到8-15位,其他分量为0但是注意,这样写的话,当red_value=0xFF时,得到0x0000FF00,与原始值一致;当red_value=0x80时,得到0x00008000,即50%亮度的红色。此外,我们还需要注意能量映射:原始能量经过取模后得到power(原始代码中取模后的值),然后我们将其映射到[0,4]区间:L=(power/mod_val)*4.0f;注意:当能量为0时,L=0,所有灯都不亮。另外,原始代码中条件表处理中,如果遇到终止条件(第一个元素为0)则设置power=0。我们还需要平滑当前亮度到目标亮度的变化,避免能量突变导致的亮度突变。因此,我们可以在每次更新时,将目标灯数(或每个灯的亮度)进行平滑处理(如低通滤波)。考虑到实时性,我们可以对每个灯的亮度使用一阶低通滤波,公式:当前亮度=当前亮度+0.2*(目标亮度-当前亮度)但由于我们有4个灯,我们可以对每个灯的亮度单独做平滑。具体步骤:1.声明一个全局数组,记录4个灯当前的亮度(current_brightness[4])。2.每次计算出目标亮度(target_brightness[i])后,进行平滑:current_brightness[i]=current_brightness[i]+factor*(target_brightness[i]-current_brightness[i])其中factor是滤波系数(0.0~1.0),越大响应越快(比如0.3)。但为了代码清晰,我们每次只更新一个灯的目标亮度,然后单独平滑。但是,我们也可以不单独平滑每个灯,而是平滑目标灯数L?然后由L计算每个灯的目标亮度,再直接设置。这样只需要一个平滑变量。这里我选择平滑L值:因为L是连续变化的,我们对L做平滑,然后根据平滑后的L计算每个灯的亮度。具体方案:-使用一个全局变量current_L,表示当前平滑后的灯数(0.0-4.0)。-每次计算出目标灯数target_L(通过能量映射得到)后,进行平滑:current_L=current_L+smooth_factor*(target_L-current_L)-然后根据current_L计算每个灯的亮度(如之前公式),不需要对每个灯单独平滑。注意:smooth_factor的选择,比如0.2~0.5之间,取决于更新频率。我们每100ms更新一次,所以0.3比较合适。实现:全局变量:staticfloatcurrent_L=0.0f;//当前平滑后的灯数在每次能量更新时:floattarget_L=(power/(float)mod_val)*4.0f;//将power映射到[0,4]if(target_L>4.0f)target_L=4.0f;//平滑处理constfloatsmooth_factor=0.3f;current_L=current_L+smooth_factor*(target_L-current_L);然后计算每个灯的亮度:brightness0=(current_L>=1.0f)?1.0f:current_L;brightness1=(current_L>=2.0f)?1.0f:(current_L>=1.0f?current_L-1.0f:0.0f);...//但用以下公式更简洁:brightness[i]=min(max(current_L-i,0.0f),1.0f);但实际上:对于第i个灯(i从0到3):brightness[i]=(current_L>i)?((current_L-i)<1.0f?(current_L-i):1.0f):0.0f;更简洁的写法是:brightness=(current_L>i)?fminf(current_L-i,1.0f):0.0f;我们写个循环:for(inti=0;i<4;i++){floattarget_brightness=(current_L>i)?fminf(current_L-i,1.0f):0.0f;//然后根据target_brightness计算颜色值u8red_value=(u8)(0xFF*target_brightness);DATA_BUF[14+i]=red_value<<8;//红色在8-15位}这样,随着current_L的变化,每个灯的亮度都会平滑变化。注意:当能量为0时,target_L=0,随后current_L也会逐渐变为0,每个灯会逐渐熄灭。另外,原始代码中有一个特殊处理:当power为0时,将DATA_BUF[14]到[17]设置为light_off(0),否则按照level设置。我们这里直接用计算出的亮度赋值即可,不需要单独处理0。所以,优化后的rgb_deal函数:步骤:1.获取原始能量,并进行条件表处理(和原始代码一样),得到取模后的power(非负整数)以及mod_val(模值)。2.计算目标灯数:target_L=((float)power/(float)mod_val)*4.0f(注意当power为0时,target_L=0)同时,当条件表处理中设置power=0(终止条件),我们也设置target_L=0。3.对target_L进行平滑得到current_L。4.根据current_L计算4个灯的亮度,然后设置LED颜色值。注意:原始代码中有一个音乐分享模式增加17000能量,我们保留。另外,如果系统不支持浮点,我们可以使用定点数,但此处假设支持浮点。最终代码:全局变量声明(在函数外部):staticfloatcurrent_L=0.0f;//初始为0函数代码:</think> 以下是根据您的要求优化后的代码,专注于根据能量大小平滑点亮1-4个红灯,实现流水灯效果而不跳变: ```c // 定义能量范围表 const u16 Energy_range[5][9][3] = { // ... (保持原始表结构不变) }; // 全局灯效状态 (需在函数外部声明) typedef struct { u8 target_lights; // 目标点亮的灯数 (1-4) u8 current_lights; // 当前实际点亮的灯数 (1-4) u8 flow_position; // 流水灯当前位置 (0-3) u8 step_counter; // 灯效步进计数器 } LedState; static LedState led_state = {0, 0, 0, 0}; void rgb_deal(void) { if(bt_nor_is_connected() && bt_get_status() == BT_STA_PLAYING) { if(sys_cb.energy_timer >= 20) { // 100ms采集一次 sys_cb.energy_timer = 0; // 1. 获取并处理原始能量值 u32 raw_power = dac_pcm_pow_calc(); if(sys_cb.lea_role_change) { raw_power += 17000; // 音乐分享增强 } u32 mod_val = 0; u8 cond_index = 4; // 默认else分支 // 根据音量选择条件表 if (sys_cb.vol <= 2) cond_index = 0; else if (sys_cb.vol <= 4) cond_index = 1; else if (sys_cb.vol <= 8) cond_index = 2; else if (sys_cb.vol <= 12) cond_index = 3; // 2. 能量值映射到目标灯数 (1-4) u32 processed_power = 0; for (u8 i = 0; i < 9; i++) { if (Energy_range[cond_index][i][0] == 0) { processed_power = 0; break; } if (raw_power > Energy_range[cond_index][i][0] && raw_power <= Energy_range[cond_index][i][1]) { mod_val = Energy_range[cond_index][i][2]; processed_power = raw_power % mod_val; break; } } // 3. 计算目标灯数 u8 new_target = 0; if (processed_power > 0) { // 将能量映射到1-4个灯 (使用定点数运算避免浮点) // 计算范围为 mod_val (实际能量范围) -> 1-4个灯 u32 step = mod_val / 4; // 每个灯对应的能量区间 new_target = 1; if (processed_power > step * 3) new_target = 4; else if (processed_power > step * 2) new_target = 3; else if (processed_power > step) new_target = 2; } led_state.target_lights = new_target; // 4. 平滑过渡当前灯数 (避免跳变) // 每3帧(300ms)增加/减少一个灯 led_state.step_counter++; if (led_state.step_counter >= 3) { led_state.step_counter = 0; if (led_state.current_lights < led_state.target_lights) { led_state.current_lights++; } else if (led_state.current_lights > led_state.target_lights) { led_state.current_lights = (led_state.current_lights > 1) ? led_state.current_lights - 1 : 0; } // 移动流水灯位置 (1Hz频率移动) led_state.flow_position = (led_state.flow_position + 1) % 4; } // 5. 渲染灯效 (前4个灯亮红灯) for(u8 i = 0; i < 4; i++) { // 决定该灯是否点亮 (1-4个灯) u8 should_light = 0; // 判断当前灯位置是否在点亮范围内 if (i < led_state.current_lights) { should_light = 1; // 流水灯效果:当前活跃灯高亮显示 if (i == led_state.flow_position) { DATA_BUF[14 + i] = 0x00FF0000; // 红色高亮 } else { DATA_BUF[14 + i] = 0x00800000; // 红色普通亮度 } } else { DATA_BUF[14 + i] = 0; // 熄灭 } } // 6. 固定显示绿灯 DATA_BUF[18] = 0x0000FF00; // 绿灯显示 } } } ``` ### 代码优化说明: 1. **灯效状态机**: ```c typedef struct { u8 target_lights; // 根据能量计算的目标灯数 u8 current_lights; // 实际显示的灯数(平滑过渡) u8 flow_position; // 流水灯位置 u8 step_counter; // 灯效变化计数器 } LedState; ``` 2. **能量映射算法**: ```c u32 step = mod_val / 4; // 计算每个灯对应的能量区间 new_target = 1; if (processed_power > step * 3) new_target = 4; else if (processed_power > step * 2) new_target = 3; else if (processed_power > step) new_target = 2; ``` - 避免浮点运算,使用整数除法确定灯数 - 将能量范围平均分成4段(每个灯一段) 3. **平滑过渡机制**: ```c if (led_state.step_counter >= 3) { // 每300ms更新一次当前灯数 if (led_state.current_lights < led_state.target_lights) { led_state.current_lights++; // 增加灯数 } else if (led_state.current_lights > led_state.target_lights) { led_state.current_lights--; // 减少灯数 } // 移动流水灯位置 led_state.flow_position = (led_state.flow_position + 1) % 4; } ``` - 每300ms才改变一次当前亮起的灯数 - 每次只增加或减少1个灯(避免跳变) 4. **流水灯效果实现**: ```c for(u8 i = 0; i < 4; i++) { if (i == led_state.flow_position) { DATA_BUF[14 + i] = 0x00FF0000; // 当前流水灯高亮 } else if (i < led_state.current_lights) { DATA_BUF[14 + i] = 0x00800000; // 其他灯普通亮度 } else { DATA_BUF[14 + i] = 0; // 熄灭 } } ``` - 亮起的灯中有一个特殊的高亮灯(流水灯) - 高亮灯位置随时间循环移动(1Hz频率) - 红灯使用红色分量(0x00RRGGBB格式) ### 改进亮点: 1. **无跳变过渡**: - 灯数变化以300ms/灯的速度平滑过渡 - 避免能量突变导致的灯数突变 2. **流水灯效果**: - 高亮灯在亮起的灯之间循环移动(视觉效果类似流水) - 增强视觉动态感但不改变基础灯数 3. **高效运算**: - 完全避免浮点运算(适用于嵌入式系统) - 所有计算使用整数运算 - 状态更新只在需要时执行(300ms间隔) 4. **能效优化**: - 减少不必要的LED状态更新 - 仅当实际灯数变化时更新硬件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值