题目
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这3个数组能排成的最小数字321323。
思路
(1) 将数组中的每个数字转换成字符串
(2) 定义A、B两个数字的排序规则,如果 AB < BA ,则 A < B
(3) 利用qsort函数,将所有字符串进行排序
(4) 依次打印,最终获取结果
个人想法
怎样将A、B两个数字进行排序? 比如 A=3, B=321,A应该排序在B的后面。
(1)先将A、B两个数字位数对齐,A的位数比B少,少的位上补9: A=399
(2) 比较A、B, 321 < 399 所以 B < A
代码
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int g_MaxNumberLength = 10; // 如果将数字A、B转换成字符串,字符串的最大长度用g_MaxNumberLength表示
char* g_StrCombine1 = new char[g_MaxNumberLength * 2 + 1];
char* g_StrCombine2 = new char[g_MaxNumberLength * 2 + 1];
// 定义排序规则,对于两个数A、B,判断是AB > BA ?
int compare(const void* strNumber1, const void* strNumber2)
{
strcpy(g_StrCombine1, *(const char**)strNumber1);
strcat(g_StrCombine1, *(const char**)strNumber2);
strcpy(g_StrCombine2, *(const char**)strNumber2);
strcat(g_StrCombine2, *(const char**)strNumber1);
return strcmp(g_StrCombine1, g_StrCombine2);
}
void PrintMinNumber(int* numbers, int length)
{
if (numbers == NULL || length <= 0)
return;
char** strNumbers = (char**) (new int[length]); // 定义一个字符串的二级指针,strNumbers包含length条子字符串
for (int i = 0; i < length; ++i)
{
strNumbers[i] = new char[g_MaxNumberLength + 1]; // 记住结束符'\0'
sprintf(strNumbers[i], "%d", numbers[i]); // 将数字转换成字符串
}
/*
qsort 功 能: 使用快速排序例程进行排序
用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针
*/
qsort(strNumbers, length, sizeof(char*), compare); // 快排
for (int i = 0; i < length; ++i)
{
printf("%s", strNumbers[i]);
}
printf("\n");
for (int i = 0; i < length; ++i) // 释放
{
delete[] (strNumbers[i]);
}
delete[] (strNumbers);
}
int main()
{
int nums[] = {3,32,321};
PrintMinNumber(nums, sizeof(nums) / sizeof(int));
return 0;
}