Muster in Array suchen

iTutHD

Mitglied
Hallo,
Ich habe folgendes Problem:
ich habe ein 2D Array a und ein 2D Array b, nun möchte ich schauen ob es eine stelle gibt(und wenn ja wo) das Array b in seiner Form im Array a vorkommt. Dabei muss aber auch die Postion aber übereinstimmen also z.B.
a =
xyxy
yyyy
xxcc

b =
y
xc

Dann ist die einzige lösung a[2][3] und a[3][3] und a [3][4]. Ich hoffe das ist irgend wie verständlich.
Nun habe ich folgenden Code:
Code:
        int k = 0;
        int pos_i = 0;
        int pos_j_min = 0;
        int pos_j_max = 0;
       
        for(int i = 0; i < a.length; i++){
            for(int j = 0; j < a[i].length; j++){
                    if(k < b[0].length && a[i][j] == b[0][k]){
                        if(pos_j_min == 0){
                            pos_j_min = j;
                            pos_i = i;
                        }
                        else if(j - pos_j_min == b[0].length){
                            pos_j_max = j;
                        }
                    }
                       
            }//y von a
        }// x von a
        if(pos_j_max - pos_j_min == b[0].length){
            System.out.println(pos_j_min + " " + pos_j_max);
        }
        else{
            System.out.println("error" + pos_j_min + " " + pos_j_max);
        }

Leider sucht der mir ja nur erstmal für b[0][length] das richtige und das wäre ja schon bei a[0][1] gegeben.
Kann mir wer helfen das zu erweitern bzw. erklären wie das lösbar wäre?
 
N

neoexpert

Gast
Java:
public class Main
{

    public static void main(String[] args)
    {
        char[][] a = {
            {'0', '1', '2', '3'},
            {'4', '5', '6', '7'},
            {'8', '9', 'a', 'b'},
            {'c' ,'d' ,'e' ,'f'}};
        char[][] b = {
            {'5', '6'},
            {'9', 'a'}};
        if(new Main().contains(a,b))
            System.out.println("c");
    }
    boolean contains(char[][] a, char[][] b){
        for (int y=0;y < a.length-b.length;y++)
        {
            for (int x=0;x < a[y].length-b[y].length;x++)
            {
                if(check(a,b,x,y))
                    return true;
            }
        }
        return false;
    }
    boolean check(char[][] a, char[][] b,int dx,int dy){
        for (int y=0;y < b.length;y++)
        {
            for (int x=0;x < b[y].length;x++)
            {
                if(a[x+dx][y+dy]!=b[x][y])
                    return false;
            }
        }
        return true;
    }
}
Interessant, du kannst damit in Bildern nach Mustern suchen. Es gibt sicherlich Varianten die schneller funktioieren. Irgendwie funktionieren ja die Gesichtsscanner.
EDIT:
Achso: man könnte ja die Bilder gröber machen und die Suche weicher also die Farben des Pixels auf Ähnlichkeit prüfen. Echt cool.
Faszinierend
 
Zuletzt bearbeitet von einem Moderator:
N

neoexpert

Gast
Korrektur:
Java:
public class Main
{

    public static void main(String[] args)
    {
        char[][] a = {
            {'0', '1', '2', '3'},
            {'4' ,'5', '6', '7'},
            {'8', '9', 'a', 'b'},
            {'c', 'd', 'e', 'f'}};
        char[][] b = {
            {'a', 'b'},
            {'e', 'f'}};

         if (new Main().contains(a, b))
            System.out.println("c");
    }
    boolean contains(char[][] a, char[][] b)
    {
        for (int y=0;y < a.length;y++)
        {
            for (int x=0;x < a[y].length;x++)
            {
                if (check(a, b, x, y))
                    return true;
            }
        }
        return false;
    }
    boolean check(char[][] a, char[][] b, int dx, int dy)
    {
        for (int y=0;y < b.length;y++)
        {
            for (int x=0;x < b[y].length;x++)
            {
                if (a[x + dx][y + dy] != b[x][y])
                    return false;
            }
        }
        return true;
    }
}
 
N

neoexpert

Gast
Hier noch eine Variante:
Da kannst du beliebige Arraylängen verwenden. Das zeichen * ist dabei Platzhalter für beliebiges zeichen:
Java:
public class Main
{

    public static void main(String[] args)
    {
        char[][] a = {
            {'0', '1', '2', '3'}, 
            {'4' ,'5', '6', '7'}, 
            {'8', '9', 'a', 'b'},
            {'c', 'd', 'e', 'f'}};
        char[][] b = {
            {'5', '*'}, 
            {'9', 'a'}};

        if (new Main().contains(a, b))
            System.out.println("c");
    }
    boolean contains(char[][] a, char[][] b)
    {
        for (int y=0;y < a.length;y++)
        {
            for (int x=0;x < a[y].length;x++)
            {
                if (check(a, b, x, y))
                    return true;
            }
        }
        return false;
    }
    boolean check(char[][] a, char[][] b, int dx, int dy)
    {
        for (int y=0;y < b.length;y++)
        {
            for (int x=0;x < b[y].length;x++)
            {
                if(b[y][x]=='*')
                    continue;
                if(y + dy>=a.length||x + dx>=a[y + dy].length)
                    continue;
                if (a[y + dy][x + dx] != b[y][x])
                    return false;
            }
        }
        return true;
    }
}
 
Zuletzt bearbeitet von einem Moderator:

Naryxus

Aktives Mitglied
Hey,

interessantes Thema!

Im Vergleich zu neoexpert verfolge ich bei mir einen rekursiven Ansatz. Ich habe auch gleich mal das Speichern der Positionen mit eingebaut, wobei das wahrscheinlich auch in neoexperts Lösung einfach möglich wäre.
Um zu sagen, welche Lösung jetzt effizienter ist, müsste ich mir die beiden Algorithmen genauer anschauen. Aber oft wählt man eine Lösung ja schon, ob man mehr auf Rekursionen oder Iterationen steht. Ich fand in diesem Fall Rekursionen recht ansprechend.

Zuerst einmal würde ich auf folgende Fälle testen (und ausschließen): Der Algorithmus macht nur Sinn, wenn die Dimensionen des einen Arrays größer gleich der Dimensionen des anderen Arrays ist. Das heißt ein Array mit den Dimensionen 2x3 kann niemals ein Teil eines Arrays mit den Dimensionen 3x2 sein.
Dies definiert eine Ordnungsrelation der Arraydimensionen.

Ich habe zuerst das Problem auf das zeilenweise Suchen eingeschränkt:

Java:
static Set<Integer> checkRow(int start, char[] row, char[] patternRow) {
   if(start > row.length - patternRow.length)
      return new HashSet<>();
   Set<Integer> out = Checker.checkRow(start + 1, row, patternRow);
   boolean check = true;
   for(int col = 0; col < patternRow.length; col++) {
      if(patternRow[col] != '\0' && row[start + col] != patternRow[col]) {
         check = false;
         break;
      }
   }
   if(check)
      out.add(start);
   return out;
}

Damit werden schon einmal alle Positionen in der Zeile ausgegeben, an denen die Zeile mit der Musterzeile übereinstimmt. Das ganze muss natürlich auch rekursiv sein, da das Muster potenziell an jedem Zeichen der Zeile beginnen kann.

Jetzt muss das ganze noch zweidimensional erweitert werden und sieht ganz ähnlich aus:

Java:
static Set<Point> check(int start, char[][] a, char[][] b) {
   if(start > a.length - b.length)
      return new HashSet<>();
   Set<Point> out = Checker.check(start + 1, a, b);
   Set<Integer> cols = IntStream.range(0, a[start].length).boxed().collect(Collectors.toSet()); //(0, 1, 2, ..., a[start].length - 1)
   int row = 0;
   do {
      cols.retainAll(Checker.checkRow(0, a[row], b[row])); //Schnittmenge der Startindizes der Zeilen
      row++;
   } while(row < b.length && !cols.isEmpty());
   cols.forEach(col -> out.add(new Point(start, col)));
   return out;
}

Das Grundprinzip hier: Man berechnet zeilenweise die Startindizes der Zeilen bezüglich des Musters und bildet dann die Schnittmenge. Der Gedanke dahinter ist, dass wenn in Zeile 1 des Testarrays die Zeile 1 des Musters ab Position 3 zu finden ist, muss auch Zeile 2 des Musters ab Position 3 in der Zeile 2 des Testarrays zu finden sein.
Und auch hier natürlich wieder rekursiv, da das Muster auch in Zeile i starten kann.

Mein Test mit den Arrays
char[][] test = {{'a', 'b', 'a', 'b'},
{'b', 'a', 'b', 'a'},
{'a', 'b', 'a', 'b'}};
char[][] pattern = {{'a', 'b'},
{'b', 'a'}};

liefert die korrekten Positionen [java.awt.Point[x=1,y=0], java.awt.Point[x=1,y=2], java.awt.Point[x=0,y=0], java.awt.Point[x=0,y=2]].

Ich hoffe, ich konnte dir etwas helfen.

Grüße Naryxus
 
N

neoexpert

Gast
Bei Rekursionen kann es zu Stack-Überlauf kommen. Aber man kann jede Rekursion in eine Iteration transformieren.
 

Naryxus

Aktives Mitglied
Ja, da hast du Recht. Natürlich muss man da schauen, in welchen Größenordnungen man arbeitet.

Wie ich schon gesagt habe, bleibt es dann eine "Sympathieentscheidung", ob man eine Rekursion oder Iteration verwendet, falls man sich um Überläufe keine Sorgen machen muss.
 
N

neoexpert

Gast
Ich würde jetzt diesen Algorithmus verwenden um nach Mustern in Bildern zu suchen. Erstmal die Bilder grob durchsuchen (niedrige Auflösung) und dann falls verschwommenes Gesicht gefunden wird, etwas genauer in dies Bereich nach Gesichtstrukturen suchen. Meinst du das kann Funktionieren?
 

Naryxus

Aktives Mitglied
Meinst du jetzt bezüglich Rekursion/Iteration? Wenn ja kommt das auf verschiedene Faktoren an. Wie groß du die Bilder betrachtest und wie leistungsfähig dein System ist.

Wenn du vom Prinzip her fragst: Ich denke, dass es eine gute Grundlage für eine Mustererkennung ist. Das Problem wird jedoch die unterschiedliche Skalierung sein. So wie der Algorithmus ist, kann er erstmal nur das Muster in einer einzigen Größe "erkennen". Nämlich in der, in der er als Array gespeichert ist. Es gibt einige Algorithmen, die dann noch das Testbild in einer Anzahl an Iterationen um einen gewissen Faktor größer/kleiner skaliert und dann jeweils testet, ob das Muster erkannt wird.

Ein weiteres Problem wird in jedem Fall die "Ähnlichkeitsrelation" in einem Bild sein. Also die Entscheidung bis zu welchem Grad das Testbild das Muster toleriert (Muss das Pixel wirklich komplett weiß sein oder reicht auch ein heller Grauton?)

Die Frage ist auch letztendlich immer, was du für ein Muster erkennen möchtest. Geht es wirklich um die Identifikation von Elementen in einem Bild, wird solch ein Algorithmus wahrscheinlich grundlegend sein.
Ich habe mal an einer Gestenerkennung gearbeitet. Dort hat der Benutzer mit der Maus eine geometrische Figur gezeichnet und das Programm hat die Form automatisiert erkannt. Hier habe ich dann mit einer Folge von Richtungsvektoren gearbeitet, um die Winkelsumme der gezeichneten Form zu erkennen und als Feature für ein neuronales Netz zum maschinellen Lernen verwendet.

Was ich damit sagen möchte, ist, dass verschiedene Algorithmen auch mit unterschiedlichen Featuren arbeiten können. Auch wenn der Ursprungsinput ein Bild ist.
Ich könnte mir zum Beispiel auch vorstellen, dass du einen Clustering-Algorithmus über das Bild laufen lässt, um ähnliche Bereiche zu finden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Muster in 2D-Array finden Allgemeine Java-Themen 4
Meeresgott OOP Factory Muster ausbauen Allgemeine Java-Themen 34
M Alles außer Muster in String ersetzen Allgemeine Java-Themen 1
W String Parsen und auf eigenes Muster anwenden (kein Regex) Allgemeine Java-Themen 11
L Strings nach gleichem Muster ordnen Allgemeine Java-Themen 4
G ThreadLocal in Muster "Unit of Work" Allgemeine Java-Themen 7
D Sterne Muster mit einer Schleife Allgemeine Java-Themen 5
K ArrayList nach bestimmtem Muster sortieren Allgemeine Java-Themen 3
S Kompositum Muster ohne Exception oder instanceof Operator Allgemeine Java-Themen 6
M RegEx: Muster ersetzen Allgemeine Java-Themen 6
T Muster/Zeichen/Texterkennung auf einem Image Allgemeine Java-Themen 9
G String nach Muster durchsuchen Allgemeine Java-Themen 5
X Bestimmtes Muster in Textdatei verändern Allgemeine Java-Themen 13
K Sequenzdiagramm für Singleton-Muster Allgemeine Java-Themen 5
M Rekursiv Verzeichnisse ansehen und auf Muster matchen Allgemeine Java-Themen 6
LucasGlockner Effizienter byte-Zugriff auf ein long[]-Array Allgemeine Java-Themen 8
8u3631984 Frage Performance bei Linked List und Array List Allgemeine Java-Themen 5
M Queue mit einem Array implemetieren Allgemeine Java-Themen 16
M Array Rang eines Elements Allgemeine Java-Themen 4
TheSepp Java bestimmtes Array auf den Wert 0 setzen Allgemeine Java-Themen 32
TheSepp Wie kann man Leerzeichen aus einer Array liste entfernen? Allgemeine Java-Themen 10
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
noah1407 Array Allgemeine Java-Themen 3
D Methoden Teil-Array mit Maximalwert bestimmen Allgemeine Java-Themen 23
N einem Array Objekte hinzufügen die ihr Array position gespeichert haben Allgemeine Java-Themen 34
N zweidimensionalen Array in dreidimensionalen Array speichern Allgemeine Java-Themen 4
N Schnellste Methode, ein Array durchzugehen? Allgemeine Java-Themen 9
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
L Array und Index Allgemeine Java-Themen 26
L die 3 größten Zahlen im Array Allgemeine Java-Themen 1
G jToggleButton in Array/ArrayList Allgemeine Java-Themen 12
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
Willi.We Array sortieren Allgemeine Java-Themen 5
gotzi242 Array Summe bestimmen tipps? Allgemeine Java-Themen 14
H Matrix ohne Array erstellen Allgemeine Java-Themen 9
Aboya Char Array rekursiv vergleichen Allgemeine Java-Themen 15
V4ll3.Wff Array in Java Allgemeine Java-Themen 4
Noahscript Aus einem byte Array Steuerungszeichen und Code bekommen und ersetzen Allgemeine Java-Themen 3
H Array Sportschütze Allgemeine Java-Themen 6
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
M Array verändern Allgemeine Java-Themen 1
A JavaFX 2 dimensionales array Allgemeine Java-Themen 1
LimDul Direktes return eines Array geht nicht Allgemeine Java-Themen 20
S Array dynamisieren oder ArrayList verwenden? Allgemeine Java-Themen 17
M Java 2D Array für ein Grid erstellen ? Allgemeine Java-Themen 2
H Array mit dem Datentype String[] initializieren Allgemeine Java-Themen 7
L ArrayList mit String Arrays in ein Array umwandeln Allgemeine Java-Themen 1
H Elemente aus ArrayList in Array speichern Allgemeine Java-Themen 8
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
N Byte Array in Java "dekomprimieren" Allgemeine Java-Themen 3
parrot Array Aufgabe Allgemeine Java-Themen 3
N String Array Eingabe Allgemeine Java-Themen 6
R Warum wird mir in der Konsole das "Standard Array" ausgegeben? Allgemeine Java-Themen 2
N Variablen Array Länge ändern. Allgemeine Java-Themen 8
D Kgv aller Paare aus einem Array mit n integer berechnen Allgemeine Java-Themen 5
W Enumeration ein Array/List als Eigenschaft mitgeben - warum geht das nicht? Allgemeine Java-Themen 0
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
A Array Problem Allgemeine Java-Themen 8
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
F Datei in String-Array einlesen Allgemeine Java-Themen 8
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
I Array Parameter mit 2 Klassen - NullPointerException Allgemeine Java-Themen 3
X Größten Werte in meinem Array löschen? Allgemeine Java-Themen 16
E Angabe wie groß Array sein soll und in for-schleifen diesen Array füllen Allgemeine Java-Themen 3
F 3 Dimensionales Array mit Allgemeine Java-Themen 9
M Steueralgorithmus verwandelt Array in Anfangszustand Allgemeine Java-Themen 9
W Array vs. ArrayList vs. HashMap Allgemeine Java-Themen 20
D Datentypen 2-3 Baum erstellen mit geordnetem int-array Allgemeine Java-Themen 0
T Objekt in Array packen Allgemeine Java-Themen 6
M Zahlen in Array anordnen Allgemeine Java-Themen 8
M Eclipse Unvollständigen Array ansteuern Allgemeine Java-Themen 2
D Erste Schritte Im Array Werte tauschen Allgemeine Java-Themen 5
Xge For/Array Error: IndexOutOfBounds Allgemeine Java-Themen 4
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
FRI3ND Datentypen Date-Array sortieren - Text mitnehmen? Allgemeine Java-Themen 7
D Integer-Array variabler Größe mit Zahlen befüllen (Schleifen) Allgemeine Java-Themen 0
J Variablen Array ertellen bei model.put Allgemeine Java-Themen 13
S Eindimensionales Array in zweidimensionales Array speichern Allgemeine Java-Themen 5
R convert 2d array list to 2d array Allgemeine Java-Themen 1
J json Array würfel Spalten durcheinander Allgemeine Java-Themen 9
MiMa Array umbau oder Alternative? Allgemeine Java-Themen 5
L Datentypen 3D Array Allgemeine Java-Themen 3
M 2D Array mit unterschiedlichen Längen erstellen und befüllen Allgemeine Java-Themen 11
Mario1409 Methoden JSON Array von URL Allgemeine Java-Themen 8
E Swing Array mit Bildern in GUI darstellen Allgemeine Java-Themen 2
P Array einer abstrakten Klasse Allgemeine Java-Themen 4
H Zweidimensionales Array - Zellen der Tabelle verbinden Allgemeine Java-Themen 2
M Zweidimensionales Array mit Binärzahlen füllen Allgemeine Java-Themen 8
M Array aus Thread Objekten erstellen Allgemeine Java-Themen 2
kodela Dynamisches Array in einer Klasse Allgemeine Java-Themen 5
G Array ohne Aufzählungszeichen ausgeben Allgemeine Java-Themen 6
J Wie kann ich ein Java Array als Säulendiagramm ausgeben? Allgemeine Java-Themen 2
Z 2D Array Pixels reparieren Allgemeine Java-Themen 2
S Algorithmus welcher True-Werte in einem Array findet und auswertet. Allgemeine Java-Themen 5
B Polibios Array erweitern Allgemeine Java-Themen 1
R Index in einem Array löschen Allgemeine Java-Themen 10
R Index in einem Array löschen Allgemeine Java-Themen 2
U Methoden Algorithmus MergeSort String [ ] array sortieren programmieren Allgemeine Java-Themen 17
J Array-List Bubble-Sort Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben