免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: fertiland
打印 上一主题 下一主题

[算法] 算法求一个数a的下一个临近数b,详情如下 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2007-10-28 09:38 |只看该作者
我看出来了,这个网易笔试题

论坛徽章:
0
22 [报告]
发表于 2007-10-29 23:11 |只看该作者

是我想错了吗

我觉的可以这样求,找到a中非0的最低位,此位减1,把此位的上一位加1,如果上一位是9就上推一位,把比加1位小的位全取0,然后从个位开始把原来取掉的位的和分掉.

[ 本帖最后由 ydhbzkx 于 2007-10-29 23:17 编辑 ]

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
23 [报告]
发表于 2007-10-30 12:04 |只看该作者
LZ,可能有溢出吗?

论坛徽章:
0
24 [报告]
发表于 2007-10-30 12:25 |只看该作者
luguo
hll 该用户已被删除
25 [报告]
发表于 2007-10-31 15:51 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
oceanpea 该用户已被删除
26 [报告]
发表于 2007-10-31 17:15 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
27 [报告]
发表于 2007-10-31 18:09 |只看该作者
原帖由 oceanpea 于 2007-10-31 17:15 发表



这个a怎么分解的阿?分解成x[k]...x[1]a9...9b0...0 ?
能写详细一点么,没看明白。。。

  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. using namespace std;

  5. /**
  6. * 计算正数num1的上临近数num2,num2满足:
  7. *    (1) num2 > num1;  
  8. *    (2) num1、num2各位数字之和相等(十进制表示);  
  9. *    (3) num2是满足(1)、(2)条件的最小正数
  10. * @param num: num1的值,应为正数
  11. * @return: 如果@param num为正数,则返回num1的上临近数num2;否则返回-1
  12. */
  13. int get_up_nearest(size_t num)
  14. {
  15.     if (num == 0)
  16.         return -1;    // 0没有上临近数

  17.     ostringstream oss;
  18.     oss << num;
  19.     string src("0");  // 保证下面的a的存在,并且不会影响结果
  20.     src += oss.str();

  21.    
  22.     // 把num表示为x[k]...x[1]a9...9b0...0,其中a != 9, b != 0(前面的x[i]可能没有)
  23.     // step1:将原串变为x[k]...[1]ab0...09...9
  24.     // step2:再次变换为x[k]...x[1](a+1)0...0(b-1)9...9,over
  25.     typedef string::size_type pos_t;

  26.     pos_t b = src.find_last_not_of('0');
  27.     pos_t a = src.find_last_not_of('9', b - 1);

  28.     // 计算x[k]...[1]ab0...09...9中"最后一个"0的位置,即x[k]...[1]ab0...c9...9
  29.     pos_t c = src.length() - b + a;
  30.     ++src[a];
  31.     src[c] = src[b] - 1;
  32.     for (pos_t i = a + 1; i < c; ++i)
  33.         src[i] = '0';
  34.     for (pos_t i = c + 1; i < src.length(); ++i)
  35.         src[i] = '9';
  36.    
  37.     int res = atoi(src.c_str());

  38.     return res;   
  39. }

  40. /**
  41. * 计算正数num1的下临近数num2,num2满足:
  42. *    (1) num2 < num1;  
  43. *    (2) num1、num2各位数字之和相等(十进制表示);  
  44. *    (3) num2是满足(1)、(2)条件的最大正数
  45. * @param num: num1的值;对于某些特殊的num值,可能不存在相应的下临近数
  46. * @return: 如果存在下临近数,则返回下临近数;否则返回-1
  47. * @note: 并不是所有数都存在下临近数,例如0~9,还如x99...9这类数就不存在下临近数
  48. */
  49. int get_down_nearest(size_t num)
  50. {
  51.     if (num < 10)
  52.         return -1;   // 不存在下临近数
  53.    
  54.     ostringstream oss;
  55.     oss << num;
  56.     string src = oss.str();
  57.    
  58.    
  59.     // 把num表示为x[k]...x[1]a0...0b9...9,其中a != 0, b != 9
  60.     // step1:x[k]...x[1]a9...90...0b
  61.     // step2:x[k]...x[1](a-1)9...9(b+1)0...0
  62.     typedef string::size_type pos_t;

  63.     pos_t b = src.find_last_not_of('9');
  64.     if (b == string::npos || b == 0)
  65.         return -1;   // num形如:x99...9,此时不存在下临近数
  66.    
  67.     pos_t a = src.find_last_not_of('0', b - 1);
  68.    
  69.     // 计算x[k]...x[1]a9...90...0b中"第一个"0的位置,即x[k]...x[1]a9...9c...0b
  70.     pos_t c = src.length() - b + a;   
  71.     --src[a];
  72.     src[c] = src[b] + 1;
  73.     for (pos_t i = a + 1; i < c; ++i)
  74.         src[i] = '9';
  75.     for (pos_t i = c + 1; i < src.length(); ++i)
  76.         src[i] = '0';
  77.    
  78.     int res = atoi(src.c_str());
  79.    
  80.     return res;   
  81. }

  82. void test(int num)
  83. {
  84.     cout << "num = " << num << ", up-nearest = " << get_up_nearest(num)
  85.         << ", down-nearest = " << get_down_nearest(num) << endl;
  86. }

  87. int main()
  88. {
  89.     test(113);
  90.     test(10);
  91.     test(200);
  92.     test(1);
  93.     test(2);
  94.     test(9);
  95.     test(99);
  96.     test(1999);
  97.     test(4684);
  98.     test(4660500);
  99.    
  100.     return 0;
  101. }
复制代码


输出:
num = 113, up-nearest = 122, down-nearest = 104
num = 10, up-nearest = 100, down-nearest = 1
num = 200, up-nearest = 1001, down-nearest = 110
num = 1, up-nearest = 10, down-nearest = -1
num = 2, up-nearest = 11, down-nearest = -1
num = 9, up-nearest = 18, down-nearest = -1
num = 99, up-nearest = 189, down-nearest = -1
num = 1999, up-nearest = 2899, down-nearest = -1
num = 4684, up-nearest = 4693, down-nearest = 4675
num = 4660500, up-nearest = 4661004, down-nearest = 4660410

论坛徽章:
0
28 [报告]
发表于 2007-10-31 23:28 |只看该作者
各位大牛数学没学太好啊~~~
不知道有数根这个东西吗

大部分的数加9即可

也有特殊情况 特殊处理 不多说了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP