Frage

Meine Java ist extrem rostig und ich bin versucht, stecken eine Benutzeroberfläche zu machen, die die Ausführung von Shell-Skripten oder Batch-Dateien je nachdem, ob bzw. es Linus oder Win32 vereinfacht. Die Dateien haben folgende Namenskonvention.

  module-verb-object-etc [args-list]
  mysql-connect-grid
  mysql-connect-rds
  mysql-dump-grid
  mysql-dump-grid-se314

schließlich möchte ich es eindeutige Begriffe zu analysieren, so ich kann:

  1. tokenize die Befehle (zB begrenzt durch „-“) und verkürzen sie in vereinfachter Begriffe wie Befehl FoxPros soemthing Fenster oder Ciscos IOS (zB „mein Co gr“ führt eine „mysql-connect-grid“ in Unix und * .cmd in win32)
  2. und auch im Stil von IOS ermöglicht es dem Benutzer abgekürzte Befehle einzugeben, so dass sie in einem Fragezeichen eingeben können (?) Und es wird ihnen einen Hinweis auf die einzigartigen verbleibenden (oder nächsten) Befehlsoptionen (zB " meine?“, gibt mySQL & "meine?" kehrt zu verbinden, oder Dump). Othr Rückgabewerte würden „mehrdeutig“ oder „unbekannt“ für Befehle, die nicht eindeutig sind oder nicht zugeordnet werden konnten. Es mag trivial erscheinen, aber es gibt viele Hunderte von Befehlen in jedem Ordner und meine Nutzer wollen nicht denken ...

schrieb ich eine Funktion, um die Liste der Dateien aus einem Verzeichnis zu ziehen und eine Reihe von fileanmes retun. Dann wandeln I, das in ein 2-dimensionales Array unter Verwendung des Verfahrens, unter dem ein dynamicly Größe Gitter von möglichen Befehle liefert.

    /**********************************************************************************
     *  MAKE GRID: Parses array of filenames and tokenizes AWS cmds.
     * @param strs  Array of filenames
     **********************************************************************************/
     public static String [][] makeGrid(String strs[], boolean bPrint) {
       String tmpGrid[][];
       int nMaxCols = 0;
       int nRows = uniqueCount(strs);
       int nGridRow = 0; 
       tmpGrid = new String [nRows][]; 
       for (int nRow=0; nRow<nRows; nRow++) { 
 String cFilename = strs[nRow];
                if (!cFilename.endsWith(".cmd") // just list unix files (filter for batch files)
    && cFilename.indexOf("-") > 0 ) // make sure there's a dash in the filename
    {
           String strTokens[] = tokenize(strs[nRow], "-"); // the dash is our token deliminator
           int nCols = strTokens.length; 
           if (nCols>nMaxCols) nMaxCols=nCols;
           tmpGrid[nGridRow] = new String [nCols];
           for (int nCol=0; nCol<nCols; nCol++) { 
               tmpGrid[nGridRow][nCol] = strTokens[nCol];
               if (bPrint) System.out.print(" "+tmpGrid[nGridRow][nCol]);
             }
            nGridRow++;
            if (bPrint) System.out.println("");
     } //end-if
         }
       String[][] cmdGrid = new String[nGridRow][nMaxCols];
       System.arraycopy(tmpGrid, 0, cmdGrid, 0, nGridRow); // removes null rows  (&NPEs!)
       return cmdGrid;
      }

Dies gibt eine 2-D-Matrix (siehe unten), so ist grid[Row-N][Col-0] eine Übereinstimmung. Ich möchte nur unterschiedliche Werte ziehen, wo row[0] ein Wildcard-Spiel für cmdToken[0] && row[1] ist, „wie“ cmdToken[1] so, dass meine Benutzer zusammen, bis "my du gr ?" kehrt "ENTER, [se314]" einen Befehl Stück kann - wenn das Sinn macht ...

String[][] makeGrid:
    mysql dump grid se314
    mysql connect grid
    mysql dump grid
    mysql connect rds

Meine Challenge: Ich kann nicht scheinen, meinen Kopf um meine Matcher-Funktion in Java zu erhalten. Wenn es SQL ist wäre es so etwas wie:

"SELECT DISTINCT col2 FROM cmd_Grid
   WHERE col1 LIKE 'cmdToken1%' " 

oder noch besser: rekursiv einen int depthmark für jede aufeinanderfolgende Spalte Einstellung

`SELECT DISTINCT col+str(depthmark+1) FROM cmd_Grid 
    WHERE col+str(depthmark) LIKE 'cmdMatchedTokens%' " 

, bis Sie haben eine genaue Übereinstimmung.

fand ich ein Paket namens joSQL, dass ich versuchte, die Verzweiflung, aber ich kann nicht scheinen, um es zu der Arbeit in Java6 zu bekommen. Wie dem auch sei: Ich hatte gehofft, dass auch für eine reine Java-Lösung, so dass alles in einer einzigen Klasse enthalten sein könnte ...

Vielleicht ist meine multidimentional Array für eindeutige Werte mit Scanner oder etwas zu analysieren ... Ich weiß, dass ich wahrscheinlich mache es viel komplizierter, als es sein muss.

ein sanfter Schub in der richtigen Richtung würde geschätzt.

TIA

War es hilfreich?

Lösung

Eine umfassende Lösung könnte sein, ein HashMap contruct so dass der Schlüssel ein möglicher Kurzbefehl wie ‚meinen Co gr ist“ und der entsprechende Wert ‚mysql-connect-grid‘. So würde es Werte in der Hash-Karte sein, die "mysql-connect-grid" als Wert haben wird.

Das ist aber eine machbare Lösung nur, wenn es eine endliche Anzahl von möglichen Schlüsseln ist. Wenn das nicht der Fall ist, dann können Sie die in String-Parsing Methoden gebaut verwenden.

Zum Beispiel:

    String[][] makeGrid = new String[][]{{"mysql", "dump", "grid", "se314"}, 
              {"mysql", "connect", "grid", ""},
              {"mysql",  "dump", "grid", ""},
              {"mysql", "connect", "rds", ""}
              };
     String[] query2 = new String[]{"my", "du", "gr"};

  String[][] matchingCommands = new String[4][4];
  int resultSize = 0;
     for(int i=0; i<makeGrid.length; i++)
  {
      String[] commandColumn = makeGrid[i];
   boolean matches = false;
      for(int cnt=0; cnt<commandColumn.length; cnt++)
      {
       String commandPart = commandColumn[cnt];
       if(cnt < query2.length){
        String queryPart = query2[cnt];
     if(commandPart.startsWith(queryPart) || queryPart.equals("?")){
         matches = true;
        }else{
         matches = false;
         break;
        }
       }
      }
      if(matches){
       matchingCommands[resultSize] = commandColumn;
       resultSize++;
      }
  }

Dieser Code-Schnipsel sollten Sie eine Vorstellung davon geben, wie man das macht. Es ist eine Sache, hier allerdings zu beachten. Die matchingCommands Array hat die 4 Zeilen und 4 Spalten initialisiert worden, die verschwenderisch ist, weil die Spiele weniger sein wird als das. Lassen Sie mich wissen, wenn Sie Hilfe machen diese effizienter benötigen. Ansonsten ist dies ein Arbeits Stück Code, das ich denke, das tut, was Sie wollen.

Andere Tipps

Sie könnten auch in aussehen einige erweiterte Datenstrukturen wie eine Arraylist anstelle eines Arrays verwenden und mit Hilfe der StringTokenizer jeden Befehl Part on the fly zu erzeugen.

Es wird so etwas wie diese:

ArrayList<String> matchingCommands = new ArrayList<String>();

    ArrayList<String> commandList = new ArrayList<String>();
    commandList.add("mysql dump grid se314");
    commandList.add("mysql connect grid");
    commandList.add("mysql dump grid");
    commandList.add("mysql connect rds");

    String queryCommand = "my du gr ?";

    for(int i=0; i<commandList.size(); i++)
    {
        boolean matches = false;
        String command = commandList.get(i);
        StringTokenizer commandTokenizer = new StringTokenizer(command, " "); // Using space as the deliminator
        StringTokenizer queryTokenizer = new StringTokenizer(queryCommand, " "); // Using space as the deliminator

        while(commandTokenizer.hasMoreTokens())
        {
            String queryPart = queryTokenizer.nextToken();
            String commandPart = commandTokenizer.nextToken();
            if(commandPart.startsWith(queryPart) || queryPart.equals("?")){
                matches = true;
            }else{
                matches = false;
                break;
            }
        }
        if(matches){
            matchingCommands.add(command);
        }
    }
    System.out.println(matchingCommands);

Dies würde sicherstellen, dass Ihr Programm dynamisch wachsen kann, und es gibt keine Verschwendung von Speichern wegen null entweder Objekte.

jetzt war ich Herumspiele mit jeder Befehlszeichenfolge Parsen (Query) für white-space Begrenzer & Zeichenüber das Array. So etwas wie:

 Scanner sCmdString = new Scanner(cInput);
 while (sCmdString.hasNext()) { 
 String cToken = sCmdString.next().toUpperCase().trim();
 System.out.println(" "+cToken+" ");
 // match cmdString[i..n] to cmdGrid
 for (int nRow=0; nRow < cmdGrid.length; nRow++) {
       for (int nCol=0; nCol < cmdGrid[nRow].length; nCol++) {
  if (cmdGrid[nRow][nCol].equalsIgnoreCase(cToken) )
     System.out.println("MATCH: "+cmdGrid[nRow][nCol]);
  else System.out.println("NO MATCH:"+cmdGrid[nRow][nCol].toUpperCase()+":"+cToken+"...");
        }
   }
   }

, aber ich war NPE mit den ungeraden Zeilenlängen zu bekommen.

Und ich mag Ihre Idee Abflachen der Spalten aus.

Ich glaube, ich würde immer noch um Duplikate zu entfernen habe ... nein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top