字符串排序 HihoCoder - 1712

题目描述

一般我们在对字符串排序时,都会按照字典序排序。当字符串只包含小写字母时,相当于按字母表"abcdefghijklmnopqrstuvwxyz"的顺序排序。

现在我们打乱字母表的顺序,得到一个26个字母的新顺序:bdceafghijklmnopqrstuvwxyz,代表’b’排在’d’前,'d’在’c’前,'c’在’e’前……

给定N个字符串,请你按照新的字母顺序对它们排序。
输入

第一行包含一个整数N。(1 <= N <= 1000)

第二行包含26个字母,代表新的顺序。

以下N行每行一个字符串S。 (|S| <= 100)
输出

按新的顺序输出N个字符串,每个字符串一行。
样例输入

5
bdceafghijklmnopqrstuvwxyz
abcde
adc
cda
cad
ddc

样例输出

ddc
cda
cad
abcde
adc

思路

题意大概就是,按照指定的新的字典序,对字符串进行排序。这里我将给定的26个英文字符记为neworder。对于这种特殊的字符串排序,我们需要将其进行转换,转换成我们所熟悉的。对于这道题,可以利用c++提供的map容器,用map存题目给出的字典序,然后再开一个结构体来操作要排序的字符串。那么要是我们不熟悉map或者一时没想起来,那么就无解了吗?当然不是,我当时看到这道题时,脑子里第一反应是,这个字符串怎么排,一个一个比较吗?肯定不会这么来做,其实我们可以将给定的待排序的字符串,转换成相对应的在neworder中的下标。举个例子:ddc,d在neworder中的下标为1,c在neworder中的下标为2,那么ddc其实就转换成了112,同样地,其他字符串也可以这样做。转换完成后,我们就可以直接调用sort方法,对转换后的字符串数组(存储的是每个字符在neworder中所对应的下标组成的字符串数组)进行排序就可以了。以测试案例为例:
abcde、adc、cda、cad、ddc 转换后为40213,412、214、241、112
我们对转换后的结果进行排序,结果为:112、214、241、40213、412。最后,我们再将字符串中的各个字符作为neworder的下标,输出对应的元素,就达到了排序的效果了。例如:neworder[1]=d,neworder[2]=c,则112就输出ddc(与前面字符串转下标是互逆的过程)。
注意:上面那个过程有坑 !!! 再将字符串中的字符转下标时,需要注意的是,不能直接将转换后的下标添加为字符串,这样会输出错误的结果,例如:lneworder中的下标为11,转换为字符串为"11",cad转换后为"241",我们如果进行排序,会将"11"转换为两个"1"分别与"241"的第一位和第二位进行比较,会得出错误的排序结果;cad>l,并且在重新转换为原字符串时会出错,"11"会转换为两个dd,并不是我们之前的 l。所有在转换后下标时,为了避免这种情况的出现,我们需要对转换后的下标进行其他转换,将所得下标通过 ‘0’+下标 转换为字符,然后将转换后的字符添加进字符串中,再进行排序,最后将排序结果,逆运算回去就可得到正确的结果。说了这么多,估计看代码来得更实在。
c++代码

#include<iostream>
#include<algorithm>
using namespace std;
//返回该字符在neworder中的下标 
//借鉴了快排中的双指针扫描法 
int indexof(char c,string neworder){
	int left=0;
	int right=neworder.length()-1;
	while(left<right){
		//左右同时遍历 
		if(c==neworder[left]){
			return left;
		}
		if(c==neworder[right]){
			return right;
		}
		left++;
		right--;
	}
}

int main(){
	int N; 
	string neworder;//给定的26个英文字符(指定的字典序) 
	cin>>N;
	cin>>neworder;
	string *str=new string[N];//动态分配内存,存储待排序的字符串 
	for(int i=0;i<N;i++){
		cin>>str[i];
	}
	
	//这里是将待排序的字符串,转换成对应于neworder中的下标 
	for(int i=0;i<N;i++){
		string s="";//用来存储转换后的字符串 
		for(int j=0;j<str[i].length();j++){
			int index=indexof(str[i][j],neworder);//将字符转换为新顺序的下标 
			char c='0'+index;//转换为对应的字符 
			s=s+c;//将转换后的字符添加在字符串s中 
		}
		str[i]=s; //用转换后的字符串将转换前的覆盖掉(可以不用额外开辟空间) 
	}
	//调用sort方法,对str进行排序 
	sort(str,str+N);
	//输出结果,遍历str字符串数组 
	for(int i=0;i<N;i++){
		for(int j=0;j<str[i].length();j++){
			cout<<neworder[str[i][j]-'0'];//与前面转下标的过程是互逆的 
		}
		cout<<endl;
	}
	delete []str;//释放内存空间 
	return 0;
}

结果截图

发布了2 篇原创文章 · 获赞 0 · 访问量 10

猜你喜欢

转载自blog.csdn.net/weixin_43862144/article/details/105123535