讨论个简单的整除问题

BT_Dana 2013-06-20 10:59:00
问题很简单, 就是把一个总的数目n进行分割, 能分成几块.
这个是大家平时常遇到的吧, 之前面试也正好见过这样一道小题呢. 来提一下吧~

假设总数为n, 每块的大小为split, 则block_num = ?

我一般就是block_num = (0 == n % split) ? (n / split) : (n / split + 1);


有没有更高效的方法? 总觉得我这种求法是不是有点费劲...
...全文
308 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-07-11
  • 打赏
  • 举报
回复
block_num = (n +split-1)/split;
一般就行了, 如果考虑溢出的话,
block_num =  ( 0 == n )? 0: (n -1)/split+1;
0 比较特殊,-1就负数了,结果就不对了
BT_Dana 2013-07-02
  • 打赏
  • 举报
回复
引用 21 楼 erqieshi 的回复:
@#20 “信息与计算科学”的 好像很计算机的样子 其实就是数学系的 ,专业名以前叫 “计算数学”
哈哈, 截至到高中毕业我对数学都很感兴趣, 大学可不敢学那玩意, 想想都怕. 不过我可很崇拜数学系的, 学这个的搞编程的, 都挺牛逼, 思维确实缜密的多.
erqieshi 2013-07-02
  • 打赏
  • 举报
回复
@#20 “信息与计算科学”的 好像很计算机的样子 其实就是数学系的 ,专业名以前叫 “计算数学”
BT_Dana 2013-07-02
  • 打赏
  • 举报
回复
引用 16 楼 erqieshi 的回复:
我#7楼讲的ceil floor就是数学上的概念 而你的问题本质就是ceil floor到ceil 就是+1 - eps eps是一个足够小的数 当然你这里split为底 最小精度 (float)1/split 就够用了而已 ceil = (float)n/split + 1 - (float)1/split 再化简 使能直接使用整数相除 就是 ceil=(n-1)/split+1 这个才是本质 (n + split-1)/split 这个才是变形 例 n + split-1 >int_max && n<int_max 时 “(n + split-1)/split”就溢出了 而“(n-1)/split+1”没有溢出
兄台是数学专业的吗, 很犀利的样子, 哈哈^^
BT_Dana 2013-07-02
  • 打赏
  • 举报
回复
引用 16 楼 erqieshi 的回复:
我#7楼讲的ceil floor就是数学上的概念 而你的问题本质就是ceil floor到ceil 就是+1 - eps eps是一个足够小的数 当然你这里split为底 最小精度 (float)1/split 就够用了而已 ceil = (float)n/split + 1 - (float)1/split 再化简 使能直接使用整数相除 就是 ceil=(n-1)/split+1 这个才是本质 (n + split-1)/split 这个才是变形 例 n + split-1 >int_max && n<int_max 时 “(n + split-1)/split”就溢出了 而“(n-1)/split+1”没有溢出
学习了. 其实最后减去的1/split恰好是eps的最大值对吧!\ 这些种表达式其实归根到底都是在周旋这个比较笨的表达式block_num = (0 == n % split) ? (n / split) : (n / split + 1); 怎么把这两种情况捏合到一起. 就是要处理恰好整除和有余数这两种情况. 1) 如果能整除, 那么+1是多加了1, 所以减去一个<=1的数, 再取整, 则结果正确. 2) 如果不能整除, n/split+1刚好是正确的结果. 而(float)n/split的余数会是1/split ~ (n-1)/split, 减去1/split不会影响结果的正确性. 可见1/split是eps的最大值.
erqieshi 2013-07-02
  • 打赏
  • 举报
回复
ceil = floor(fval+1-eps) floor = ceil(fval + eps - 1) round = floor(fval +0.5) round = ceil(fval -0.5+eps) floor = round(fval - 0.5) ceil = round(fval + 0.5 - eps)
橡木疙瘩 2013-07-02
  • 打赏
  • 举报
回复
同意楼上,用(n-1)/split+1以避免溢出。
erqieshi 2013-07-02
  • 打赏
  • 举报
回复
我#7楼讲的ceil floor就是数学上的概念 而你的问题本质就是ceil floor到ceil 就是+1 - eps eps是一个足够小的数 当然你这里split为底 最小精度 (float)1/split 就够用了而已 ceil = (float)n/split + 1 - (float)1/split 再化简 使能直接使用整数相除 就是 ceil=(n-1)/split+1 这个才是本质 (n + split-1)/split 这个才是变形 例 n + split-1 >int_max && n<int_max 时 “(n + split-1)/split”就溢出了 而“(n-1)/split+1”没有溢出
BT_Dana 2013-07-01
  • 打赏
  • 举报
回复
引用 11 楼 Primitive_forest 的回复:
block_num=(n-1)/split+1 最后一块可能比前面的小
这个也对, 和那个道理是差不多的, 稍微换一下角度. 其实也就是一个表达式, 通分之后就是一个. 当然不是随便拆的, (n-1)/split+1继续拆成n/split - 1/split + 1可就不对了, 整数除法要谨慎!
BT_Dana 2013-07-01
  • 打赏
  • 举报
回复
引用 10 楼 vuqrzk5w 的回复:
ceil、floor
指的是用朴素的算法哦, 不用库函数, 用库函数还得需要头文件神马的.
BT_Dana 2013-07-01
  • 打赏
  • 举报
回复
引用 5 楼 wangdahu888 的回复:
[quote=引用 4 楼 aa2650 的回复:] [quote=引用 2 楼 edwardvsnc 的回复:] block_num = (n + split - 1)/split;
妙啊, 亲~ 加上(模 - 1)再去做除法, 找的就是你了! 这个表达式我比较接受, 看着舒服, 够简短.[/quote] 怎么妙了,没看明白其数学原理[/quote] 正好能整除的数, 加上(模 - 1), 除以这个模, 被除法截断后值是不会变的 不能整除的, 也就是有余数的, 加上(模 - 1)后一定溢出到下一区间去了, 被除法截断后也刚刚好正确. 比如模(也就是这里的split)是5 n为30时, 加上4(模-1)之后是34, 不会"溢出"到下一区间(35~39), 除完仍然是6 如果n是31/32/33/34, 加上4(模-1)之后一定而且刚好"溢出"到下一区间(35~39), 被除法截断后, 结果刚刚好. 表达能力不太好, 就这么解释下吧...
Primitive_forest 2013-06-21
  • 打赏
  • 举报
回复
block_num=(n-1)/split+1 最后一块可能比前面的小
vuqrzk5w 2013-06-21
  • 打赏
  • 举报
回复
ceil、floor
jiacye13 2013-06-21
  • 打赏
  • 举报
回复
哈哈,又学习了一招,感谢2楼~
jiandingzhe 2013-06-21
  • 打赏
  • 举报
回复
减去余数不就行了?
remain = n % block_size;
block_num = (n-remain) / block_size;
那闯 2013-06-20
  • 打赏
  • 举报
回复
block_num = (n + split - 1)/split;
ri_aje 2013-06-20
  • 打赏
  • 举报
回复
block_num = n/split; 不就行了吗。
erqieshi 2013-06-20
  • 打赏
  • 举报
回复
ceil 打错字了
erqieshi 2013-06-20
  • 打赏
  • 举报
回复
数学原理就是 所谓的天花板数cel(fvl) 与地板数 floor(fvl) 以及跟四舍五入数round(fvl)间的相互转化 你这个需要求的是天花板数 但是整数运算是截断的即是地板数
lm_whales 2013-06-20
  • 打赏
  • 举报
回复
一般都是这样计算的,除非是浮点数计算。 block_num = (n +split-1)/split;
加载更多回复(3)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧