兩字母交叉最少問題

問題:假設某字符串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放左邊還是右邊,我直接兩種情況都算一下,選移動次數小的,我沒看出規律,只會這麼寫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章