首页 > 试题广场 >

数串

[编程题]数串
  • 热度指数:99974 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
设有n个正整数,将他们连接成一排,组成一个最大的多位整数。
如:n=3时,3个整数13,312,343,连成的最大整数为34331213。
如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613。

输入描述:
有多组测试样例,每组测试样例包含两行,第一行为一个整数N(N<=100),第二行包含N个数(每个数不超过1000,空格分开)。


输出描述:
每组数据输出一个表示最大的整数。
示例1

输入

2
12 123
4
7 13 4 246

输出

12312
7424613
#include <iostream>
#include <algorithm>
using namespace std;
bool campare(string i ,string j){
    return (i+j)>(j+i);
}
int main(){
    int n;
    while(cin>>n){
        vector<string>temp(n,"");
        for(int i = 0 ; i < n ; ++i){
            cin>>temp[i];
        }
        sort(temp.begin(),temp.end(),campare);
   	    for(int i = 0 ; i < n;++i)
                cout<<temp[i];
  	    cout<<endl;
    }
    return 0;
}

编辑于 2017-09-11 16:19:39 回复(3)

看到大家都使用了Collections类,我说一下我的解法(除了scanner,没有import任何东西)。
首先,本题可以理解为对N个数进行排序,只不过排序的标准不是数值的大小,而是两个字符串组合到一起转化成整形后的数值大小,所以只需要随便采用一种排序方法,在比较大小时改成比较字符串组合的大小就行。
话不多说,上代码:

import java.util.Scanner;

/**
 * Created by kevin on 17-9-5.
 * Mail: chewenkaich@gmail.com
 */
public class Main {

    public static void main(String[] args) {
        // 获取输入
        Scanner in = new Scanner(System.in);
        int count = Integer.valueOf(in.nextLine().trim());
        if (count > 100) return;
        String inStr = in.nextLine().trim();
        String[] dataStr = inStr.split(" ");
        int[] data = new int[dataStr.length];
        for (int i = 0; i < dataStr.length; i++) {
            data[i] = Integer.valueOf(dataStr[i]);
        }

        // 此处为一个冒泡排序,也可以使用其他快排,归并等其他高效排序方法
        for (int pass = data.length - 1; pass >= 0; pass--) {
            for (int i = 0; i < pass; i++) {
                if (!is1stBiggerThan2nd(data[i], data[i + 1])) { // 第i个数“小于”第i+1个数
                    int tem = data[i + 1];
                    data[i + 1] = data[i];
                    data[i] = tem;
                }
            }
        }

        // 输出结果
        String result = "";
        for (int each : data) {
            result += String.valueOf(each);
        }
        System.out.println(result);
    }

    /**
     * 从两个整数组合起来较大时,其中的第一个整数,例如,
     * a=3489, b=3423
     * 因为a组合b = 34893423 > b组合a = 34233489,所以返回a
     *
     * @param a
     * @param b
     * @return true, a+b > b+a; false, a+b < b+a
     */
    static boolean is1stBiggerThan2nd(Integer a, Integer b) {
        if (Integer.valueOf(String.valueOf(a) + String.valueOf(b)) > Integer.valueOf(String.valueOf(b) + String.valueOf(a)))
            return true;
        else return false;
    }
}

最终程序运行结果如下
运行时间:169ms
占用内存:13040k
如果有任何问题,欢迎指正。

发表于 2017-09-05 19:43:53 回复(3)
import java.util.*;

/**
 * 
 * @author 何嘉龙
 *
 */
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while (in.hasNext()) {
			int n = in.nextInt();
			List<Integer> list = new ArrayList<>();
			for (int i = 0; i < n; i++) {
				list.add(in.nextInt());
			}
			Collections.sort(list, new Comparator<Integer>() {

				@Override
				public int compare(Integer o1, Integer o2) {
					String s1 = String.valueOf(o1);
					String s2 = String.valueOf(o2);
					return (s2 + s1).compareTo(s1 + s2);
				}
			});
			for (int i = 0; i < list.size(); i++) {
				System.out.print(list.get(i));
			}
			System.out.println();
		}
	}
}
编辑于 2017-08-16 21:09:01 回复(21)
//其实这就是个字符串的冒泡排序,如果字符串A+B>B+A那么认为A>B
//以此为准则,采用冒泡排序的方法将字符串按大小排序,然后输出就可以了 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	int i,j;
	int num=0;
	char data[100][5]={'\0'};
	char tempa[7]={'\0'},tempb[7]={'\0'},temp[5]={'\0'};
	scanf("%d",&num);
	for(i=0;i<num;i++)
	{
		scanf("%s",data[i]);
	}
	strcpy(temp,data[0]);
	for(i=0;i<num;i++)
	{
		for(j=i+1;j<num;j++)
		{
			strcpy(tempa,data[i]);
			strcat(tempa,data[j]);
			strcpy(tempb,data[j]);			
			strcat(tempb,data[i]);
			if(strcmp(tempa,tempb)<0)
			{
				strcpy(temp,data[j]);
				strcpy(data[j],data[i]);
				strcpy(data[i],temp);
			}
		}
        printf("%s",data[i]);
	}
	system("pause");
	return 0;
} 


编辑于 2018-06-20 14:49:01 回复(17)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
bool cmp(const string &a, const string &b) {
    string l = a, r = b;
    int i=0;
    //如果两个字符串长度不同,则将另一个字符穿的前缀补到尾部
    if(l.size() < r.size())
        while(l.size() < r.size()) l += r[i++];
    else 
        while (l.size() > r.size()) r += l[i++];
    //降序排列
    return l >= r;
}
int main() {
    int N;
    while (cin >> N) {
        vector<string> num(N);
        for (int i = 0; i<N; ++i) cin >> num[i];
        sort(num.begin(), num.end(), cmp);
        for (auto c : num) cout<<c;
        cout << endl;
    }
}

编辑于 2017-07-04 20:31:51 回复(3)

自己写cmp函数 即将两个数前后位置不同的两种情况比较

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;
vector<string> ve;
int cmp(string a, string b){
    long  x = atol((a + b).c_str());
    long  y = atol((b + a).c_str());
    if(x < y) return 1;
    return 0;
}

int main(){
    int n;
    while(scanf("%d", &n) == 1){
        ve.clear();
        string s;
        for(int i = 0; i < n; i++){
            cin>>s;
            ve.push_back(s);
        }
        sort(ve.begin(), ve.end(), cmp);
        for(int i=ve.size()-1;i>=0;i--) cout<<ve[i];
        cout<<endl;
    }
}
发表于 2018-10-03 21:22:15 回复(0)
//纯粹的C语言,大致思路是将两个字符串按两种方式拼接,判断哪个在前面大,然后将字符串排序,从而转化为排序问题
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char a[110][1100];
int min(int a,int b)
{
    if(a>b)    
       return b;
       return a ;
}
int cmp(int x,int y)
{
    char b[1000],c[1000];//本来我在这里想直接对字符串a操作的,但是呢a是全局变量,后面还要输出
    strcpy(b,a[x]);
    strcpy(c,a[y]);
    int i,n1,n2;
     char str[1000];
     n1=strlen(a[x]);
     n2=strlen(a[y]);
     //字符串拼接
     for(i=n1;i<=n1+n2;i++) 
         b[i]=c[i-n1];
    for(i=n2;i<n1+n2;i++)
        c[i]=b[i-n2];
        c[i]='\0';
    return strcmp(b,c);
 } 
 int main(void)
 {
     int n,i,j;
     char jiaohuan[1000];
     while(~scanf("%d",&n))
     {
         for(i=0;i<n;i++)
             scanf("%s",a[i]);
         for(i=0;i<n-1;i++)
         {
             for(j=i+1;j<n;j++)
             if(cmp(i,j)<0)
             {
                 strcpy(jiaohuan,a[i]);
                 strcpy(a[i],a[j]);
                 strcpy(a[j],jiaohuan);
             }
         }
         for(i=0;i<n;i++)
             printf("%s",a[i]);
         printf("\n");
     }
     return 0;
 }
发表于 2017-12-13 00:57:29 回复(1)
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>

const int N = 100;
const int MaxLen = 3;

char num1[MaxLen+1];
char num2[MaxLen+1];

char buf1[2*MaxLen+1];
char buf2[2*MaxLen+1];

int myCompare(const void* n1, const void* n2) {
	sprintf(num1, "%d", *(int*)n1);
	sprintf(num2, "%d", *(int*)n2);

	strcpy(buf1, num1);
	strcat(buf1, num2);

	strcpy(buf2, num2);
	strcat(buf2, num1);

	return strcmp(buf1, buf2);
}

int main() {
	int n = 0;
	int buf[N];
	while (std::cin >> n) {
		for (int i = 0; i < n; ++i) {
			std::cin >> buf[i];
		}
		qsort(buf, n, sizeof(int), myCompare);
		for (int i = n-1; i >= 0; --i) {
			std::cout << buf[i];
		}
		std::cout << "\n";
	}
}
发表于 2017-08-28 19:51:49 回复(0)

将所有数字转化为字符串,并将所有字符串按照字典序从大到小输出即可
注意:
字符串a为字符串b的前缀时为特殊情况,例如:a=82,b=821,此时b的字典序大于a。但显然,要将a先于b输出。
这种特殊情况的判断方法为,若b除去前缀a的剩余部分的字典序小于b,则将a先于b输出,否则仍然按照正常字典序输出。

发表于 2017-06-28 21:12:42 回复(5)
if __name__ == '__main__':
    n = raw_input()
    arr = raw_input().split()
    print ''.join(sorted(arr, lambda x, y : -cmp(x+y, y+x)))
提供一个正常人都能看懂的方法,其他语言也都有这几个函数。简单又粗暴
编辑于 2017-08-11 15:33:17 回复(6)

分享一个很好理解的冒泡算法,python3.5,因为我自己不会用cmp,所以就用了这个笨一点的办法

N = int(input())
nums = list(map(str,input().split()))
for i in range(len(nums)):
    for j in range(1,len(nums)-i):
        if nums[j-1]+nums[j] < nums[j]+nums[j-1]:
            nums[j-1],nums[j] = nums[j],nums[j-1]
res = int("".join(nums))
print(res)
编辑于 2018-09-05 19:10:27 回复(2)


import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;


public class Main{
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()){
            int n = in.nextInt();
            ArrayList<Integer> als = new ArrayList<Integer>();
            for (int i = 0; i < n; i++) {
                 als.add(in.nextInt());
            }
            als.sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    String a = String.valueOf(o1);
                    String b = String.valueOf(o2);
                    return (b + a).compareTo(a + b);
                }
            });

            for (Integer i:
                 als) {
                System.out.print(i);
            }
            System.out.println();
        }
    }
}
发表于 2017-08-08 10:29:54 回复(8)
Python3 不用任何import的版本, 使用内置比较函数。
class Str(str):
    def __lt__(self, other):
        return str.__lt__(self + other, other + self)

while True:
    try:
        n = int(input())
        a = list(map(Str, input().rstrip("\n").split()))
        print(int("".join(sorted(a, reverse=True))))
    except:
        break


编辑于 2018-10-05 18:27:53 回复(0)
while(n=readline()){
    n = parseInt(n);
    line = readline();
    arr = line.split(' ');
    arr.sort(function(a,b){
        return (b+a)-(a+b);
    }); 
    print(arr.join(''))
}
用js写也是很简单。。。
主要就是排序的依据应该是 两个数字和的大小 a+b和b+a的结果哪个大就排前面
编辑于 2018-05-11 11:23:35 回复(1)


//一句话:字符串的冒泡排序;和数组的排序区别在于:以前是比较前后数字大小,现在比较前后数字,不同顺序合并后
//的大小
import java.util.*;
class Solusion{
    public void sort_num(String []str){
        int n = str.length;
        if(n <= 1) System.out.print(str[0]);
        else
        {
            String temp;
            for(int i = 0; i < n; i ++){
                for(int j = 0; j < n - i -1; j ++){
                    if( Integer.valueOf( str[j] + str[j + 1] ) > 
                        Integer.valueOf( str[j + 1] + str[j] ) ){

                        temp = str[j];
                        str[j] = str[j + 1]; 
                        str[j + 1] = temp;

                    }
                }
            }
            for(int i = n - 1; i >= 0;i --)
                System.out.print(str[i]);
            System.out.println();
        }
    }
}
public class Main{
    public static void main(String []args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            String []str1 = new String[n];
            for(int i = 0 ; i < n ;i ++)
                str1[i] = sc.next();
            Solusion solusion = new Solusion();
            solusion.sort_num(str1);
            
        }
    }
}


发表于 2018-12-04 15:52:26 回复(0)
#include "bits/stdc++.h"
using namespace std;
const int MAXN=100+5;
int num[MAXN];
bool cmp(int a,int b)
{
    char x[]="111111",y[]="111111";
    sprintf(x,"%d%d",a,b);
    sprintf(y,"%d%d",b,a);
    if(strcmp(x,y)>0)
        return true;
    return false;
}
int main()
{
    int N=0;
    while(cin>>N)
    {
        for(int i=0;i<N;i++)
            cin>>num[i];
        sort(num,num+N,cmp);//特殊排序
        for(int i=0;i<N;i++)
            cout<<num[i];
        cout<<endl;
    }
    return 0;
}

编辑于 2018-10-31 23:50:12 回复(0)

好想用 javascript 来写这个题目怎么办 :)
可是连题目都看不懂好气啊
是这样吗:

function get(ns){
return +(ns.join('').split('').sort().reverse().join(''))
}
get(['12','123'])
编辑于 2018-09-12 00:00:24 回复(0)
C++11真的是骚操作
#include<bits/stdc++.h>
using namespace std;
static bool cmp(string s1,string s2){
    return (s1+s2)>(s2+s1);
}
int main(){
    int n;
    cin>>n;
    int i;
    vector<string> s;
    for(i=0;i<n;i++){
        string tmp;
        cin>>tmp;
        s.push_back(tmp);
    }
  sort(s.begin(),s.end(),cmp);
    string q="";
    for(i=0;i<s.size();i++)
        q+=s[i];
    cout<<q<<endl;
}
发表于 2018-08-29 19:36:34 回复(0)

include<iostream>

include<vector>

include<math.h>

using namespace std;
int main()
{

int m = 0;
cin >> m;
vector<int> n(m);//存取每个数字
vector<int> o(m,1);//存取每个数字的位数
vector<int> f(m, 0);//存取每个数字的首位数
for (auto &a : n)
{
    cin >> a;
}
int b = 0;
for (int i = 0; i < m; i++)
{
    b = n[i];
    if (b < 10)
    {
        f[i] = b;
    }
    while (b >= 10)
    {
        b = b / 10;
        f[i] = b;
        o[i]++;
    }
}
int p = 0;
for (int u = 0; u < m; u++)
{
    for (int i = 0; i < m - u - 1; i++)
    {
        if (n[i] * pow(10, o[i + 1]) + n[i + 1]>n[i + 1] * pow(10, o[i]) + n[i])//判断相邻两位拼接的顺序
        {
            p = f[i];
            f[i] = f[i + 1];
            f[i + 1] = p;

            p = o[i];
            o[i] = o[i + 1];
            o[i + 1] = p;

            p = n[i];
            n[i] = n[i + 1];
            n[i + 1] = p;
        }
    }
}
for (int i = m - 1; i >= 0; i--)
{
    cout << n[i];
}
cout << endl;
return 0;

}
运行时间:4ms
占用内存:480k

发表于 2018-08-13 00:20:25 回复(0)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt())
        {
            int n = sc.nextInt();
            
            List<String> list = new ArrayList<>();
            while (n-- != 0)
                list.add(sc.next());
            
            Collections.sort(list, (str1, str2) -> (str2 + str1).compareTo(str1 + str2));
            for (String s : list)
                System.out.print(s);
            
            System.out.println();
        }

        sc.close();
    }
}

发表于 2018-08-04 21:52:23 回复(0)