• 面试题----寻找比一个N位数大的“下”一个数


    1. 题目描述

          写出一个算法,实现如下功能:

    给定一个N位数字组成的数,找出比这个数大的由相同数字组成的下一个数

    例如:如果数字为 25468, 则结果为25486 如果数字为 21765, 则结果为 25167 如果数字为 54321, 则结果为 54321 (因为没有比这个数大的相同数字组成的值)

       

         2.问题分析

    • 因为N是一个没有范围的数,因此在解决此题时排出用N-位整数作为输入,而是用字符串来处理
    • 若存在有连续数字是相同的应该如何处理?
    • 观察例子可以得到如下思路

         一个N数如83557761,从右往左,找到当前位置上的数比它左边的数大为止(相等也要继续),即找到左边第一个7,比5大,得到7761,逆序为1677,然后从左往右找到第一个比5大的数6,交换5和6,即得到83561577。

         3.此算法一般性讲解

         把N位数分为两部分前i位和后N-i位,其中后N-i位从右往左是不减的(要么递增,要么相等),因此,不管怎样调这N-i,数都不会增大。按前面的分法,第i位一定比第i+1位小,也可能比第i+2位小,以此类推,找到第i+j位数,它比第i位数大,但是第i+j+1位数比第i位数小,交换第i位和第i+j位,然后提取i+1到第i+j-1这部分数字和第i+j+1到第N位的数字,这两部分分别逆序之后交换位置放置即可。结合例子可以理解。

        

          4.代码和注释

     1 #include<iostream>
     2 #include<string>
     3 #include <algorithm> 
     4 using namespace std;
     5 
     6 
     7 int main()
     8 {
     9     string digit;
    10     cin >> digit;
    11 
    12     int len,i,j;
    13     len = digit.length();
    14     //N<=1直接输出
    15     if(len <= 1)
    16     {
    17         cout << digit<<endl;
    18         return 0;
    19     }
    20     //当digit中有连续的相同数字,在从右到左遍历时仍然继续遍历
    21     for(i=len-1;i>=1;i--)
    22         if(digit[i]>digit[i-1])break;
    23 
    24     //digit从右到左都是不减的,则不用调整
    25     if(i==0)
    26     {
    27         cout << digit<<endl;
    28         return 0;
    29     }
    30     //提取前i位
    31     string pre = digit.substr(0,i);
    32     //提取后N-i位
    33     string end = digit.substr(i,len-i);
    34     
    35     reverse(end.begin(), end.end()); //逆序
    36     
    37 
    38     int index = pre.length();
    39     int num =pre[index-1]; 
    40     for(j=0;j<end.length();j++)
    41         if(end[j]>=num)break;
    42 
    43     //交换第i位和第i+j位
    44     pre[index-1] = end[j];
    45     end[j]=num;
    46 
    47     digit = pre+end;//合并即可
    48 
    49     cout<<digit<<endl;
    50     return 0;
    51 }
  • 相关阅读:
    自由职业者:如何找到你的第一个客户 【转载】
    MPI教程地址
    多线程程序设计.....
    PE格式的深入理解(一)
    用Hook解决在VC++与C++Builder方面界面设计的一些问题
    ANSI,MBCS,Unicode与使用swprintf的陷阱
    关于单片机程序
    C#操作SharePoint列表
    CAML中比较日期时间类型[转]
    使用C#创建webservice及三种调用方式
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/3659437.html
Copyright © 2020-2023  润新知