问题:假设某字符串str=“ABBBA”,只由字母A,B组成,且无规律,只要求长度大于0,长度合理范围内不限。
str1=”ABBBA”,不同字母之间接触的次数是2次;
str2=”ABABA”,不同字母之间接触的次数是4次;
str1=”ABBAA”,不同字母之间接触的次数是2次;
要使接触的次数最少,就要移动字母,比如str2=”ABABA”,相邻的两个字母互换一次,也就是移动一次,并且只有相邻的字母才能互换,那么str2=”ABABA”→“AAABB”移动了3次,过程为:
ABABA→ABA*AB*→A*AB*AB→AA*AB*B(星号引着的是互换的两个字母)。
要求:用最少的移动次数,使接触次数最少。
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请无序连续输入A,B若干个,中间无空格隔开:");
String str=sc.nextLine();
int lengh=str.length();
int times_left=0;//记录将全部A移到左边所需要的接触次数
int times_right=0;//记录将全部A移到右边所需要的接触次数
int times_A=0;//记录目前A的个数
int sign_A=-1;//记录目前遍历到的位置
//把A移到左边
for(int i=0;i<lengh;i=sign_A+1){
sign_A=str.indexOf('A',i);//从i开始查找,返回当前A的在字符串中的下标
if(sign_A==-1)//没有'A'则退出循环
break;
//某个A要移到正确的位置需要移动搞得次数是它前面B的个数
times_left+=sign_A-times_A;//sign_A-times_A也就是前面有多少个B
times_A++;//查找到一个A就加1
}
times_A=0;
sign_A=lengh;
//把全部A都移到右边
for(int i=lengh-1;i>=0;i=sign_A-1){
sign_A=str.lastIndexOf('A',i);//从字符串的i位置向前(左)查找。
if(sign_A==-1)
break;
//因为返回的sign是正序的,所以要lengh-1-sign_A得到倒序的下标
times_right+=lengh-1-sign_A-times_A;
times_A++;
}
//下面判断哪个比较小,并且输出移动后的字符串
if(times_left>times_right){
for(int i=0;i<times_A;i++)
System.out.print("B");
for(int i=0;i<lengh-times_A;i++)
System.out.print("A");
System.out.println();
System.out.println(times_right);
}
else{
for(int i=0;i<times_A;i++)
System.out.print("A");
for(int i=0;i<lengh-times_A;i++)
System.out.print("B");
System.out.println();
System.out.println(times_left);
}
}
}
结果实例:
思路:接触最少不就是把两种字母分别放到左边或者右边,那么到底是A放左边还是右边,我直接两种情况都算一下,选移动次数小的,我没看出规律,只会这么写。