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. P>
Exemple d'entrée: {63, 101, 245, 215, 0} {245, 215} P>
sortie attendue: 2 p>
Exemple d'entrée 2: {24, 55, 74, 3, 1, 1} {24, 56, 74} P>
Sortie attendue 2: -1 p>
34 Réponses :
en python:
def f(l,s): for i in range(len(l)): if l[i:i+len(s)]==s:return i return -1
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. :)
en python: à tester p> qui imprime: p>
in c #: 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"
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"?
Un autre en Python:
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/.../ a>
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 () code>. 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 code> lorsque vous correction i> 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 ... I>, 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 :)
Ruby, à l'aide d'une matrice # pack (41 caractères caractères):
sub bytearray_search { ($a,$b) = @_; index(pack('C*',@$a),pack('C*',@$b)) }
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 code> 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
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. P>
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
Pour utiliser cette classe: TestMatch de vide privé () {Liste
PostScript, Strong> 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> Malheureusement, le Syntaxe Highlighter ne connaît pas la potscript, une lisibilité est toujours limitée. P> 149 Strike> 146 Strike> 170 Strike> 166 Strike> 167 grève>
false code> par
[[nom code> et
true code> par
[[EQ code> Pour enregistrer trois caractères li >
s code> apparaît deux fois dans
A code>. Malheureusement, ce bugfix a 24 caractères. Li>
/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!
:-) Ensuite, vous n'avez pas vu la solution J au code Skyline Golf: Stackoverflow.com/Questtions/1066234/the-skyline-problem/.../a>
En fait, PostScript de base en tant que langage de programmation (c'est-à-dire de laisser tous les opérateurs de graphisme / description) n'est pas terriblement difficile à saisir dès que vous connaissez l'opération basée sur la pile et le RPN.
Voici une version C # à l'aide de la comparaison des chaînes. Cela fonctionne correctement, mais se sent un peu haçonneux pour moi. 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;}
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; }
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?
LISP V1
(defun byte-array-subseqp (subarr arr) (let* ((alength (length arr)) (slength (length subarr)) (found (loop for start from 0 to (- alength slength) when (equalp subarr (subseq arr start (+ start slength))) do (return start)))) (values (when found t) (or found -1))))
Pourquoi ne pas utiliser Rechercher a "rel =" Nofollow Noreferrer "> lispworks.com/documentation/lw50/clhs/body/... >?
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 }; }
Lisp commun:
(defun golf-code (master-seq sub-seq) (search sub-seq master-seq))
Il pourrait même battre J avec un changement de renommage: o très impressionnant: p
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
c #, fonctionne avec n'importe quel type d'exploitation d'égalité:
(defun golf-code (master-seq sub-seq) (let ((x (search sub-seq master-seq))) (values (not (null x)) (or x -1))))
pour les listes: p> pour les tableaux: p> public static int IndexOf<T>( T[] arr1, T[] arr2 )
{
return !arr2.Except( arr1 ).Any() ? Array.IndexOf( arr1, arr2[0] ) : -1;
}
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.
haskell (114 caractères):
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
37 caractères pour encore plus de fonctionnalités que reques: il renvoie une liste de Tous les indices correspondants em>. p> utilisation: p>
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!
ruby, j'ai honte d'après avoir vu le code de Lar
Je sens que je triche, mais en utilisant Perl, cela ferait ce que l'OP veut: normalement 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. P>
blockQuote> p> index () code> 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: p>
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.
code d'air PHP 285 caractères } p> p>
rubis 1.9 (44b) goruby (29b) p>
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 code> est, je ne vois pas comment
2 code> il échoue le deuxième exemple; Il devrait vraiment être
b.Size code>.
> chacun_cons (b.Size) cerceaux. Merci!
basé sur import List;t s=maybe(-1)id.findIndex id.map(isPrefixOf s).tails
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 code> (suppression des points de code
l code>)
Vous pouvez utiliser Lambda pour Python3 pour obtenir 36 t = lambda l, s: octets (L) .Find (octets (s)) code> Notez que les octets fonctionnent différemment pour Python2
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
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.
php
en 105 ... p> ou plus explicitement, p>
gnu c: ansi c, sans bibliothèque: p>
C #, listes appelées "A" et "B":
Enumerable.Range(-1, a.Count).Last(n => n == -1 || a.Skip(n).Take(b.Count).SequenceEqual(b));
python fort>: 84 caractères prolog fort>: 84 caractères (dit "Non" au lieu de retourner -1): p>
Python ONLINER Fonction Définition de 64 caractères puisque nous sommes explicitement passés un éventail d'octets em> Nous pouvons transformer cela au tableau d'octet natif de Python STR code> et utiliser
str.find code> p> p>
+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/...
m(byte[] substring, int substart, int sublength, byte[] bigstring, int bigstart, int biglength)
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. N'avait pas remarqué que vous avez posté cela séparément lorsque j'ai mis à jour ma réponse.
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]
bizarre, personne n'a publié le JavaScript ..
solution 1: p>
solution 2: p> r = s = b.length; s> = 0 && (R = A.Indexof (B [ 0])); pour (x = 0; x
p> r = m = -1; b.map (fonction (d) {n = a.indexof (d); r == m && (c = r = n); si (n == m || c ++! = n) r = m}); code> p>
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.