Pixel density(简单的字符串处理)

本博客指导用户如何通过屏幕尺寸和分辨率计算电子产品如手机和平板的像素密度(PPI),包括处理不规范的数据输入并给出计算结果,精确到小数点后两位。

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

1、题目大意:

给定字符串,处理,要求将其分成五个部分,很简单的题目,赛后一遍就对了,不过赛中却忽略了后几个空格的处理,

Pixel density

Time Limit: 1000MS    Memory limit: 65536K

题目描述

Pixels per inch (PPI) or pixel density is a measurement of the resolution of devices in various contexts; typically computer displays, image scanners, and digital camera image sensors. Note, the unit is not square inches. Good quality photographs usually require 300 pixels per inch when printed. When the PPI is more than 300(phone), we call it retina screen. Sunnypiggy like the retina screen very much.


But you know it is expensive for Sunnypiggy and Sunnypiggy’s own smart phone isn’t like that.
I tell you how to calculate the PPI. First we must know how big the mobile phone’s screen is. Then we get the resolution (Hp*Wp) about it. After that we calculate the diagonal resolution in pixels (Dp) and divided by diagonal size in inches. Now you get the answer.
Maybe you knew it, but Sunnypiggy’s math is very bad and he wants you to help him to calculate the pixel density of all the electronic products he dreamed.

输入

First you will get an integer T which means the number of test cases, and then Sunnypiggy will tell you the name and type of the electronic products. And you know, Sunnypiggy is a careless boy and some data aren’t standard, just like 04.00 inches or 0800*0480.

输出

Output the answers to Sunnypiggy just like the sample output. Maybe it is not a phone. Sunnypiggy like such a form, although it seems no use. The result should be rounded to 2 decimal places. When it has no screen (0.0 inches) that we define the answer is 0.00(PPI).

示例输入

2iPhone 4S  3.5 inches 960*640 PHONEThe new iPad  0009.7 inches 2048*1536 PAD

示例输出

Case 1: The phone of iPhone 4S's PPI is 329.65.Case 2: The pad of The new iPad's PPI is 263.92.

直接贴代码吧

#include<stdio.h>
#include<string.h>
#include <cmath>
/*char s[150];
char s0[50],s1[50],s2[50],s3[50],s4[50],s11[50];
*/
double stoa(char *str)
{
    int k=0;
    double sum=0;
    int flag=0;
    for(int i=0; i<strlen(str); i++)
    {
        if(str[i]=='.')
        {
            k=i;
            flag=1;
            break;
        }
    }
    if(flag==1)
    {
        int j=0;
        for(int i=k-1; i>=0; i--)
        {
            sum+=pow(10.0,j)*(str[i]-'0');
            j++;
        }
        j=-1;
        for(int i=k+1; i<strlen(str); i++)
        {
            sum+=pow(10.0,j)*(str[i]-'0');
            j--;
        }
    }
    else
    {
        int len=strlen(str);
        for(int i=0; i<len; i++)
            sum+=(str[i]-'0')*pow(10.0,len-i-1);
    }
    return sum;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cas=1; cas<=t; cas++)
    {
        char s[150]= {0};
        char s0[50]= {0},s1[50]= {0},s2[50]= {0},s3[50]= {0},s4[50]= {0},s11[50]= {0};
        if(cas==1)
            getchar();
        gets(s);
        //printf("%s\n",s);
        int flag=0,k;
        for(int i=0; i<strlen(s); i++)
        {
            if(s[i]=='i'&&s[i+1]=='n'&&s[i+2]=='c'&&s[i+3]=='h'&&s[i+4]=='e'&&s[i+5]=='s'&&s[i-1]==' '&&s[i+6]==' ')
            {
                flag=1;
                k=0;
                int jj=i-1;
                int sum1=0;
                for(int j=jj;j>=0;j--)
                {
                    if(s[j]==' ')
                    {
                        jj--;
                        sum1++;
                    }
                    else
                    break;
                }
                for(int j=jj;j>=0;j--)
                {
                    if(s[j]!=' ')
                    s1[k++]=s[j];
                    else
                    break;
                }
                k=0;
                for(int j=strlen(s1)-1;j>=0;j--)
                s11[k++]=s1[j];
                k=0;
                jj=i-sum1-strlen(s1)-1;
                for(int j=jj;j>=0;j--)
                {
                    if(s[j]==' ')
                    {
                        jj--;
                        sum1++;
                    }
                    else
                    break;
                }
                for(int j=0;j<=jj;j++)
                s0[k++]=s[j];
                k=0;sum1=0,jj=i+6;
                for(int j=jj;j<strlen(s);j++)
                {
                    if(s[j]==' ')
                    {
                        sum1++;
                    }
                    else
                    break;
                }
                for(int j=i+5+sum1+1;j<strlen(s);j++)
                {
                    if(s[j]!='*')
                    s2[k++]=s[j];
                    else
                    break;
                }
                k=0;
                for(int j=i+5+sum1+strlen(s2)+2;j<strlen(s);j++)
                {
                    if(s[j]!=' ')
                    s3[k++]=s[j];
                    else
                    break;
                }
                k=0;
                for(int j=i+5+sum1+strlen(s2)+1+strlen(s3)+1;j<strlen(s);j++)
                {
                    if(s[j]==' ')
                    {
                        sum1++;
                    }
                    else
                    break;
                }
                k=0;
                for(int j=i+5+sum1+strlen(s2)+1+strlen(s3)+1;j<strlen(s);j++)
                {
                    if(s[j]>='A'&&s[j]<='Z')
                    s4[k++]=s[j]+32;
                    else
                    s4[k++]=s[j];
                }
            }
            if(flag==1)
                break;
        }
        double a=stoa(s11);
        double b=stoa(s2);
        double c=stoa(s3);
       //printf("%lf %lf %lf\n",a,b,c);
        //printf("%s/%s/%s/%s/%s\n",s0,s11,s2,s3,s4);
        double sum=sqrt(b*b+c*c)/a;
        if(a==0)
        {
            printf("Case %d: The %s of %s's PPI is 0.00.\n",cas,s4,s0);
        }
        else
        printf("Case %d: The %s of %s's PPI is %.2lf.\n",cas,s4,s0,sum);
    }
    return 0;
}
/*
3
iPhone 4S .00 inches 0960*00640 PHONE
The new iPad        .5 inches 2048*1536 PAD
ddinches  3.5 inches 960*640 PHONE
*/


帮我分析这几个方法,修改不合理的部分,并注释修改,将主要逻辑流程说明就好,多余的文字去除,方法如下: def checkImage(self, src_path, similar=0.95, loc=5, debug=False): """ 检测当前屏幕是否存在目标图片(基于图像匹配) :param src_path: 目标图片路径(相对或绝对路径) :param similar: 相似度阈值(0-1之间,默认0.95) :param loc: 匹配位置参数(具体含义依赖ImgUtils.quick_find实现) :param debug: 是否开启调试模式(默认False) :return: 布尔值(True:找到目标图片;False:未找到) """ # 步骤1:获取当前屏幕截图路径 screenshot_dir = os.path.join(os.getcwd(), "resource/superapp") os.makedirs(screenshot_dir, exist_ok=True) current_screenshot_path = os.path.join(screenshot_dir, "test.png") # 步骤2:校验目标图片是否存在 resource_root = os.path.join(os.getcwd(), "resource", "superapp") target_image_path = os.path.join(resource_root, src_path) if not os.path.isfile(target_image_path): print(f"{src_path}不存在!!!") # 步骤3:校验截图文件是否有效 if not os.path.exists(current_screenshot_path) or not os.path.isfile(current_screenshot_path): print(f"{current_screenshot_path}无效!!!") # 步骤4:校验相似度阈值有效性 if not 0 <= similar <= 1: raise ValueError(f"相似度阈值必须在0到1之间,当前值:{similar}") try: # 步骤5:调用图片匹配算法(返回匹配坐标和匹配得分) match_position, match_score = self.quick_find( current_screenshot_path, target_image_path, similar=similar, loc="all", debug=debug ) print(f"匹配结果-坐标:{match_position},得分:{match_score}") # 步骤6:判定是否匹配成功(坐标和得分均不为None) is_matched = (match_position is not None) and (match_score is not None) print(f"匹配结果:{is_matched}") return is_matched except Exception as e: print(f"图片匹配异常:{str(e)}") return False def quick_find(self,fp1: str, fp2: str,similar: float = 1,density: float = None,rect: tuple = None,loc: str = "all", debug: bool = False) -> any: """在背景图像中搜索目标图像的位置(核心功能:图像匹配)""" # -------------------- 调试模式初始化(可选计时) -------------------- if debug: # from time import time # 示例计时工具(可替换为自定义TS) # start_time = time() # 记录开始时间 print(f"此处废弃调试计时") # -------------------- 步骤1:加载背景图和目标图 -------------------- background_img = Image.open(fp1) # 加载背景图(待搜索的大图) target_img = Image.open(fp2) # 加载目标图(需要查找的小图) # -------------------- 步骤2:确定搜索区域 -------------------- bg_width, bg_height = background_img.size # 获取背景图尺寸(宽度, 高度) # 若未手动指定搜索区域rect,则根据loc自动计算默认区域(调用get_rect) if rect is None: rect = self.get_rect( width=bg_width, height=bg_height, loc=loc) # -------------------- 步骤3:预处理图像为数组 -------------------- # 注:img2arr可能是将PIL图像转为numpy数组的工具函数(需自定义实现) if rect: cropped_bg = background_img.crop(rect) else: cropped_bg = background_img background_arr = self.img2arr(cropped_bg) # 背景图数组 target_arr = self.img2arr(target_img) # 目标图数组 # -------------------- 调试模式:输出预处理耗时 -------------------- if debug: print(f"此处废弃调试计时") # -------------------- 步骤4:执行图像匹配 -------------------- # 调用核心匹配函数(假设find_arr是自定义匹配函数,需自行实现) return self.find_arr( im1=background_arr, im2=target_arr, similar=1, density=density, rect=rect, debug=False ) def get_rect(self,width: int, height: int, loc: str = "all", region_ratio: float = 0.5) -> tuple: """ 根据位置字符串计算背景图的搜索区域矩形坐标(适配quick_find的loc参数) """ center_x, center_y = width // 2, height // 2 half_w = int(width * region_ratio / 2) half_h = int(height * region_ratio / 2) if loc == "all": return (0, 0, width, height) elif loc == "top_left": return (0, 0, width // 2, height // 2) elif loc == "top_right": return (width // 2, 0, width, height // 2) elif loc == "bottom_left": return (0, height // 2, width // 2, height) elif loc == "bottom_right": return (width // 2, height // 2, width, height) elif loc == "center": return ( center_x - half_w, center_y - half_h, center_x + half_w, center_y + half_h ) else: raise ValueError( f"无效的loc参数:{loc}。\n" f"可选值:'all'(全图)、'top_left'(左上)、'top_right'(右上)、'bottom_left'(左下)、'bottom_right'(右下)、'center'(中心)" ) def img2arr(slef,img, rect=None, convert=True): """ 将图像转换为像素值的二维数组 参数: img: PIL.Image 对象,输入图像 rect: 元组 (x_start, y_start, x_end, y_end),可选,指定要提取的矩形区域坐标 convert: 布尔值,是否将图像转换为灰度模式(默认True) 返回: 二维列表,每个元素是对应坐标的像素值(0-255) """ # 转换为灰度图(如果需要) if convert and img.mode != 'L': img = img.convert('L') # 'L' 表示8位灰度模式 # 获取图像尺寸(宽、高) width, height = img.size # 加载像素访问对象(用于获取具体坐标的像素值) pixels = img.load() # 情况1:需要提取指定矩形区域的像素 if rect: x_start, y_start, x_end, y_end = rect # 解包矩形区域坐标 # 遍历y轴范围(高度方向),再遍历x轴范围(宽度方向) return [ [ pixels[x, y] # 获取坐标(x, y)的像素值 for x in range(width) # 遍历图像宽度方向所有x坐标 if x_start <= x <= x_end # 仅保留x在指定区域内的像素 ] for y in range(height) # 遍历图像高度方向所有y坐标 if y_start <= y <= y_end # 仅保留y在指定区域内的像素 ] # 情况2:无矩形区域,返回全图像素数组 return [ [ pixels[x, y] # 获取坐标(x, y)的像素值 for x in range(width) # 遍历宽度方向所有x坐标 ] for y in range(height) # 遍历高度方向所有y坐标 ] def find_arr(self,im1, im2, similar=1, density=None, rect=None, debug=False): """ 在主图像数组中查找模板图像的位置(基于像素匹配的定位算法) 参数: im1: 二维列表,主图像的像素数组(行×列结构) im2: 二维列表,待查找的模板图像的像素数组(行×列结构) similar: 相似度阈值(0-1之间),值越大要求匹配越严格(默认1) density: 元组(density_x, density_y),采样密度参数(控制匹配时的采样点数) rect: 元组(x_start, y_start, x_end, y_end),可选,限制搜索区域的矩形框 debug: 布尔值,是否开启调试模式(打印耗时等信息,默认False) 返回: (相似度, 位置元组)(None, None) 位置元组格式: (x1, y1, x2, y2) 表示模板在主图中的左上和右下坐标 """ # 调试模式:记录开始时间 if debug: print(f"此处废弃调试计时") # -------------------- 初始化基础参数 -------------------- template_width = len(im2[0]) # 模板图像的宽度(列数) template_height = len(im2) # 模板图像的高度(行数) # 主图像中模板可滑动的最大横向/纵向位置数(避免越界) max_x = len(im1[0]) - template_width + 1 # 横向最大起始x坐标范围 max_y = len(im1) - template_height + 1 # 纵向最大起始y坐标范围 # -------------------- 处理采样密度 -------------------- # 采样密度:控制匹配时的采样点数(密度越大,采样点越少,计算越快) if not density: # 未指定密度时,通过工具类获取默认采样密度(假设返回横向/纵向的位移位数) density_x, density_y = self.get_density(template_width, template_height) else: density_x, density_y = density # 使用用户指定的密度参数 # 计算采样步长(通过右移操作实现降采样) step_y = template_height >> density_y # 纵向采样步长(行数方向) step_x = template_width >> density_x # 横向采样步长(列数方向) total_samples = step_y * step_x # 总采样点数(用于计算相似度) max_fail = (1 - similar) * total_samples # 最大允许不匹配点数(超过则判定不匹配) # 调试模式:打印采样参数 if debug: print(f"denXX: {step_x}; denYY: {step_y}; total: {total_samples}") print(f"maxFailNum {max_fail}") # -------------------- 搜索超时控制(5分钟) -------------------- start_time = time.time() timeout = start_time + 5 * 60 # 最大允许运行时间5分钟 # -------------------- 遍历主图像所有可能的位置 -------------------- # 外层循环:纵向遍历主图像(y坐标范围) for y in range(max_y): # 内层循环:横向遍历主图像(x坐标范围) for x in range(max_x): # 超时检测 if time.time() > timeout: return None, None # 超时返回空 mismatch = 0 # 当前位置的不匹配点数计数 is_match = True # 是否匹配的标记 # 遍历所有采样点(纵向×横向) for sample_y in range(step_y): for sample_x in range(step_x): # 计算采样点在模板中的实际坐标(通过左移还原原始位置) template_x = sample_x << density_x # 模板中的列坐标 = 采样x × 2^density_x template_y = sample_y << density_y # 模板中的行坐标 = 采样y × 2^density_y # 获取模板采样点的像素值 template_pixel = im2[template_y][template_x] # 获取主图像对应位置的像素值(主图起始位置(x,y) + 模板偏移(template_x, template_y)) main_pixel = im1[y + template_y][x + template_x] # 像素不匹配时计数 if main_pixel != template_pixel: mismatch += 1 # 超过最大允许不匹配数时,提前终止检查 if mismatch >= max_fail: is_match = False break if not is_match: break # 内层循环提前终止 # 匹配成功时返回结果 if is_match: # 调试模式:记录结束时间 if debug: print(f"此处废弃调试计时") # 处理区域限制(rect参数):调整返回的位置坐标 if rect: x_start, y_start, x_end, y_end = rect # 最终位置 = 原始位置 + rect的偏移量 return ( 1 - (mismatch / total_samples), # 相似度 = 1 - 不匹配率 ( x + x_start, # 左上角x坐标 y + y_start, # 左上角y坐标 x + template_width + x_start, # 右下角x坐标 y + template_height + y_start # 右下角y坐标 ) ) else: # 无区域限制时直接返回原始位置 return ( 1 - (mismatch / total_samples), (x, y, x + template_width, y + template_height) ) # 调试模式:记录结束时间 if debug: print(f"此处废弃调试计时") # 遍历完所有位置未找到匹配 return None, None def get_density(self,width, height, maxWNum=4, maxHNum=4): """ 计算图像匹配时的横向/纵向采样密度(通过右移次数控制采样点数) 核心逻辑: 通过循环右移操作(等价于不断除以2取整),将图像的宽/高缩小到不超过maxWNum/maxHNum, 最终返回需要右移的次数(即密度参数)。该参数用于控制匹配时的采样间隔。 参数: width: 原始图像的宽度(列数) height: 原始图像的高度(行数) maxWNum: 横向最大允许采样点数(默认4) maxHNum: 纵向最大允许采样点数(默认4) 返回: (density_x, density_y): 横向/纵向的采样密度(右移次数) """ # 初始化密度参数(右移次数) density_x, density_y = 0, 0 # -------------------- 计算横向采样密度 -------------------- # 当宽度超过maxWNum时,持续右移(每次右移1位,即宽度减半) while width > maxWNum: density_x += 1 # 右移次数+1(密度增加) width = int(width >> 1) # 宽度右移1位(等价于整除2) # -------------------- 计算纵向采样密度 -------------------- # 当高度超过maxHNum时,持续右移(每次右移1位,即高度减半) while height > maxHNum: density_y += 1 # 右移次数+1(密度增加) height = int(height >> 1) # 高度右移1位(等价于整除2) return density_x, density_y
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值