6
votes

Trouver un motif dans une chaîne binaire

J'essaie de trouver un motif répétitif dans une chaîne de chiffres binaires.

par exemple. 0010010010 ou 1110111011 = OK

pas. 0100101101 = mauvais

Les chaînes sont de 10 chiffres longues (comme ci-dessus) et je suppose que 2 itérations du «motif» sont le minimum.

J'ai commencé à définir manuellement une «banque» de motifs que le programme pourrait correspondre à celui-ci, mais il doit y avoir une meilleure façon d'utiliser un algorithme?

La recherche m'a eu nulle part - je pense que la langue et la terminologie que j'utilise est incorrecte.


7 commentaires

Voulez-vous dire que vous voulez savoir si la chaîne entière peut être représentée comme une chaîne plus courte répétée deux fois ou plus? Quelle est votre définition d'un "modèle répété"?


Toute chaîne peut être considérée comme ayant un motif qui répète mais a une période plus longue que le nombre de bits peut être montré.


+1 pour choisir la langue en fonction du problème. Je me demande si Pralog battrait JavaScript ici.


Pour autant que je sache, il y a 62 possibilités. S'il vous plaît voir ma réponse.


@groovy je le fais 52 pas 62? 0000000000 0000100001 0001000010 0001000100 0001100011 0010000100 0010001000 0010010010 0010100101 0011000110 0011001100 0011100111 0100001000 0100010001 0100100100 0100101001 0101001010 0101010101 0101101011 0110001100 0110011001 0110101101 0110110110 0111001110 0111011101 0111101111 1000010000 1000100010 1000110001 1001001001 1001010010 1001100110 1001110011 1010010100 1010101010 1010110101 1011010110 1011011011 1011101110 1011110111 1100011000 1100110011 1100111001 1101011010 1101101101 1101110111 1101111011 1110011100 1110111011 1110111101 1111011110 1111111111


@ Paddy3118 Je compte ceux-ci comme des motifs différents, même si la chaîne ressemble à la même chose: 0000000000 => 0,00.000.0000 00000; 1111111111 => 1,11,111 11111111111; 0101010101 => 01 0101; 1010101010 => 10 1010;


@groovy: merci. J'ai compté "un" modèle répété dans une chaîne; Vous comptez toutes les chaînes répétitives.


7 Réponses :


1
votes

Vous n'avez que 2 modèles de 2 ^ 10, c'est un petit nombre suffisant que vous pouvez simplement précalcomputer toutes les chaînes valides et stocker les résultats dans une matrice booléenne de 1024 éléments; Si une chaîne est valide, puis la convertissez-la en un entier (E.G. "0000001111" = 15) et stockez "True" dans l'index de la matrice résultant. Pour vérifier si une chaîne est valide, convertissez-la en un entier et recherchez l'index dans la matrice booléenne précalisée.

Si vos chaînes sont plus longues que 10 chiffres, vous devrez être plus intelligent de déterminer si une chaîne est valide, mais que vous n'avez que 1024 cordes, vous pourriez aussi bien être paresseux à ce sujet.


1 commentaires

Je suppose que vous avez une longueur de motif minimum de 3, alors vérifiez si str.substring (0, 2) = str.Substring (3, 5) = str.Substring (6, 8), et si str.substring (0 , 0) = str.substring (9, 9). Si c'est faux, essayez un motif de longueur 4; str.Substring (0, 3) = str.Substring (4, 7) et str.Substring (0, 1) = str.Substring (8, 9). Si cela échoue, essayez un motif de longueur 5. Un motif de longueur 6 serait str.Substring (0, 3) = str.Substring (6, 9), mais je suppose que vous avez une longueur maximale de modèle de 5.



2
votes

tout un défi. Qu'en est-il de cette fonction?

function findPattern(n) {
    var oksubs = [n.substr(0,5),n.substr(0,4),n.substr(0,3)];
    for(var i=0; i<oksubs.length; ++i) {
        var sub = oksubs[i];
        if((sub+sub+sub+sub).substr(0,10)==n) return sub;
    }
    return false;
}


2 commentaires

Hey Jan, merci d'avoir publié rapidement le code. Je pense, il est possible de trouver des modèles sans utiliser d'oksubs. Prenez les premiers 5 ou 4 ou 3 chiffres de la chaîne d'origine elle-même. par cinq je veux dire stringlength / 2


Oh, merci Jack! On dirait que nous avons réussi à mettre les mathématiques, la force brute et les JS ensemble!



1
votes

Mon approche de force brute serait:

par exemple h3>
  1. Givenstring: 0010010010 code>: p> li>

  2. Créer une liste de modèles possibles pour Givenstring 0010010010 Code>: P>

    function findPatterns(str){
        var len = str.length;
        var possible_patterns = {};  // save as keys to prevent duplicates
        var testPattern;
        var foundPatterns = [];
    
        // 1) create collection of possible patterns where:
        //    1 < possiblePattern.length <= str.length/2
        for(var i = 0; i <= len/2; i++){
            for(var j = i+2; j <= len/2; j++){
                possible_patterns[str.substring(i, j)] = 0;
            }
        }
    
        // 2) create testPattern to test against given str where:
        //    testPattern.length >= str.length
        for(var pattern in possible_patterns){
            testPattern = new Array(Math.ceil(len/pattern.length)+1).join(pattern);
            if(testPattern.indexOf(str) >= 0){
                foundPatterns.push(pattern);
            }
        }
        return foundPatterns;
    }
    
  3. les répéter pour créer des cordes de longueur> = 10 p>

    foundPatterns = [010, 001, 100]
    
  4. et vérifier ... p>

    testPattern2: 010010010010
    givenString :   0010010010
    
  5. Modèles trouvés: P>

    testPattern0 = 0000000000    // 00 00 00 00 00
    testPattern1 = 010010010010  // 010 010 010 010
    testPattern2 = 001000100010  // 0010 0010 0010
    ...
    


2 commentaires

Votre liste de modèles possibles est incomplète: qu'en est-il de 0011001100 ? N'hésitez pas à copier les modèles de ma réponse.


Ma liste des modèles possibles ne contient que des motifs trouvés dans l'exemple indiqué String 0010010010. Ma méthode construit la liste des modèles possibles de manière dynamique sur la chaîne à portée de main. Ou je manque quelque chose?



1
votes
  1. Maintenance d'un tableau de 2 ^ 10 ne peut pas aider parce que cela n'indique pas que les chaînes ont des modèles répétés.
  2. Pour avoir un motif répétitif, la longueur du motif ne peut être que <= 5

  3. Il peut y avoir un motif de longueur 1.Mais de longueur de longueur cinq va le couvrir. [Étape édité]

  4. S'il y a un motif avec une longueur 2, il y a toujours un motif avec une longueur 4.

  5. de (1), (2), (3) et (4), il est nécessaire de vérifier les motifs de longueur 3,4 et 5

  6. Cela signifie que si les trois premiers chiffres correspondent aux trois chiffres suivants, passez jusqu'à la fin de la chaîne d'autre casser et aller sur 7

  7. Match Correspondre aux quatre premiers chiffres avec les quatre suivants si correspondez-vous jusqu'à la fin de la chaîne sinon casser et aller à 8

  8. Match Correspondre aux cinq premiers chiffres avec les quatre suivants si correspondez-vous jusqu'à la fin de la chaîne sinon rompre et aller à 9

  9. Si l'un de 6, 7,8 est faux, défaillance de retour


4 commentaires

Il peut être généralisé si nous considérons la longueur maximale du motif = Max StringLength / 2 et commencez à comparer à partir de 3 à stringthlength / 2


L'étape 3 est erronée et redondante: 1111111111 a un motif de longueur 1, mais il s'agit également de la longueur de longueur 5, de sorte que la conclusion à l'étape 5 est correcte avec une chance


je suis d'accord. Bon Trouver Jan. Cependant, l'algo. Tiens toujours bien, comme vous l'avez dit à juste titre. J'ai réalisé une dernière chose, les étapes 6,7 et 8 devraient être appliquées dans l'ordre inverse pour que nous trouvions le motif avec max. longueur.


Merci d'inspiration pour l'algorithme de force brute, voir ma réponse mise à jour. J'aime quand la force brute gagne :-)



0
votes

Cette réponse utilise une expression régulière Python à compiler avec l'ensemble de drapeaux verbeux qui permet aux févalités multiples avec des commentaires et des espaces non significatifs. J'utilise également des groupes nommés dans le REGEXP.

Le REGEXP a été développé à l'aide de l'outil Kodos.

Le REGEXP recherche les chaînes répétitives les plus longues de longueur cinq puis trois caractères répétés. (deux caractères répétés sont redondants car il est égal au quatre plus longs; et de même, une répétition est redondante sur cinq). xxx

donne la sortie: < Pré> xxx


2 commentaires

Ne devrait pas 1001110011 montrer comme ayant un motif répétitif de 10011?


@chao, corrigé. Merci. J'ai ajouté un "\ 'supplémentaire quand j'ai copié le regexp de Kodos par erreur.



0
votes

en python (à nouveau) mais sans régexps: xxx

sortie: xxx


0 commentaires

1
votes

Autant que je puisse dire, il y a 62 cordes binaires à motifs de longueur 10 => 2 ^ 1 + 2 ^ 2 + 2 ^ 3 + 2 ^ 4 + 2 ^ 5 . Voici quelques codes qui les énumère et correspond à une chaîne à motifs: xxx

sortie: xxx


0 commentaires