Amazon : 找出所给数字的下一个回文数

25 篇文章 0 订阅

找出所给数字的下一个回文数。所给数字不一定是回文数,要找的是恰好大于这个数字的最小的回文数。

本例子给出了两种方法来实现它。


 思路:  把该数字从中间分成左右长度相等两个数字串,记为左数字串和右数字串。

 
 A: 如果该数字串数字个数>1, 则按下面处理:
 1:如果该数的位数是偶数,把左数字串反过来,形成一个新的右数字串。
    1.1如果该新的右数字串换成数字后,比原来的右数字串大,则原来的左数字串+新的右数字串=所求之数字串。
    1.2 否则,把左数字加1,重新生成为一个新的左数字串,然后把它反转,形成新的右数字串。
        则 新的左数字串 + 新的右数字串 = 所求之数字串。
  
   2 如果该数的位数是奇数,把左数字串反过来,形成一个新的右数字串。
     2.1如果该新的右数字串换成数字后,比原来的右数字串大, 则 原来的左数字串 + 新的右数字串 = 所求之数字串。
     2.2 否则,把中间的那个数字+1。
          2.2.1 如果该中间数字加1后大于9,则把原来的左数字+1,然后形成一个新的左数字串,;如果该中间数字加1后<=9,原来的左数字串不变。
         2.2.2 把上步中的左数字串反转,形成新的右数字串。
         2.2.3 合并上面步骤得到的左数字串+中间数字+右数字串,即为所求之数字串。
 
 B: 如果数字串数字个数=1,则按以下处理:
 如果该数字<9,则,该数字+1后为所求的数字。
 如果该数字=9,则11为所求的数字。
 

程序输出:

entered number=12456 digits=5
V1 result number=12521
V2 result number=12521
entered number=12320 digits=5
V1 result number=12321
V2 result number=12321
entered number=12923 digits=5
V1 result number=13031
V2 result number=13031
entered number=1234 digits=4
V1 result number=1331
V2 result number=1331
entered number=8 digits=1
V1 result number=9
V2 result number=9
entered number=9 digits=1
V1 result number=11
V2 result number=11
entered number=9999 digits=4
V1 result number=9999
V2 result number=100001
entered number=1001001 digits=7
V1 result number=1002001
V2 result number=1002001


RUN SUCCESSFUL (total time: 955ms)


程序代码:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>

using namespace std;

void test(){
  std::stringstream ss; 
  ss<<12345;
  int m=0;
  ss >> m;
  cout<<m<<endl;
  
  string str("");
  str=ss.str();
  cout<<str<<endl;
  string str1("abc");
  在进行多次转换前,必须调用 stringstream::clear()
  ss.clear();
   ss << str1;
   str=ss.str();
   cout<<str<<endl;
   /*
    must use the below 2 statements to clear content stringstream.
    * 
    */
   ss.clear();
   ss.str("");
   str=ss.str();
   cout<<"final="<<str<<endl;
}
/*
 思路:把该数字从中间分成左右长度相等两个数字串,记为左数字串和右数字串。
 
 *A: 如果该数字串数字个数>1, 则按下面处理:
 1:如果该数的位数是偶数,把左数字串反过来,形成一个新的右数字串。
    1.1如果该新的右数字串换成数字后,比原来的右数字串大,则原来的左数字串+新的右数字串=所求之数字串。
    1.2 否则,把左数字加1,重新生成为一个新的左数字串,然后把它反转,形成新的右数字串。
        则 新的左数字串 + 新的右数字串 = 所求之数字串。
  
   2 如果该数的位数是奇数,把左数字串反过来,形成一个新的右数字串。
     2.1如果该新的右数字串换成数字后,比原来的右数字串大, 则 原来的左数字串 + 新的右数字串 = 所求之数字串。
     2.2 否则,把中间的那个数字+1。
          2.2.1 如果该中间数字加1后大于9,则把原来的左数字+1,然后形成一个新的左数字串,;如果该中间数字加1后<=9,原来的左数字串不变。
         2.2.2 把上步中的左数字串反转,形成新的右数字串。
         2.2.3 合并上面步骤得到的左数字串+中间数字+右数字串,即为所求之数字串。
 * 
 *B: 如果数字串数字个数=1,则按以下处理:
 * 如果该数字<9,则,该数字+1后为所求的数字。
 * 如果该数字=9,则11为所求的数字。
 */
int GetFirstBiggerPalindromeV2(int givenumber) {
 if(givenumber <=0)
     return 0;
  std::stringstream ss; 
  ss<<givenumber;
  string numberstring=ss.str(); 
  //digits
  int len=numberstring.length();
  bool odd=false;
  
  if(len&1==1)
      odd=true;
  
  string leftstr(""),rightstr(""),reverseleftstr("");
  int leftnum,rightnum,reserveleft;
  
  if(len>1) {
  leftstr.append(numberstring,0,len>>1);
  if(odd)
    rightstr.append(numberstring,(len>>1)+1,len>>1);
  else
    rightstr.append(numberstring,len>>1,len>>1);
  
  reverseleftstr=leftstr;
  reverse(reverseleftstr.begin(),reverseleftstr.end());
  
  //must clear for ss via clear() and str("");
  //clear() just clear out flags of stringstream.
  ss.clear();
  ss.str("");
  ss<<leftstr;
  ss>>leftnum;
  
  ss.clear();
  ss.str("");
  ss<<rightstr;
  ss>>rightnum;
  
  ss.clear();
  ss.str(""); 
  ss<<reverseleftstr;
  ss>>reserveleft;
  }
  int resultnum;
  string resultstring;
  
  if(odd){
      if(len==1) {
            ss.clear();
            ss.str("");
          ss<<numberstring;
          ss>>resultnum;
          
          if(resultnum==9)
              resultnum=11;
          else
              resultnum++;
         }
      else { //len>1
          char pchar=numberstring.at(len>>1);
          int middlevalue=pchar-'0';
          if(reserveleft <= rightnum){
           if(middlevalue<9) {
               pchar++;               
           } else {
               pchar='0';
               leftnum++;
               ss.clear();
               ss.str("");
               ss<<leftnum;
               leftstr=ss.str();
               
               reverseleftstr=leftstr;
               reverse(reverseleftstr.begin(),reverseleftstr.end());
           }           
          } 
         resultstring=leftstr;
         resultstring.append(1,pchar);
         resultstring += reverseleftstr;
         ss.clear();
         ss.str("");
         ss<<resultstring;
         ss>>resultnum; 
      }
   }
  
  if(!odd) {
       if(reserveleft <= rightnum) {
        //把左数字加1,重新生成为左数字串,然后把它反转,形成新的右数字串。
        //把这两个数字串相加,就是所求之数。
        leftnum++;
        ss.clear();
        ss.str("");
        ss<<leftnum;
        leftstr=ss.str();
        reverseleftstr=leftstr;
        reverse(reverseleftstr.begin(),reverseleftstr.end());
       }
       resultstring=leftstr;
       resultstring += reverseleftstr;
       
       ss.clear();
       ss.str("");
       ss<<resultstring;
       ss>>resultnum; 
   }
  cout<<"V2 result number="<<resultnum<<endl;
  return resultnum;
}

int GetFirstBiggerPalindrome(int givenumber) {
   
    if(givenumber <=0)
     return 0;
    
    char strnumber[100]={0};
    bool odd=true;
    int numberdigit=0,middle=0;
           
    sprintf(strnumber,"%d",givenumber); 
    numberdigit=strlen(strnumber);
    cout<<"entered number="<<strnumber<<" digits="<<numberdigit<<endl;
    
     middle=numberdigit/2;
    if((numberdigit&1)==1) {
        odd=true;
        middle++;
    }
    else
        odd=false;
  
    char leftstr[100]={0};
    char rightstr[100]={0};
    char leftreversestr[100]={0};
    
    int leftnumber=0,rightnumber=0,leftreverse=0;
    char middlenum;
    int index=0;
    int mid_position;
    
     if(odd)
        mid_position=middle-1;
     else
        mid_position=middle;
    
    for(index=0;index<mid_position;index++){
       leftstr[index]= strnumber[index];
       leftreversestr[ mid_position-1-index]=leftstr[index];
    }
    leftstr[index]='\0';
    leftreversestr[index]='\0';
    
    leftnumber=atoi(leftstr);
    leftreverse=atoi(leftreversestr);
    
    for(index=middle; index< numberdigit; index++){
       rightstr[index - middle]= strnumber[index]; 
    }
     rightstr[index]='\0';
     rightnumber=atoi(rightstr);
    
     char finalstr[100]={0};
     char *ptr=0;
     int resultNumber=0;
     
     if(odd){
         if(numberdigit==1){
             middlenum=strnumber[middle-1];
             resultNumber=middlenum-'0';
            if(resultNumber<9)
                resultNumber++;
            else
                resultNumber=11;
         }
         //multi digits >=3
         else {
           middlenum=strnumber[middle-1];
           if(leftreverse <= rightnumber) {
            if(middlenum < '9' ){
               middlenum++;
               strcpy(finalstr,leftstr);
               finalstr[middle-1]=middlenum;
               ptr=finalstr + middle;
               strcpy(ptr,leftreversestr);
               resultNumber=atoi(finalstr);
           }
           //==9           
           else {
                middlenum='0';
                leftnumber++;
                //remake the reverse left
                sprintf(leftstr,"%d",leftnumber);
                int length=strlen(leftstr);
                for(index=0;index<length;index++){
                  leftreversestr[length-1-index]=leftstr[index];
                }
                leftreversestr[index]='\0';
                strcpy(finalstr,leftstr);
                finalstr[middle-1]=middlenum;
                ptr=finalstr + middle;
                strcpy(ptr,leftreversestr);
               resultNumber=atoi(finalstr);
            } 
        }
       else { //left>right
               strcpy(finalstr,leftstr);
               finalstr[middle-1]=middlenum;
               ptr=finalstr + middle;
               strcpy(ptr,leftreversestr);
               resultNumber=atoi(finalstr);
        }
       }
     }
     
     //even
     if(!odd) {
          if(leftreverse < rightnumber){
              leftnumber++;
               sprintf(leftstr,"%d",leftnumber);
               int length=strlen(leftstr);
               for(index=0;index<length;index++){
                  leftreversestr[length-1-index]=leftstr[index];
                }
                
                leftreversestr[index]='\0';
                strcpy(finalstr,leftstr); 
                ptr=finalstr + middle;
                strcpy(ptr,leftreversestr);
               resultNumber=atoi(finalstr);
          }
          //leftreverse > right, make directly
          else {
              strcpy(finalstr,leftstr);
              ptr=finalstr + middle;
              strcpy(ptr,leftreversestr);
              resultNumber=atoi(finalstr);
          }
     } 
        
    cout<<"V1 result number="<<resultNumber<<endl;
   return  resultNumber;
}
/*
 * 
 */
int main(int argc, char** argv) {
    /*string str="12345";
      test();
     return 0;
    */  
      GetFirstBiggerPalindrome(12456);
      GetFirstBiggerPalindromeV2(12456);
      
      GetFirstBiggerPalindrome(12320);
      GetFirstBiggerPalindromeV2(12320);
       
      GetFirstBiggerPalindrome(12923);
      GetFirstBiggerPalindromeV2(12923);
          
      GetFirstBiggerPalindrome(1234);
      GetFirstBiggerPalindromeV2(1234);
      
      GetFirstBiggerPalindrome(8);
      GetFirstBiggerPalindromeV2(8); 
      
       GetFirstBiggerPalindrome(9);
      GetFirstBiggerPalindromeV2(9);
      
       GetFirstBiggerPalindrome(9999);
      GetFirstBiggerPalindromeV2(9999); 
      
      GetFirstBiggerPalindrome(1001001);
      GetFirstBiggerPalindromeV2(1001001); 
      
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值