Frage

Ich habe eine Textdatei, die wie folgt aussieht:

name1
1 0 1 0 1
0 1 1 1 0
0 0 0 0 0
name2
1 0 1 0 1
0 0 1 1 0
0 0 0 0 1

d. Folgte ein Klar Etikett durch ein paar Zeilen mit 1/0 durch Leerzeichen getrennt. Die Anzahl der Reihen von 1/0 variabel ist, aber jede Reihe zwischen zwei bestimmten Markierungen soll die gleiche Anzahl von 1/0-en (obwohl könnte möglicherweise nicht) hat.

Wie packe ich jeden Namen + Reihen Brocken mit einem Scanner? Gibt es eine elegante Möglichkeit, die Konsistenz auf der Anzahl der Zeilen (und liefert eine Art von Feedback, wenn sie nicht konsistent sind) zu erzwingen?

Ich denke, es könnte eine bequeme Möglichkeit, mit cleveren Begrenzer-Spezifikation sein, aber ich kann nicht, dass die Arbeit zu bekommen scheinen.

War es hilfreich?

Lösung 2

Noch besser ist, nach einer dienliche Antwort auf eine andere Frage (Danke Bart ):

static final String labelRegex="^\\s*\\w+$";
static final Pattern labelPattern = Pattern.compile(labelRegex, Pattern.MULTILINE);
Matcher labelMatcher = labelPattern.matcher("");

static final String stateRegex = "([10] )+[10]\\s+";
static final String statesRegex = "("+stateRegex+")+";
static final Pattern statesPattern = Pattern.compile(statesRegex, Pattern.MULTILINE);
Matcher stateMatcher = statesPattern.matcher("");

static final String chunkRegex = "(?="+labelRegex+")";
static final Pattern chunkPattern = Pattern.compile(chunkRegex,Pattern.MULTILINE);
Scanner chunkScan;

public void setSource(File source) {
    if(source!=null && source.canRead()) {
     try {
      chunkScan = new Scanner(new BufferedReader(new FileReader(source)));
      chunkScan.useDelimiter(chunkPattern);
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
}

public Map<String, List<GraphState>> next(int n) {
 Map<String,List<GraphState>> result = new LinkedHashMap<String,List<GraphState>>(n);
  String chunk, rows;
  int i=0;
  while (chunkScan.hasNext()&&i++<n) {
    chunk = chunkScan.next().trim();
    labelMatcher.reset(chunk);
    stateMatcher.reset(chunk);
   if (labelMatcher.find()&&stateMatcher.find()) {
    rows = stateMatcher.group().replace(" ", "");
    result.put(labelMatcher.group(), rowsToList(rows.split("\\n")));
   }
  }
  return result;
}

Andere Tipps

Ich würde es die einfache Art und Weise tun. Schnappen Sie jede Zeile als String, und führen Sie es durch, sagen wir, einen regulären Ausdruck, der die Spiele 1-oder-0-Follow-by-Raum-Muster. Wenn es passt, behandeln sie wie eine Reihe. Wenn nicht, behandelt es wie ein Klar Label. Überprüfen Sie, ob die Zeilen-Spalten-Größe Konsistenz nach der Tat durch die Überprüfung, dass jedes Array Etikett von Daten entspricht die Größe des Arrays der ersten Etiketts von Daten.

EDIT: Ich war nicht bekannt, die Scanner Klasse, obwohl es praktisch klingt. Ich denke, die wesentliche Idee noch in etwa gleich sein sollte ... verwenden, um die Scanner Ihre Eingabe zu analysieren und behandelt die Frage der Umfänge selbst.

Auch in der Theorie könnte man einen regulären Ausdruck erzeugt, der das Etikett und das gesamte Array passen würde, obwohl ich weiß nicht, ob Sie eine produzieren können, die garantieren, dass sie paßt nur Sätze von Linien mit der gleichen Anzahl von Werte in jeder Reihe. Aber dann, mehr automatisierte Überprüfung einzurichten, dann würden Sie wahrscheinlich einen zweiten regulären Ausdruck konstruieren müssen, die genau passt die Größe des Arrays des ersten Eintrags, und verwenden Sie es für alle anderen. Ich denke, dies ist ein Fall, wo die Heilung schlimmer als die Krankheit ist.

Sie müßten die Datei und eine Schleife durch jede Zeile mit readline () öffnen, bis Sie das Ende der Datei treffen.

- Ich nehme Sie tun Konsistenz, wie Sie die Datei durchlaufen. Wenn Sie die Informationen gespeichert werden sollen und es später zu verwenden, würde ich irgendeine Art von Datenstruktur prüfen, mit.

Wie Sie diese durchqueren, können Sie die Zeile mit einem einfachen regulären Ausdruck überprüfen, um zu überprüfen, ob es sich um ein Markenname ist. Falls nicht, teilen Sie die Zeile auf der Grundlage der ‚‘ (Leerzeichen), und es wird in einem Array zu Ihnen zurück. Dann die Größe auf eine einheitliche Größe auf Basis überprüfen.

Grund Pseudo-Code:

int consistentSize = 5; // assume you have a size in mind

while ( (line = readLine()) != EOF)
{
    // check for if label, if it's a simple name, you won't really need a regex
    if (line == label)
    {
         // not sure if you want to do any consistency checking in here
    } else {
         String[] currLine = line.split(' ');
         bool consist = true;
         // now loop through currLine and do a check if each character is a number
         for (int i = 0; i < currLine.size(); i++)
         {
            // can't remember java function for this (isNum() I think)
            if (!currLine[i].isNum) { consist = false; break; }
         }
         // if got past this, the row has all numbers, therefore it is ok
            // could easily add another array to keep track of rows that didn't have valid numbers and suhc
         if (currLine.size() < consistentSize) System.out.println("row "+j + " is inconsistent");
    }
}

Sie können auch eine weitere Schleife hinzufügen, wenn Sie nicht wissen, die Größe, die Sie für jede Zeile erwarten und einige Logik setzen in die gängigste Größe zu finden und dann herauszufinden, was nicht übereinstimmt. Ich bin nicht sicher, wie kompliziert Ihre Konsistenz Bedürfnisse Überprüfung sein.

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