Verifique se há ocorrências de string em outra string

8

Desafio

Tenho certeza de que você leu o título e veio buscar seu representante, pensando nas coisas de seus filhos, mas pense novamente! Você precisa desafiar um ao outro no código mais curto para contar as ocorrências de uma string em outra. Por exemplo, dada a seguinte entrada:

aaaabbbbsssffhd

como uma string e a string

s

deve produzir

3

Regras

Pouco antes de você sorrir e dizer: "Ei, eu vou usar ----", leia isto:

  • Não há uso de bibliotecas externas ou da API do seu idioma. Você precisa implementá-lo manualmente. O que significa que você não pode usar a função ou o método interno do seu idioma para contar ocorrências
  • E / S sem arquivo
  • Não há conexão com um servidor, site, etc.
  • No caso de `ababa`, onde começa com` aba` e se você ler as últimas 3 letras, também é `aba`, você conta apenas uma *

Obrigado @ProgramFOX por isso (a última regra)!
* Dica : ao contar ocorrências, você pode remover as que contou para evitar desobedecer a esta regra

Eu acho que as duas últimas regras são apenas para dobradores de regras!

Critério vencedor

Como indicado anteriormente, o vencedor é o código com menos bytes usados. O vencedor será anunciado cinco dias depois (15 de junho de 2014)

Minha pequena resposta

Aqui está minha resposta em C ++, na qual assume que a livariável contém a string para verificar ocorrências e lé a string a procurar f:

Ungolfed

int c = 0;
while (li.find(lf) != string::npos)
{
    int p = li.find(lf);
    int l = p + lf.length() - 1;
    for (p = p; p <= l; p++)
    {
        li[p] = static_cast<char>(8);
    }
    ++c;
}

Obviamente, para usar std::string, você deve incluir o arquivo de cabeçalho da string!

Golfe

int c=0;while(li.find(lf)!=string::npos){int p=li.find(lf);int l=p+lf.length()-1;for(p=p;p<=l;p++){li[p]=static_cast<char>(8);}++c;}

Resultado

A variável cserá o valor de quantas vezes a cadeia foi encontrada


                                                                          Aproveitar!

Vencedora

Após uma longa espera, a resposta @Dennis vence com apenas 3 bytes, escritos em GolfScript

Comunidade
fonte
5
Devemos contar o mesmo personagem duas vezes? Por exemplo, se a entrada for ababae aba, devemos produzir 1ou 2? O terceiro aé o fim do primeiro abae o começo do segundo aba.
precisa
1
A API da linguagem significa bibliotecas que podem ser importadas (que acompanham a linguagem) ou métodos de tipos de dados ou comandos internos?
seequ
2
Precisa lidar com seqüências de caracteres mais longas do que spara correspondência? Se não: eu tenho uma solução J 5 caractere:+/a=b
ɐɔıʇǝɥʇuʎs
2
A entrada vem através de variáveis ​​ou STDIN?
see
1
Função ou programa?
Kyle Kanos

Respostas:

7

GolfScript, 3 bytes

/,(

Assume que string e substring estão na pilha.

Experimente online.

Como funciona

/  # Split the string around occurrences of the substring.
,  # Get the length of the split array.
(  # Subtract 1.
Dennis
fonte
Impressionante .. Mas eu tenho uma pequena pergunta: você aprendeu o GolfScript apenas para desenvolver código e resolver problemas de código?
1
Eu fiz, mas eu o uso ocasionalmente para outras tarefas até agora. Precisa de uma tabela ASCII? golfscript <<< '127,32,-""+'é mais rápido que abrir um navegador da web.
Dennis
@Dennis [win key] jqt [return] a. [return]é ainda mais rápido;)
#
@ Synthetica: Bem, foi apenas um exemplo. Mas jqtparece interessante. O que é isso?
Dennis
@ Dennis É o console J padrão que vem com J (é um daqueles consoles gráficas, como o iPython QTConsole)
ɐɔıʇǝɥʇuʎs
7

JavaScript 32

Nada realmente interessante aqui ...

(p=prompt)().split(p()).length-1

split O principal objetivo é criar uma matriz a partir de uma string usando o delimitador no argumento.

Michael M.
fonte
split()não faz parte da "API do seu idioma"?
svidgen
2
o objetivo é não contar ocorrências de uma sequência ... então, onde está o limite de APIs autorizadas?
Michael M.
1
@ Michael Peço desculpas por ser vago, isso é aceitável. Editei a pergunta para reformular para "você não pode usar a função ou o método interno do seu idioma para contar ocorrências", portanto, se não se destina ao objetivo da pergunta, você pode usá-lo ...
@ 404NotFound É bom saber ... esta é a minha resposta também? :) ... (+1)
svidgen
1
Esta é a única resposta que não assume que os Vars já foram inicializados, então você recebeu meu voto positivo. Se você assumisse que os vars foram inicializados como todas as outras respostas, teria obtido a.split(b).length-119. Talvez o @svidgen deva esclarecer a inicialização na pergunta.
randunel
2

J (7)

No use of external librariesVerifica! , or your language's API.Verifica...? Não sei o que é uma API de linguagem. You have to implement it manuallyVerifica! No file I/OVerifica! No connecting with a server, website, et ceteraVerifica!

+/a E.b

Como funciona:

E.é WindowedMatch: a Refsheet J fornece 're' E. 'reread'como exemplo. Isso dá 1 0 1 0 0 0. Então, a única coisa que resta a fazer é simplesmente adicionar isso com +/(basicamente sum).

Eu não acho que isso conta como uso your language's built-in function or method for counting occurences, mas isso é discutível.

EDIT: Apenas para ficar claro:

   +/'aba'E.'ababa'
2
ɐɔıʇǝɥʇuʎs
fonte
Eu pensei ababa-> abaera retornar 1?
Kyle Kanos
@KyleKanos Era, mas o autor disse especificamente @Synthetica Absolutley go for it!quando perguntei a ele, então acho que está tudo bem.
ɐɔıʇǝɥʇuʎs
1

C # - 73

//a = "aba";
//b = "ababa";

Console.Write(b.Split(new string[]{a},StringSplitOptions.None).Length-1);

// output = "1"
mnsr
fonte
Está errado! abaaparece duas vezes na Abeba: aba ba ab aba.
2
@Runemoro "Em um caso de ababa, onde ele começa com abae se você ler os últimos 3 letras é também aba, você só contar um *" << Nas regras ..
MNSR
Oh, não leu ...
1

Python 2.x - 49 23 22 bytes

Isso pressupõe que a entrada variável esteja correta. Ambas as strings podem ter qualquer comprimento.

@Avall encurtado.

a='s'
b='aaaabbbbsssffhd'
print~-len(b.split(a))

Versão de 49 bytes, conta todas as instâncias da substring ('aba' está em 'ababa' duas vezes).

a='s'
b='aaaabbbbsssffhd'
print sum(a==b[i:i+len(a)]for i in range(len(b)))
seequ
fonte
Trabalhou com todos os testes eu colocá-lo em ...
E meios de API da linguagem que você tem que usar sua própria função ou método, não use programador da linguagem built-in maneira de fazê-lo (se ele tiver um, eu sou um C ++; ()
Bem, o segundo absolutamente é o método da linguagem para isso. Além disso, o primeiro gera 3 se a='aa'eb é o mesmo. Tudo bem?
seequ
Sim, absolutamente
Além disso, gera 2 para o a='aba'; b='ababa'caso.
seequ
0

Powershell 32

($args[0]-split$args[1]).count-1

Funciona assim:

PS C:\MyFolder> .\ocurrences.ps1 ababa aba
1

Explicação: Utilizado -splitpara separar o primeiro argumento pelo segundo, retorna o tamanho da matriz resultante da divisão (menos 1)

DarkAjax
fonte
0

Applescript, 106 bytes

Applescript é uma linguagem divertida, mas boba, para jogar golfe.

on run a
set AppleScript's text item delimiters to (a's item 1)
(count of (a's item 2)'s text items)-1
end

Corra com osascript:

$ osascript instr.scpt s aaaabbbbsssffhd
3
$ 
Trauma Digital
fonte
0

C # - 66 bytes

//s = "aba"
//t = "ababa"

Console.Write(t.Split(new[]{s},StringSplitOptions.None).Length-1);

//Output: 1
tsavinho
fonte
ri muito. Essa é basicamente a minha resposta. Normalmente, neste site, se você não conseguir encontrar algo diferente de uma resposta existente, poderá dar dicas para a resposta existente sobre como economizar alguns bytes extras.
MNSR
@ Malik Ouça, eu não pude comentar naquele momento. Caso contrário, eu comentei sua resposta. Estou disposto a anotar minha resposta, se você quiser.
tsavinho 12/06
1
Justo. Eu não me importo de qualquer maneira. Eu estava apenas deixando você saber.
MNSR
0

C 130 120

Nota: provavelmente travará se chamado com argumentos incorretos.

r;main(int c,char**a){char*p=*++a,*q,*t;while(*p){for(q=a[1],t=p;*q&&*q==*t;q++)t++;*q?p++:(p=t,r++);}printf("%d\n",r);}

Ungolfed (tipo):

int main(int argc, char *argv[]) {
    int result = 0;
    char *ptr = argv[1];
    while (*ptr) {
        char *tmp, *tmp2 = ptr;
        // str(n)cmp
        for (tmp = argv[2]; *tmp; tmp++, tmp2++)
            if (*tmp != *tmp2)
                break;
        if (*tmp) {
            ptr++;
        } else {
            result++;
            ptr += tmp;
        }
    }
    printf("%d\n", result);
}

Versão antiga com strstre strlen: 103

l;main(int c,char**a){char*p=a[1];l=strlen(a[2]);while(c++,p>l)p=strstr(p,a[2])+l;printf("%d\n",c-5);}
aragaer
fonte
0

Delphi XE3 (113)

Toma 2 strings, remove a substring da string e substratos novo comprimento do antigo, seguido por uma divisão do comprimento da substring.

function c(a,b:string):integer;begin c:=(Length(a)-Length(StringReplace(a,b,'',[rfReplaceAll])))div Length(b)end;

Teste:

c ( 'aaaabbbbsssffhd', 's') = 3
c ( 'aaaabbbbsssffhd', 'a') = 4
-C ( 'ababa', 'ABA') = 1
c ( 'ababa', 'C') = 0

Teun Pronk
fonte
0

Lua (48)

Então, pensei em enviar outra resposta, desta vez em lua. É muito possível que isso possa ser melhorado muito, sou muito novo nisso.

print((a.len(a)-a.len(a.gsub(a,b,"")))/b.len(b))
Teun Pronk
fonte
0

Fortran 90: 101

O abuso padrão de digitação implícita funciona para qualquer matriz de tamanho ae b, embora se deva esperar isso len(a) < len(b).

function i();i=0;k=len(trim(b))-1;do j=1,len(trim(a))-k;if(a(j:j+k)==b(1:1+k))i=i+1;enddo;endfunction

Esta função deve ser containeditada dentro de um programa completo para funcionar. ae bsão recebidos do stdin e podem ser inseridos na mesma linha (separados por vírgula ou espaço) ou em linhas diferentes. Compile via gfortran -o main main.f90e execute como faria com qualquer outro programa compilado.

program main
   character(len=256)::a,b
   read*,a,b
   print*,i()
 contains
   function i()
     i=0
     k=len(trim(b))-1
     do j=1,len(trim(a))-k
        if(a(j:j+k)==b(1:1+k))i=i+1
     end do
   end function
end program main

Testes:

>ababa aba
2

Eu poderia fazer o retorno acima 1 se adicionar 4 caracteres ( ,k+1) para o doloop

> aaaabbbbbsssffhd s
3
Kyle Kanos
fonte
0

Mathematica 26 23

Funciona como o algoritmo de Dennis, mas mais elaborado:

Length@StringCases[a,b]

Três chars raspados pelos szabólicos.

DavidC
fonte
Length@StringCases[a,b]é mais curto. Esse problema não está bem especificado, porque, se não podemos usar StringCount, não está claro se alguma das outras String*funções internas também deve ser permitida ... todas elas são baseadas no mesmo código subjacente.
Szabolcs
Obrigado. Eu esqueci StringCases. Não estava claro para mim o que o OP significava pela API do idioma.
DavidC
Usando o novo operador de composição no Mathematica 10 , podemos até escrever uma função como Length@*StringCases. Isso é mais curto do que Length@StringCases[##]&se tivéssemos que escrever apenas uma função, mas na verdade não a aplicássemos em ae b.
Szabolcs
0

C ++ 225

int n,k,m;
int main()
{
string s1,s2;
cin>>s1;
cin>>s2;
int x=s1.size(),y=s2.size();
if(x>=y)
{
for(int i=0;i<x;i++)
{
k=0,m=0;
for(int j=0;j<y;j++)
{
if(s2[j]==s1[i+m])
{
    k++,m++;
}
else break;
}
if(k==y)
{
n++;
i+=(y-1);
}
}
}
cout<<n<<endl;
return 0;
}
bacchusbeale
fonte
0

Java (38)

System.out.print(a.split(b).length-1);

(A pergunta não exigia um programa ou função completo.)

Ypnypn
fonte
0

Cobra - 25

print a.split(b).length-1
Furioso
fonte
0

K / Kona 6

+/y~'x

Onde xestá a string e ya substring. ~é o operador negate, com ', é aplicado a todos os elementos em x; ele retornará 0se não corresponder e 1se corresponder. Como é aplicado em elementos, o resultado de y~'xé um vetor, o+/ seguida, soma o resultado, fornecendo o número total de ocorrências.

Infelizmente, esse método exige que yhaja apenas um caractere; caso contrário, compararemos uma cadeia de vários caracteres com uma única cadeia de caracteres, resultando em a length error.

Kyle Kanos
fonte