Sto cercando di creare un programma che identi fi ca determinati modelli nei numeri. Non sono sicuro che questo abbia bisogno di un algoritmo o di una programmazione attentamente studiata. Non sto cercando qualcuno che fornisca il codice sorgente, solo alcune idee che stimolano il pensiero per mettermi nella giusta direzione.Programma Java per identificare gli schemi nei numeri
I numeri saranno di lunghezza fissa di 6 cifre da 000000 a 999999. Immagino che ogni numero venga memorizzato come parte di un array. Vorrei quindi testare il numero in base a un modello.
Per esempio diciamo che il 3 modelli sto usando sono
A A A A A A - would match such examples as 111111 , 222222, 333333 etc where
A B A B A B - would match such examples as 121212 , 454545, 919191 etc
A (A+1) (A+2) B (B+1) (B+2) - would match such examples as 123345, 789123, 456234
immagino la parte che sono bloccato su è come allocare ogni parte dell'array intero in un valore come A o B
I miei pensieri iniziali sarebbero solo per assegnare ciascuna parte come una singola lettera. Quindi, se la matrice costituita da 1 3 5 4 6 8, quindi vorrei creare una mappa come
A=1
B=3
C=5
D=4
E=6
F=8
Poi in qualche modo prendere la prima modello,
AAAAAA
e prova con qualcosa di simile, se (AAAAAA = ABCDEF) AAAAAAA allora abbiamo abbinato
se poi non provare (ABABAB = ABCDEF) ecc attraverso tutti i miei modelli
In questo scenario non v'è alcun motivo per cui il valore assegnato a C sopraelevazione essere uguale al valore assegna a F come nel numero 234874.
Non sono sicuro che questo abbia un senso per nessuno, ma suppongo di poter affinare la mia domanda sulla base del feedback.
In sintesi, sto cercando idee su come fare in modo che un programma accetti un numero di 6 cifre e restituisca a noi quale modello corrisponde.
SOLUZIONE
Dopo i commenti riportati mi ha messo su una buona pista sotto è quello che ho creato come soluzione finale.
package com.doyleisgod.number.pattern.finder;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class FindPattern {
private final int[] numberArray; //Array that we will match patterns against.
private final Document patternTree = buildPatternTree(); //patternTree containing all the patterns
private final Map<String, Integer> patternisedNumberMap; //Map used to allocate ints in the array to a letter for pattern analysis
private int depth = 0; //current depth of the pattern tree
// take the int array passed to the constructor and store it in out numberArray variable then build the patternised map
public FindPattern (int[] numberArray){
this.numberArray = numberArray;
this.patternisedNumberMap = createPatternisedNumberMap();
}
//builds a map allocating numbers to letters. map is built from left to right of array and only if the number does not exist in the map does it get added
//with the next available letter. This enforces that the number assigned to A can never be the same as the number assigned to B etc
private Map<String, Integer> createPatternisedNumberMap() {
Map<String, Integer> numberPatternMap = new HashMap<String, Integer>();
ArrayList<String> patternisedListAllocations = new ArrayList<String>();
patternisedListAllocations.add("A");
patternisedListAllocations.add("B");
patternisedListAllocations.add("C");
patternisedListAllocations.add("D");
Iterator<String> patternisedKeyIterator = patternisedListAllocations.iterator();
for (int i = 0; i<numberArray.length; i++){
if (!numberPatternMap.containsValue(numberArray[i])) {
numberPatternMap.put(patternisedKeyIterator.next(), numberArray[i]);
}
}
return numberPatternMap;
}
//Loads an xml file containing all the patterns.
private Document buildPatternTree(){
Document document = null;
try {
File patternsXML = new File("c:\\Users\\echrdoy\\Desktop\\ALGO.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.parse(patternsXML);
} catch (Exception e){
e.printStackTrace();
System.out.println("Error building tree pattern");
}
return document;
}
//gets the rootnode of the xml pattern list then called the dfsnodesearch method to analyse the pattern against the int array. If a pattern is found a
//patternfound exception is thorwn. if the dfsNodeSearch method returns without the exception thrown then the int array didnt match any pattern
public void patternFinder() {
Node rootnode= patternTree.getFirstChild();
try {
dfsNodeSearch(rootnode);
System.out.println("Pattern not found");
} catch (PatternFoundException p) {
System.out.println(p.getPattern());
}
}
//takes a node of the xml. the node is checked to see if it matches a pattern (this would only be true if we reached the lowest depth so must have
//matched a pattern. if no pattern then analyse the node for an expression. if expression is found then test for a match. the int from the array to be tested
//will be based on the current depth of the pattern tree. as each depth represent an int such as depth 0 (i.e root) represent position 0 in the int array
//depth 1 represents position 1 in the int array etc.
private void dfsNodeSearch (Node node) throws PatternFoundException {
if (node instanceof Element){
Element nodeElement = (Element) node;
String nodeName = nodeElement.getNodeName();
//As this method calls its self for each child node in the pattern tree we need a mechanism to break out when we finally reach the bottom
// of the tree and identify a pattern. For this reason we throw pattern found exception allowing the process to stop and no further patterns.
// to be checked.
if (nodeName.equalsIgnoreCase("pattern")){
throw new PatternFoundException(nodeElement.getTextContent());
} else {
String logic = nodeElement.getAttribute("LOGIC");
String difference = nodeElement.getAttribute("DIFFERENCE");
if (!logic.equalsIgnoreCase("")&&!difference.equalsIgnoreCase("")){
if (matchPattern(nodeName, logic, difference)){
if (node.hasChildNodes()){
depth++;
NodeList childnodes = node.getChildNodes();
for (int i = 0; i<childnodes.getLength(); i++){
dfsNodeSearch(childnodes.item(i));
}
depth--;
}
}
}
}
}
}
//for each node at a current depth a test will be performed against the pattern, logic and difference to identify if we have a match.
private boolean matchPattern(String pattern, String logic, String difference) {
boolean matched = false;
int patternValue = patternisedNumberMap.get(pattern);
if (logic.equalsIgnoreCase("+")){
patternValue += Integer.parseInt(difference);
} else if (logic.equalsIgnoreCase("-")){
patternValue -= Integer.parseInt(difference);
}
if(patternValue == numberArray[depth]){
matched=true;
}
return matched;
}
}
l'elenco XML di modelli assomiglia a questo
<?xml version="1.0"?>
<A LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<pattern>(A)(A)(A)(A)</pattern>
</A>
<B LOGIC="=" DIFFERENCE="0">
<pattern>(A)(A)(B)(A)</pattern>
</B>
</A>
<B LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<pattern>(A)(A)(B)(A)</pattern>
</A>
<B LOGIC="=" DIFFERENCE="0">
<pattern>(A)(A)(B)(B)</pattern>
</B>
</B>
</A>
<A LOGIC="+" DIFFERENCE="2">
<A LOGIC="+" DIFFERENCE="4">
<A LOGIC="+" DIFFERENCE="6">
<pattern>(A)(A+2)(A+4)(A+6)</pattern>
</A>
</A>
</A>
<B LOGIC="=" DIFFERENCE="0">
<A LOGIC="+" DIFFERENCE="1">
<B LOGIC="+" DIFFERENCE="1">
<pattern>(A)(B)(A+1)(B+1)</pattern>
</B>
</A>
<A LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<pattern>(A)(B)(A)(A)</pattern>
</A>
<B LOGIC="+" DIFFERENCE="1">
<pattern>(A)(B)(A)(B+1)</pattern>
</B>
<B LOGIC="=" DIFFERENCE="0">
<pattern>(A)(B)(A)(B)</pattern>
</B>
</A>
<B LOGIC="=" DIFFERENCE="0">
<A LOGIC="=" DIFFERENCE="0">
<pattern>(A)(B)(B)(A)</pattern>
</A>
<B LOGIC="=" DIFFERENCE="0">
<pattern>(A)(B)(B)(B)</pattern>
</B>
</B>
<A LOGIC="-" DIFFERENCE="1">
<B LOGIC="-" DIFFERENCE="1">
<pattern>(A)(B)(A-1)(B-1)</pattern>
</B>
</A>
</B>
<A LOGIC="+" DIFFERENCE="1">
<A LOGIC="+" DIFFERENCE="2">
<A LOGIC="+" DIFFERENCE="3">
<pattern>(A)(A+1)(A+2)(A+3)</pattern>
</A>
</A>
</A>
<A LOGIC="-" DIFFERENCE="1">
<A LOGIC="-" DIFFERENCE="2">
<A LOGIC="-" DIFFERENCE="3">
<pattern>(A)(A-1)(A-2)(A-3)</pattern>
</A>
</A>
</A>
</A>
e il mio modello di classe di eccezione trovato assomiglia a questo
package com.doyleisgod.number.pattern.finder;
public class PatternFoundException extends Exception {
private static final long serialVersionUID = 1L;
private final String pattern;
public PatternFoundException(String pattern) {
this.pattern = pattern;
}
public String getPattern() {
return pattern;
}
}
Non sono sicuro se tutto questo vi aiuterà chiunque con un simile problema o se qualcuno ha commenti su come funziona sarebbe bello ascoltarli.
Sembra regex per me. – Bill
Bene, non vorrei hardcode una corrispondenza esatta (cioè, A = 1 situazioni di tipo). Probabilmente vorrai considerare ogni diverso personaggio incontrato per essere una cifra diversa. Le separazioni di spazio dovrebbero probabilmente essere numeri diversi (non cifre). –
Questa è roba di IA. Douglas Hofstadter ha fatto la sua carriera proprio su questa scoperta di modelli. –