剑指Offer:面试题33 把数组排成最小的数

/*
把数组排成最小的数:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接处的所有数字中的最小的一个。例如
输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323

思路:
我们应该对于给出的两个数字m和n,需要确定规则m和n哪个应该排序在前面,而不是比谁大谁小。
m和n能拼成mn或者nm,当mn<nm时,我们打印出mn,此时定义<
由于m和n都在int中,而拼接之后可能溢出,因此用字符串法来处理大数问题。
由于mn和nm位数相同,所以比较大小只需按照字符串大小比较即可。

输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。
输出:
对应每个测试案例,
输出m个数字能排成的最小数字。
样例输入:
3
23 13 6
2
23456 56
样例输出:
13236
2345656
*/

/*
关键:
1 我们应该对于给出的两个数字m和n,需要确定规则m和n哪个应该排序在前面,而不是比谁大谁小。
m和n能拼成mn或者nm,当mn<nm时,我们打印出mn,此时定义<
由于m和n都在int中,而拼接之后可能溢出,因此用字符串法来处理大数问题。
由于mn和nm位数相同,所以比较大小只需按照字符串大小比较即可。
2  char** strNumbers = (char**)(new int[iLen]);//经典,这里定义二级指针,strNumbers是指向字符指针的指针,而字符指针又指向每个字符串

3  for(int i = 0 ; i < iLen ; i++)//对每个字符指针new一下,然后写入整数
 {
  strNumbers[i] = new char[MAXLEN + 1];
  sprintf(strNumbers[i],"%d",pArr[i]);//用字符串解决大数问题
4  qsort(strNumbers,iLen,sizeof(char*),compare);
//void qsort(void* buf,size_t num,size_t size,int(*compare)(const void*,const void*)),qsort一半适用于二级字符指针的字符数组时间比较,sort不行
5  for(int k = 0 ; k < iLen ; k++)//注意先删除一级指针,再删除二级指针
 {
  delete[] strNumbers[k];
 }
 delete[] strNumbers;
6 int compare(const void* str1,const void* str2)//qsort比较函数所用形参必须是const void*
7 strcpy(strNum1,*(const char**)str1);//注意,如果改成strcpy(strNum1,(const char*)str1),是不能实现排序的,不知道为什么 ?
 strcat(strNum1,*(const char**)str2);
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;

const int MAXSIZE = 101;
const int MAXLEN = 10;

//int compare(const char* str1,const char* str2)
int compare(const void* str1,const void* str2)//qsort比较函数所用形参必须是const void*
{
 char strNum1[2*MAXLEN + 1];
 char strNum2[2*MAXLEN + 1];
 strcpy(strNum1,*(const char**)str1);//注意,如果改成strcpy(strNum1,(const char*)str1),是不能实现排序的,不知道为什么 ?
 strcat(strNum1,*(const char**)str2);
 strcpy(strNum2,*(const char**)str2);
 strcat(strNum2,*(const char**)str1);
 return strcmp(strNum1,strNum2);
}

void printMinNum(int* pArr,int iLen)
{
 if(!pArr || iLen < 1 || iLen > 100)
 {
  return;
 }
 char** strNumbers = (char**)(new int[iLen]);//经典,这里定义二级指针,strNumbers是指向字符指针的指针,而字符指针又指向每个字符串
 for(int i = 0 ; i < iLen ; i++)//对每个字符指针new一下,然后写入整数
 {
  strNumbers[i] = new char[MAXLEN + 1];
  sprintf(strNumbers[i],"%d",pArr[i]);//用字符串解决大数问题
 }
 //sort(strNumbers,strNumbers + iLen,compare);//采用我们自定义的比较函数进行比较
 qsort(strNumbers,iLen,sizeof(char*),compare);//void qsort(void* buf,size_t num,size_t size,int(*compare)(const void*,const void*)),qsort一半适用于二级字符指针的字符数组时间比较,sort不行
 for(int j = 0 ; j < iLen ; j++)
 {
  printf("%s",strNumbers[j]);
 }
 printf("\n");
 for(int k = 0 ; k < iLen ; k++)//注意先删除一级指针,再删除二级指针
 {
  delete[] strNumbers[k];
 }
 delete[] strNumbers;
}

void process()
{
 int n;
 while(EOF != scanf("%d",&n))
 {
  if(n < 1 || n > 100)
  {
   continue;
  }
  int iArr[MAXSIZE];
  for(int i = 0 ; i < n ; i++)
  {
   scanf("%d",&iArr[i]);
  }
  printMinNum(iArr,n);
 }
 
}

int main(int argc,char* argv[])
{
 process();
 getchar();
 return 0;
}


 


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值