10
votes

Array Recherche de code défi du code

Voici mon défi (code Golf): Prenez deux tableaux d'octets et déterminez si le deuxième tableau est une sous-chaîne du premier. Si c'est le cas, émettez l'index sur lequel le contenu du deuxième réseau apparaît dans la première. Si vous ne trouvez pas le deuxième tableau dans la première, alors la sortie -1.

Exemple d'entrée: {63, 101, 245, 215, 0} {245, 215}

sortie attendue: 2

Exemple d'entrée 2: {24, 55, 74, 3, 1, 1} {24, 56, 74}

Sortie attendue 2: -1

EDIT: Quelqu'un a souligné que le Bool est redondant, de sorte que toute votre fonction doit faire est de renvoyer une INT représentant l'indice de la valeur ou -1 si non trouvé.


6 commentaires

Le paramètre booléen est redondant depuis Res> = 0 -> vrai; res <0 -> faux; Cela permettra d'écrire le code aussi pour les langues sans retour multiple


@DFA: J'ai également pensé à cette construction aussi pour C #. Afin de s'adapter au contrat, ma fonction renvoie ma fonction un tableau d'objet avec un BOOL et un INT. Pas très élégant, mais il remplit une sorte de contrat, je suppose.


Votre utilisation du terme "sous-ensemble" ici peut être incorrecte. Si cela suffirait pour que les octets de la deuxième matrice soient présents dans la première matrice, alors "sous-ensemble" est correct. Toutefois, s'il est nécessaire que les octets du deuxième tableau soient présents dans la première matrice sous forme de séquence contiguë à maintenir l'ordre d'origine, le terme que vous recherchez est "Substring".


Il serait logique de permettre également une valeur de retour de Undef / NULL / NIL lorsque aucun match n'est trouvé, car cela est plus idiomatique dans certaines langues.


@RCIX - Votre défi initial a demandé un sous-ensemble et non une sous-chaîne qui aboutit à celles d'entre nous qui ont répondu au défi initial qui a maintenant voté.


Je suis désolé. Je n'étais pas au courant de la différence entre le sous-ensemble et la sous-chaîne à l'époque, et je voulais vraiment dire sous-chaîne.


34 Réponses :


4
votes

en python:

def f(l,s):
 for i in range(len(l)):
  if l[i:i+len(s)]==s:return i
 return -1


4 commentaires

Rétrécissement d'indentation et de jonction (dans la mesure du possible) rend cette solution de 121 caractères.


et renommer l = grand et s = petit, vous obtenez 94 caractères: p


Et quelques astuces supplémentaires le remet à 73 caractères:


Merci pour l'aide. J'ai également coupé le nom de la fonction et le blancheur pour l'obtenir jusqu'à 75 caractères. Pas mal pour une solution que (a) est relativement lisible et (b) n'appelle pas une fonction de bibliothèque pour faire le levage lourd. :)



1
votes

en python: xxx

à tester xxx

qui imprime: xxx < P> NOTE Il y a une solution plus courte, mais il utilise des caractéristiques de langue Python qui ne sont pas vraiment portables.


0 commentaires

1
votes

in c #: xxx pré>

EXEMPLE D'UTILISATION: P>

byte[] a1 = new byte[] { 24, 55, 74, 3, 1 };
byte[] a2 = new byte[] { 24, 56, 74 };
object[] result = test(a1, a2);
Console.WriteLine("{0}, {1}", result[0], result[1]); // prints "False, -1"


4 commentaires

On dirait que cela retourne une chaîne. Il devrait retourner un bool et un int. Je vais aller préciser cela dans la question.


Nous avons trouvé la même solution :)


@RCIX: J'ai mis à jour la matrice de retour avec des valeurs de BOOL et INT séparées. @NICK D: Oui, j'ai trouvé que cela était plutôt simple: o)


Coupez-vous les caractères si vous faites 'à l'aide de system.text.encoding' et utilisez 'var' au lieu de "chaîne"?



3
votes

Un autre en Python: xxx


11 commentaires

J'aime cette idée, mais la position renvoyée est incorrecte, car elle renvoie la position dans la chaîne "hexed".


Je l'ai donné d'autres pensées: cette idée fonctionne lors de l'utilisation d'octets. Voir Stackoverflow.com/Questions/1078770/...


Vous avez raison Stephan, merci. Je ne peux pas utiliser d'octets dans mon exemple, mais je l'ai réparé avec une autre façon, un peu laid :)


Malheureusement, votre code échoue maintenant pour une autre raison. Essayez la banquise ([123, 123], [231]) ... (la concaténation de 123 et 123 provoque 231 pour être assorties, et donc l'indice '0.333' est renvoyé.)


Ah, c'est pourquoi j'ai utilisé mon 1ère correction du hex () . Ok, maintenant je place un zéro entre les chiffres pour les séparer.


Désolé, toujours faux, pour deux raisons: la sous-carrée ([1, 200], [102]) donnera un faux positif et le point de vue ne devrait être divisé que par quatre si elle est! = -1. (En outre, vous voudrez peut-être utiliser // au lieu de / pour forcer la division entière, pour vous assurer que la fonction renvoie également un int lors de l'utilisation de Python 3+)


Merci Stephan :) C'est le résultats lorsque vous correction Code, sans le tester, au début de la matinée et ne buvez pas une tasse de café. À propos de la division Integer, je n'ai pas travaillé Python 3+ mais j'ai suivi vos conseils. -1/4 retour -1. N'est-ce pas vrai dans Python 3?


En effet ce n'est pas le cas. En Python 3+, -1/4 == -0,25 et -1 // 4 == -1. Quant à la procédure à suivre pour corriger votre code: [6) travaillez .Zfill (6) avec POS // 6? (Il est facile de voir que .Zfill (5) ne fonctionnera pas.)


... grattez ces dernières remarques. Je remarque maintenant que vous interviendrez maintenant les chiffres avec un espace. C'est correct, je pense. Je vais +1 maintenant :)


comme pour comment ... , que voulez-vous dire? Je l'ai déjà corrigé. Ou y a-t-il plus de bugs? :)


Je pense que nos commentaires ont traversé. Pour être clair: cela me semble sans bug maintenant :)



4
votes

Ruby, à l'aide d'une matrice # pack (41 caractères caractères):

sub bytearray_search {
  ($a,$b) = @_;
  index(pack('C*',@$a),pack('C*',@$b))
}


6 commentaires

J'écris quelque chose de similaire (def t (a, b) (i = a.to_s.index (b.to_s))? [True, I]: [Faux, -1] fin), mais vous m'avez battu. +1!


Pensé à utiliser à eux aussi, mais cela rendrait ByteArray_Search ([123], [1,2,3]) entraîne [vrai, 0].


Tableau # Inspecter est également trop lourd, car vous devriez dépasser les supports avant d'indexer.


($ i = index (pack ('c *', @ $ a1), pack ('c *', @ $ A2)))> = 0 || 0, $ i travaillerait également et soyez plus court.


Mis à jour / raccourci pour ne plus retourner la valeur booléenne.


A1.Pack (c = 'c *'). Index (A2.Pack c) || ​​-1



0
votes

comme Fredrik a déjà posté le code à l'aide de la conversion de chaîne. Voici une autre façon dont il pourrait être fait en utilisant c #.

Jwoolard me battre à cela, btw. J'ai aussi utilisé le même algorithme que lui. C'était l'un des problèmes que nous avons dû résoudre en utilisant C ++, au collège. xxx


0 commentaires

1
votes
public class SubArrayMatch
{
    private bool _IsMatch;
    private int _ReturnIndex = -1;
    private List<byte> _Input;
    private List<byte> _SubArray;
    private bool _Terminate = false;
#region "Public Properties"
    public List<byte> Input {
        set { _Input = value; }
    }

    public List<byte> SubArray {
        set { _SubArray = value; }
    }

    public bool IsMatch {
        get { return _IsMatch; }
    }

    public int ReturnIndex {
        get { return _ReturnIndex; }
    }
#endregion
#region "Constructor"
    public SubArrayMatch(List<byte> parmInput, List<byte> parmSubArray)
    {
        this.Input = parmInput;
        this.SubArray = parmSubArray;
    }
#endregion
#region "Main Method"
    public void MatchSubArry()
    {
        int _MaxIndex;
        int _Index = -1;
        _MaxIndex = _Input.Count - 1;

        _IsMatch = false;

        foreach (byte itm in _Input) {
            _Index += 1;

            if (_Terminate == false) {
                if (SubMatch(_Index, _MaxIndex) == true) {
                    _ReturnIndex = _Index;
                    _IsMatch = true;
                    return;
                }
            }
            else {
                return;
            }
        }
    }

    private bool SubMatch(int BaseIndex, int MaxIndex)
    {
        int _MaxSubIndex;
        byte _cmpByte;
        int _itr = -1;

        _MaxSubIndex = _SubArray.Count - 1;
        _MaxSubIndex += 1;

        if (_MaxSubIndex > MaxIndex) {
            _Terminate = true;
            return false;
        }

        foreach (byte itm in _SubArray) {
            _itr += 1;

            _cmpByte = _Input(BaseIndex + _itr);

            if (!itm == _cmpByte) {
                return false;
            }
        }

        return true;
    }
#endregion

}
By Anhar Hussain Miah 
'Edited by: Anhar.Miah @: 03/07/2009

1 commentaires

Pour utiliser cette classe: TestMatch de vide privé () {Liste INP = nouvelle liste (); Liste p = nouvelle liste (); INP.Ajouter (63); INP.Ajouter (101); INP.Ajouter (245); INP.Ajouter (215); INP.Ajouter (0); P.Ajouter (245); P.Ajouter (215); SUBARRAYMATCH FX0 = Nouveau sous-réseauMatch (INP, P); FX0.MatchSubarry (); if (fx0.ismatch == true) {console.writine ("vrai" + fx0.returnindex); } else {console.writeine ​​("faux"); }} 'Edité par: anhar.miah @: 03/07/2009



7
votes

PostScript, Strong> 149 Strike> 146 Strike> 170 Strike> 166 Strike> 167 grève> 159 caractères strong> (dans la partie "Faire le travail"): xxx pré>

Notez que cela trouvera la dernier em> l'occurrence de la sous-carraille Si elle est contenue plus d'une fois. p>

Historique de révision: strong> p>

  • remplacer false code> par [[nom code> et true code> par [[EQ code> Pour enregistrer trois caractères li >
  • Supprimé un bug pouvant causer un faux négatif si le dernier élément de s code> apparaît deux fois dans A code>. Malheureusement, ce bugfix a 24 caractères. Li>
  • a fait le bugfix un peu moins cher, économisant quatre caractères li>
  • a dû insérer un espace à nouveau parce qu'un tableau de bord est un caractère légal d'un nom. Cette erreur de syntaxe n'a pas été attrapée car l'étui à essai n'a pas atteint ce point. Li>
  • a cessé de retourner les bools lorsque l'OP ne les oblige plus. Sauve 8 caractères. Li> ul>

    Version expliquée: strong> p>

    Malheureusement, le Syntaxe Highlighter ne connaît pas la potscript, une lisibilité est toujours limitée. P>

    /A [63 101 245 215 0] def
    /S [245 215 ] def
    
    /Slast S length 1 sub def % save the index of the last element of S,
                              % i.e. length-1
    /Spos Slast def % our current position in S; this will vary
    [ % put a mark on the bottom of the stack, we need this later.
    
    /check % This function recursively removes values from the stack
           % and compares them to the values in S
    {
      dup [ 
      eq
      { % we found the mark on the bottom, i.e. we have no match
        pop -1 % remove the mark and push the results
      }
      { % we're not at the mark yet
        dup % save the top value (part of the bugfix)
        S Spos get
        eq 
        {  % the top element of the stack is equal to S[Spos]
           pop % remove the saved value, we don't need it
           Spos 0
           eq 
           { % we are at the beginning of S, so the whole thing matched.
             ] length % Construct an array from the remaining values
                      % on the stack. This is the part of A before the match,
                      % so its length is equal to the position of the match.
                      % Hence we push the result and we're done.
           }
           { % we're not at the beginning of S yet, so we have to keep comparing
             /Spos Spos 1 sub def % decrease Spos
             check % recurse
           }
           ifelse
        }
        { % the top element of the stack is different from S[Spos]
          Spos Slast eq {pop} if % leave the saved top value on the stack
                                 % unless we're at the end of S, because in
                                 % this case, we have to compare it to the
                                 % last element of S (rest of the bugfix)
          /Spos Slast def % go back to the end of S
          check % recurse
        }
        ifelse
     }
     ifelse
    }
    def % end of the definition of check
    
    A aload % put the contents of A onto the stack; this will also push A again,
            % so we have to ...
    pop % ...remove it again
    check % And here we go!
    



0
votes

Voici une version C # à l'aide de la comparaison des chaînes. Cela fonctionne correctement, mais se sent un peu haçonneux pour moi. XXX PRE>

Voici une version légèrement plus longue qui effectue une réelle comparaison de chaque élément de matrice individuel. P>

int FindSubArray(byte[] super, byte[] sub)
{
    int i, j;
    for (i = super.Length - sub.Length; i >= 0; i--)
    {
        for (j = 0; j < sub.Length && super[i + j] == sub[j]; j++);
        if (j >= sub.Length) break;
    }
    return i;
}

// 135 characters
int F(byte[]x,byte[]y){int i,j;for(i=x.Length-y.Length;i>=0;i--){for
(j=0;j<y.Length&&x[i+j]==y[j];j++);if(j>=y.Length)break;}return i;}


0 commentaires

6
votes

C99

#include <string.h>
#define f(a,b,c,d,e,f) { void * g = memmem(a, b, c, d); f = (e = !!g) ? g - a : -1; }


2 commentaires

Intéressant, mais quelle est la longueur?


Je pensais que Memmem était spécifique à GNU ... par conséquent, cela ne fonctionnerait que pour GNUC99 PAS C99?




0
votes

C #:

public static object[] isSubArray(byte[] arr1, byte[] arr2) {
  int o = arr1.TakeWhile((x, i) => !arr1.Skip(i).Take(arr2.Length).SequenceEqual(arr2)).Count();
  return new object[] { o < arr1.Length, (o < arr1.Length) ? o : -1 };
}


0 commentaires

12
votes

Lisp commun:

(defun golf-code (master-seq sub-seq)
  (search sub-seq master-seq))


1 commentaires

Il pourrait même battre J avec un changement de renommage: o très impressionnant: p



0
votes

dans Ruby:

def subset_match(array_one, array_two)
  answer = [false, -1]
  0.upto(array_one.length - 1) do |line|
    right_hand = []
    line.upto(line + array_two.length - 1) do |inner|
      right_hand << array_one[inner]
    end
    if right_hand == array_two then answer = [true, line] end
  end
  return answer
end


0 commentaires

0
votes

c #, fonctionne avec n'importe quel type d'exploitation d'égalité: xxx


0 commentaires

0
votes
(defun golf-code (master-seq sub-seq)
  (let ((x (search sub-seq master-seq)))
    (values (not (null x)) (or x -1))))

0 commentaires

-2
votes

c # strong>

pour les listes: p> xxx pré>

pour les tableaux: p>

public static int IndexOf<T>( T[] arr1, T[] arr2 )
{
    return !arr2.Except( arr1 ).Any() ? Array.IndexOf( arr1, arr2[0] ) : -1;
}


3 commentaires

Je pense que vous avez mal compris le problème: la question demande une correspondance de sous-chaîne, de sorte que [1,2,3] ne contient pas [1,3].


@Ephémission - La question initiale a demandé: "Si le deuxième tableau est un sous-ensemble de la première" - pas une sous-chaîne. Cela ne devrait pas être voté tel qu'il répond à la question initiale car elle renvoie en effet le résultat attendu.


Je ne l'ai pas votté, j'aimerais juste le voir corrigé ... surtout que toutes les autres réponses ont été réparées aussi.



0
votes

haskell (114 caractères): xxx


1 commentaires

Un port trivial de ma solution J est de 75 caractères: liste d'importation; g A = carte fst.filter snd.zip [0.]. Plan (((== a) .take (longueur a)). Queues



8
votes

j

37 caractères pour encore plus de fonctionnalités que reques: il renvoie une liste de Tous les indices correspondants . xxx

utilisation: xxx


xxx < / h1>


4 commentaires

Accrocher: Est-ce que cette vérification si le deuxième tableau est présent en tant que sous-chaîne du premier?


Le premier tableau existe de manière contiguë dans la deuxième matrice à partir d'un indice renvoyé.


ooohhhh ... donc ce que vous dites est en plus de l'index de démarrage de la sous-chaîne, il génère tous les indices de correspondance?


Vache sacrée! C'est pire que Perl!



0
votes

ruby, j'ai honte d'après avoir vu le code de Lar xxx


0 commentaires

3
votes

Je sens que je triche, mais en utilisant Perl, cela ferait ce que l'OP veut: xxx

normalement index () dans perl fonctionne sur les cordes avec Sémantique des personnages, mais les "usages d'octets" pragma le font à la place des octets Segmintics. Du manpage:

quand "utiliser des octets" est dans effet, le codage est temporairement ignoré et chaque chaîne est traitée comme une série d'octets.


2 commentaires

J'ai vérifié, et même si je retire la plupart des espaces, c'est 44 caractères. Si près!


Cela ne fonctionne que si vous commencez avec deux cordes, mais le défi consistait à commencer par deux tableaux d'octets. Bon point avec les octets d'utilisation, il faut probablement ajouter celui-ci à ma suggestion de Perl pour pouvoir renvoyer l'index correct dans toutes les situations.



0
votes

code d'air PHP 285 caractères xxx

}


0 commentaires

3
votes

rubis 1.9 (44b) xxx

goruby (29b) xxx


5 commentaires

Si vous pouvez raser quelques caractères de ceci, il battra la mise en œuvre J actuellement sur le dessus.


Cette mise en œuvre J ne renvoie pas l'index ou -1 si non trouvé. Si ce n'est pas une exigence, vous pouvez également vous raser de plus d'octets sur les implémentations rubis.


Malheureusement, vous devrez remplacer chaque_cons (2) avec chaque_cons (B.Size) pour que cela fonctionne, ce qui ajoute 5 autres caractères.


Retourner nil au lieu de -1 si c'est plus naturel me semble parfaitement amende pour moi; Il y a un commentaire suggérant que la question soit modifiée. Maintenant que je cherche ce que Ruby's énumérable # chacun_cons est, je ne vois pas comment 2 il échoue le deuxième exemple; Il devrait vraiment être b.Size .


> chacun_cons (b.Size) cerceaux. Merci!



5
votes

Python 2 & 3, 73 Strike> 68 Strike> 58 caractères

basé sur Nikhil Chelliah 's Réponse kaiser.se 's Réponse : P>

import List;t s=maybe(-1)id.findIndex id.map(isPrefixOf s).tails


2 commentaires

J'ai raccourci le haskell. Si vous retournez l'ordre d'argument, vous pouvez couper 4 autres caractères: TS = peut-être (-1) id.findindindex id.map (ispréfixof s) .Trails (suppression des points de code l )


Vous pouvez utiliser Lambda pour Python3 pour obtenir 36 t = lambda l, s: octets (L) .Find (octets (s)) Notez que les octets fonctionnent différemment pour Python2



1
votes

rubis fort>. Pas exactement le plus court du monde, mais cool puisqu'il s'agit d'une extension du tableau.

class Array
  def contains other=[]
    index = 0
    begin
      matched = 0
      ndx = index
      while other[matched] == self[ndx]
        return index if (matched+1) == other.length
        matched += 1
        ndx += 1
      end
    end until (index+=1) == length
    -1
  end
end

puts [ 63, 101, 245, 215, 0 ].contains [245, 215]
# 2
puts [ 24, 55, 74, 3, 1 ].contains [24, 56, 74 ]
# -1


1 commentaires

Ouais, mais pour 'A.Contains B', il serait inefficace pour de grandes valeurs d'un lieu où il y a des matches partiels de B, mais seulement un match complet près de la fin de A. Beaucoup d'autres algorithmes sont bien meilleurs.



1
votes

php

en 105 ... xxx

ou plus explicitement, xxx


0 commentaires

1
votes

gnu c: xxx

ansi c, sans bibliothèque: xxx


0 commentaires

1
votes

C #, listes appelées "A" et "B":

Enumerable.Range(-1, a.Count).Last(n => n == -1 
    || a.Skip(n).Take(b.Count).SequenceEqual(b));


0 commentaires

2
votes

python : 84 caractères xxx

prolog : 84 caractères (dit "Non" au lieu de retourner -1): xxx


0 commentaires

2
votes

Python ONLINER Fonction Définition de 64 caractères xxx

puisque nous sommes explicitement passés un éventail d'octets Nous pouvons transformer cela au tableau d'octet natif de Python STR et utiliser str.find


1 commentaires

+1 Pour une solution très claire qui fonctionne dans Python 2 & 3. Je rasée d'un autre 6 octets: Stackoverflow.com/Questtions/1078770/...



1
votes
m(byte[] substring, int substart, int sublength, byte[] bigstring, int bigstart, int biglength)

0 commentaires

2
votes

python3 36 octets strong>

basé sur Stephan202 P>

>>> t=lambda l,s:bytes(l).find(bytes(s))
... 
>>> t([63, 101, 245, 215, 0], [245, 215])
2
>>> t([24, 55, 74, 3, 1], [24, 56, 74])
-1


1 commentaires

+1. N'avait pas remarqué que vous avez posté cela séparément lorsque j'ai mis à jour ma réponse.



0
votes

Golfscript - 35 octets

Seulement 32 octets strong> Pour la fonction réelle si nous comptons la même chose que pour J P>

{:b;:a,,{.a@>b,<b={}{;}if}%-1or}:f;

#Test cases (same as J)               output
[63 110 245 215 0] [245 215] f p   #  [2]
[22 55 74 3 1] [24 56 74] f p      #  -1
[1 1 1 2 1 1 3] [1 1]f p           #  [0 1 4]
[0 1 2 3 1 0 2 1 2 0] [1 2] f p    #  [1 7]


0 commentaires

0
votes

bizarre, personne n'a publié le JavaScript ..

solution 1:

r = s = b.length; s> = 0 && (R = A.Indexof (B [ 0])); pour (x = 0; x xxx

solution 2:

r = m = -1; b.map (fonction (d) {n = a.indexof (d); r == m && (c = r = n); si (n == m || c ++! = n) r = m}); xxx


0 commentaires