涉及算法:拓扑排序
不知道什么是拓扑排序请参照这篇文章 拓扑排序详解
不知道什么是拓扑排序请参照这篇文章 拓扑排序详解
题目大意:要求根据给定的m组字符间的大小关系,给n个字符从小到大排序
题目分析:首先将大小关系转化成为拓扑图,在找入度的时候注意:若没有找到入度为0的点说明出现了环即出现了矛盾;若找到多个入度为0的点则说明大小关系还不能确定,这时还需要继续找入度为0的点因为可能会找到环;若找到一个入度为0的点则继续寻找下一个入度为0的点当找到n个入度为0的点时说明大小关系已经确定
代码如下:
import java.util.Arrays;
import java.util.Scanner;
public class Main
{
static int n,m;
static String[] relations=new String[1000];
static int[][] dis=new int[26][26];
static int[] vis=new int[26];
static char[] c=new char[26];
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
n=in.nextInt();
m=in.nextInt();
while (m!=0 || n!=0)
{
for (int i = 0; i < m; i++)
{
relations[i]=in.next();
}
solve();
n=in.nextInt();
m=in.nextInt();
}
}
private static void solve()
{
fill(dis, 0);
for (int i = 0; i < m; i++)
{
switchToRelation(i);//每次加入一组关系
int topResult=topSort();
switch (topResult)
{
case 0:
System.out.println("Inconsistency found after " +(i+1)+ " relations.");
return;
case 1:
System.out.print("Sorted sequence determined after " +(i+1)+ " relations: ");
for(int j=0;j<n;j++){
System.out.print(c[j]);
}
System.out.println(".");
return;
}
}
System.out.println("Sorted sequence cannot be determined.");
}
private static int topSort()
{
Arrays.fill(vis, 0);
int k=0;
int zeroCount=0;//入度为0的个数
int pos=0;
boolean flag=false;
while (k<n)
{
/**
* 找出入度为0的点
*/
zeroCount=0;
for(int j=0;j<n;j++)
{
if(vis[j]==1) continue;
for(int i=0;i<n;i++)
{
if(vis[i]==1 || dis[i][j]==0)
{
if(i==n-1)//j的入度为0
{
zeroCount++;
pos=j;
}
}
else {//j的入度不为0
break;//换一个j求入度
}
}
}
/**
* zeroCount:
* 0:没有找到入度为0的点,即出现了环
* 1:找到1个入度为0的点,符合要求可以继续找
* 其他:找到多个入度为0的点,关系不确定,但这时不能跳出,因为接下来有出现环的可能
*/
switch (zeroCount)
{
case 0:return 0;
case 1:
vis[pos]=1;
c[k]=(char)(pos+65);
break;
default://不能直接跳出,还需要找到最后看看是否有环
flag=true;
vis[pos]=1;
break;
}
k++;
}
if(flag){
return -1;
}else {
return 1;
}
}
private static void fill(int[][] arr,int a)
{
for(int i=0;i<arr.length;i++)
{
Arrays.fill(arr[i], a);
}
}
//将输入的关系转化为入度
public static void switchToRelation(int k){
String s=relations[k];
if(s.charAt(1)=='>'){
dis[s.charAt(2)-65][s.charAt(0)-65]=1;
}else {
dis[s.charAt(0)-65][s.charAt(2)-65]=1;
}
}
}