conor tighe.
conor tighe.

Reputation: 123

Is there a way to move columns in a 2d array matrix?

I want to take the following matrix below and rearrange the chars TOAD to ADOT and the rearrange the corresponding columns below to where the char above moved, so for example A moved to col 0 so now VGD should all be in col 0 etc.

TOAD is a separate array by the way! im using that keyword to sort the martrix alphabetically.

    T O A D 
    V V V X 
    D V G G 
    D F D V 

I've gotten this far, basically all I want to know is if A Moves to the start how do I make the whole column below move with it?

public class CipherKey {

Scanner write = new Scanner (System.in);
Matrix polyCipher;
private final char[] PHRASE_KEY = { 'J', 'A', 'V', 'A'};
String[][] matrixStore = new String[PHRASE_KEY.length][PHRASE_KEY.length];
String outmrk = "|";
String inmrk = ",";
CipherKey(Matrix m) {
    polyCipher = m;
}


public void assembleMatrix()  { 

    String s = matrixFormatter(polyCipher.getTranslation());
    matrixStore = buildMatrix(s,outmrk,inmrk);
    System.out.print(printMatrix(matrixStore));
    System.out.print(sortMatrix(matrixStore));


}


public String printMatrix(String s [][]){
    char key[] = polyCipher.getKeyword().toCharArray();
    String keyOut = "";
    for(int i=0;i<key.length;i++){
        keyOut += key[i] + " ";
    }
    keyOut += "\n";
    for (int i = 0; i < s.length; i++) {
   //     keyOut += PHRASE_KEY[i] + " ";
       for (int j = 0; j < s[i].length; j++) {
            keyOut += s[i][j] + " ";
        }
        keyOut += "\n";
    }
    return keyOut.toUpperCase();
}

public static String [][] buildMatrix (String translation, String outermarker, String innermarker) {
    // outerdelim may be a group of characters
    String [] sOuter = translation.split("[" + outermarker + "]"); 
    int size = sOuter.length;
    // one dimension of the array has to be known on declaration:
    String [][] result = new String [size][size]; 
    int count = 0;
    for (String line : sOuter)
    {
        result [count] = line.split (innermarker);
        ++count;
    }
    return result;
}

Here is the part im having trouble with:

public String sortMatrix(String a [][]){

    System.out.println("\nAlphabetically rearranged: ");
    char[] key = polyCipher.getKeyword().toCharArray();
    char[] alphaKey = polyCipher.getKeyword().toCharArray();
    String alphaOut = "";
    for(int i=0;i<alphaKey.length;i++){
        alphaOut += alphaKey[i] + " ";
    }

        char[][] x = new char[4][36];
        x[0] = new char[]{key[0], key[1], key[2], key[3]};
        x[1] = new char[]{'V', 'V', 'V', 'X'};
        x[2] = new char[]{'D', 'V', 'G', 'G'};
        x[3] = new char[]{'D', 'F', 'D', 'V'};

        String [] strArray = new String[x[0].length];

        for (int loop1 = 0; loop1 < x.length; loop1++){
            for (int loop2 = 0; loop2 < x[0].length; loop2++){
                if(strArray[loop2] == null){
                    strArray[loop2] = "";
                }
                strArray[loop2] += x[loop1][loop2];
            }
        }

        Arrays.sort(strArray);

        alphaOut += "\n";
        for (int i = 0; i < strArray.length; i++) {
       //     keyOut += PHRASE_KEY[i] + " ";
           for (int j = 0; j < s[i].length; j++) {
               alphaOut += s[i][j] + " ";
            }
           alphaOut += "\n";
        }
        alphaOut.toUpperCase();


}


public String matrixFormatter(String x){

     String resultstr = "";
      int i = 0;
      while(i < x.length()) {
        // If end of string: only add character.
        if (i == x.length() - 1) {
          resultstr += x.substring(i, i + 1);
        } else {
          if ( ((i + 1) % 4) == 0) {
            resultstr += x.substring(i, i + 1)  + "|";
          } else {
            resultstr += x.substring(i, i + 1)  + ",";
          }
        }
        i++;
      }
      return resultstr;

}

}

Upvotes: 0

Views: 3226

Answers (3)

Anshuman
Anshuman

Reputation: 841

To do so, you will have to track the movement and move other elements accordingly. But looking at your program, I can see that you are relying on java API for sorting.

If you want to continue to do so, I can give you a small trick which will work for you.

Step 1: Define your arrays:

    char[][] x = new char[4][4];
    x[0] = new char[]{'T', 'O', 'A', 'D'};
    x[1] = new char[]{'V', 'V', 'V', 'X'};
    x[2] = new char[]{'D', 'V', 'G', 'G'};
    x[3] = new char[]{'D', 'F', 'D', 'V'};

Step 2: Convert it to single dimensional string array concatenating the character vertically.

    String [] strArray = new String[x[0].length];

    for (int loop1 = 0; loop1 < x.length; loop1++){
        for (int loop2 = 0; loop2 < x[0].length; loop2++){
            if(strArray[loop2] == null){
                strArray[loop2] = "";
            }
            strArray[loop2] += x[loop1][loop2];
        }
    }

Step 3: Sort your string array

    Arrays.sort(strArray);

Step 4: convert it back to char array

    for (int loop1 = 0; loop1 < strArray.length; loop1++){
        for (int loop2 = 0; loop2 < strArray[loop1].length(); loop2++){
            x[loop2][loop1] = strArray[loop1].charAt(loop2);
        }
    }

This should do the trick.

EDIT: Assuming that you have to switch the places of String a [][] based on the positioning of char[] alpha, you will have to transform it to a char[][] array like I did below:

    char[] alpha = {'T', 'O', 'A', 'D'};
    String a [][] = {{"V", "V", "V", "X"},{"D", "V", "G", "G"},{"D", "F", "D", "V"}};

    char[][] x = new char[a.length+1][];
    x[0] = alpha;

    for(int loop1 = 0; loop1 < a.length; loop1++){
        x[loop1+1] = new char[a[loop1].length];
        for (int loop2 = 0; loop2 < a[loop1].length; loop2++){
            x[loop1+1][loop2] = a[loop1][loop2].charAt(0);
        }
    }

this will covert your two arrays to one 2-dimensional array on which you can run the rest of the steps:

char[][] x = new char[4][4];
x[0] = new char[]{'T', 'O', 'A', 'D'};
x[1] = new char[]{'V', 'V', 'V', 'X'};
x[2] = new char[]{'D', 'V', 'G', 'G'};
x[3] = new char[]{'D', 'F', 'D', 'V'};

Upvotes: 1

egracer
egracer

Reputation: 362

Transpose your data so that the rows as represented above become columns and vice versa. Since a 2 dimensional array is an array of arrays, you want each sub-array to contain all of the characters in a column. Then you can write a function to sort the sub-arrays by the content of each sub-array's first index.

    char[][] unsorted = new char[4][4];
    unsorted[0] = new char[]{'T', 'V', 'D', 'D'};
    unsorted[1] = new char[]{'O', 'V', 'V', 'F'};
    unsorted[2] = new char[]{'A', 'V', 'G', 'D'};
    unsorted[3] = new char[]{'D', 'X', 'G', 'V'};

    // Now sort unsorted[0] through unsorted[3] by the entries at unsorted[i][0]

You can write a simple Comparator class and use the public static <T> void sort(T[] a, Comparator<? super T> c) method in java.util.Arrays. Or write a simple insertion sort.

Upvotes: 0

Joop Eggen
Joop Eggen

Reputation: 109613

As a matrix is an array (the rows) of arrays (the columns), it is better to first transpose your data. Then switching rows (the earlier columns) can be done efficiently:

void switchRows(String[][] a, int i, int j) {
    String[] temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

Transposing means a[i][j] should be filled as old a[j][i].

Also maybe you might consider using char instead of String.

Upvotes: 0

Related Questions