문자열이 같은지 확인


29

당신의 작업은 간단 합니다. 하나 개의 문자열이 평등 연산자를 사용하지 않고 다른 (안 주소 값) (예 : 동일한 경우 결정 ==, ===또는 .equal()) 또는 불평등 ( !=, !==다른 언어와 유사) 아무것도. 이것은 어디서나 의미합니다! 코드의 어느 곳에서나이 연산자를 사용할 수 없습니다. 그러나를 !exp직접 비교하지 않는 등의 전환을 사용할 수 있습니다 exp != with something else.

또한 strcmp , strcasecmp 등과 같은 기능을 사용할 수 없습니다 .

비교 연산자에 관해서는 ( >=, <=, >, <), 그들은 또한 허용 . 나는 일부 답변에 이것이 포함된다는 것을 알고 있지만 평등 연산자와 경계를 이루지 않는 더 많은 답변을보고 싶습니다.


PHP를 사용하는 예는 다음과 같습니다.

<?php

$a = 'string';
$b = 'string';

$tmp = array_unique(array($a, $b));

return -count($tmp) + 2;

문자열이 일치하는지 여부를 나타 내기 위해 true 또는 false (또는 언어에서 0 또는 1과 같이 true 또는 false로 평가되는 항목)를 반환하십시오. 위 예제에서 문자열을 하드 코딩해야합니다. 골프에서는 문자열을 세지 않아야하므로 변수를 미리 선언하면 선언을 세지 마십시오.


1
결과를 출력하거나 단순히 bool을 반환하는 함수를 작성해야합니까? 완전한 프로그램을 작성해야하는 경우 Java 및 C #과 같은 작동 가능한 실행 파일을 작성하기 위해 중요한 상용구가있는 언어로 대답 할 수 있습니다. 구체적인 지침의 해석, 선택에 많은 영향을 미침). 그리고 우리는 어떻게 현을 가져 가야합니까? STDIN에서 읽는 하드 코딩이 명령 행 인수로 전달됩니까?
Tony Ellis

이것이 [code-golf]입니까 아니면 [popularity-contest]입니까? 둘 다 될 수 없습니다.
Gareth

죄송합니다. 두 의견을 모두 반영하도록 질문을 수정했습니다.
David Chen

불평등이 허용됩니까?
user80551

문자열을 두 번 이상 (각) 하드 코딩 해야하는 경우 길이를 계산해야합니까?
user80551

답변:


34

파이썬 49 45 18 22 15 14

(문자열 변수를 고려하면 + 3)

print{a:0,b:1}[a]

문자열은 따옴표로 묶인 두 번 a및 한 번 으로 하드 코딩되어야 b합니다.

ab문자열에 사전 초기화해야합니다.


파이썬 셸, 9

(문자열 변수를 고려하면 + 3)

{a:0,b:1}[a]

쉘에서 출력

>>> a = 'string'
>>> b = 'string'
>>> {a:0,b:1}[a]
1
>>> a = 'string'
>>> b = 'stringgg'
>>> {a:0,b:1}[a]
0
>>> {'string':0,'string':1}['string']
1
>>> {'stringggg':0,'string':1}['stringggg']
0
>>> 

설명

첫 번째와 두 번째 문자열의 키를 사용하여 dict (해시 테이블)를 만듭니다. 두 번째 문자열이 동일하면 first의 값이 초의 값으로 대체됩니다. 마지막으로 첫 번째 키의 값을 인쇄합니다.

편집 : OP는 False / True 대신 0/1을 허용하고 사전 초기화 된 변수를 사용했습니다.


@manatwork Golfscript와 아래의 perl은 0/1을 사용합니다.
user80551

@manatwork 완료
user80551

두 번째 솔루션으로 13 대신 16을 계산합니다.
Abhijit

@Abhijit ab포함 할되지는 문자열 내가 + 2 * LEN (STR1) + 렌 (STR2) + 6 ( ') 추가 그 이유는, 하드 코딩이 있어야한다
user80551

clevernesse의 경우 +1이지만 더 이상 가장 짧지는 않습니다.)
avalancha

20

파이썬 ( 17 11) :

b in a in b

(코드에서 명확하지 않은 경우 b가 a에 포함되어 있고 a가 b에 포함되어 있는지 확인합니다.)

대체 파이썬 : ( 8 7)

Tom Verelst의 Go 솔루션에서 파생되었습니다.

b in[a]

보너스 : 이것은 모든 유형에 적용됩니다.

편집하다:

잠깐만, 문자열로 직접 프로그래밍 할 수 있고 따옴표를 세지 않아도됩니다 (또는 적어도 골프 스크립트가하는 일). 그래서 ... 골프 스크립트와 동등한 Python? 어머!

대체 대체 Python ( 5 4) :

(클라우드 감사합니다)

"string"in["string"]

기발한:

"string" in["string"]

대안 대안 대안 Bendy-ruly Python (2) :

"string"is"string"

비교 키워드 에 대해서는 언급 된 바가 없습니다 (심각한 제출이 아니며 나에게 발생한 것입니다 ...)


2
사용할 수 있습니다 b in a in b. 과는 필요하지 않습니다 ...
조지

2
이제 willem 's answer의 복제본입니다 .
manatwork

in와 사이의 공백을 제거하여 7 자로 줄일 수 있습니다 [a]. 즉 b in[a]작동해야합니다.
user3002473

아, 몰랐어 감사합니다 :)
ɐɔıʇǝɥʇuʎs

인상적! 또한 알지 못했습니다
Willem

14

자바 스크립트, 11 10

문자열은 a와 b에 저장해야합니다.

!(a>b|a<b)

편집 : 지적 해 주셔서 감사합니다 대니, |대신 충분합니다||


5
아니요, 크고 작은 연산자를 사용하고 있습니다. 그들은 대회에서 금지되지 않았습니다.
Adam Szabo

2
+1. 이것은 다른 많은 언어에서도 동일하게 작동합니다.
Archetypal Paul

3
틀렸을 수도 있지만 제거 할 수 |없습니까?
Danny

3
평등 및 불평등 연산자 와 마찬가지로 규칙 감독 비교 함수 도 금지 되지만 비교 연산자 는 언급되지 않았습니다.
user2357112는 Monica

2
@philcolbourn Yes, rules changed yesterday but answer is 2 days old.
Bakuriu


8

Python - 11 (without the strings)

>>> a = 'ss'
>>> b = 's'
>>> a in b in a
False

In the same spirit:a<=b<=a which is only 7 characters. Although I don't know whether the comparison <= would be considered an "inequality". From the question it appears that any comparison that is not an equality check is okay, which would allow <=.
Bakuriu

yeah, thats a nice one @Bakuriu, and I agree, its not totally clear when the rules are violated or not. 'in' after all alsoome how contains an equal statement.
Willem

6

GolfScript (5 chars)

'string1''string1'].&,(

Fairly straightforward port of the PHP reference implementation. Leaves 0 (=false) on the stack if the strings are the same, or 1 (=true) if they're different.


doesn't work for me: 1 if the string are the same, and 2 if they're different. 'string1''string1'].&,1& works
guy777

@guy777, this assumes that the stack is empty at the start. The question is rather vague on program fragments. You're probably testing it as a whole program and starting with an empty string on the stack from stdin.
Peter Taylor

5

Javascript (45 bytes):

Here is another solution in Javascript.

var a='string',b='string',c=!a.replace(b,'');

The space is important.

c should be true.


Only !a.replace(b,'') is counted. So character count should be 16. Actually, some people even count it 14, since you can specify the string directly.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

5

C++, 63 58 56

const char* a = "string";
const char* b = "string";
int main(){while(*a**b*!(*a^*b))++a,++b;return!(*a^*b);}

2
Could you get away with auto instead of const char*?
aldo

I think so yes, but since the rules say the string variables aren't counted towards the character count I didn't bother to golf them.
mattnewport

Could you fold increments into the while test and leave the body empty? And if you go for c instead of c++, remove int at the beginning.
orion

I don't see any way to reduce the character count by folding the increments into the while test without hitting the same bug of accessing a string past the end I pointed out in Abhijit's C answer. You only want to increment a and b if both tests pass (neither a nor b is pointing to the null terminator and a is equal to b). There's probably a way to improve on this but I haven't been able to find it!
mattnewport

3

coreutils: uniq -d

Just enter your two strings as the standard input of a pipe and uniq -d | grep -q . will print nothing but will have a return value of success or error. If you want to print the boolean, just replace with uniq -d | grep -c .

How many characters? I let you count; uniq -d|grep -q . with no extra spaces has 17 characters in it, but since the whole job is performed by uniq, I would say this solution is a 0-character one in... uniq own language!

Actually, uniq -d will print one line if the two strings are identical, and nothing if the are different.


3

Strings have to be stored in a and b. Will not work if either is null.

C#, 53

string.IsNullOrEmpty(a.Replace(b,"")+b.Replace(a,""))

C#, 28

a.Contains(b)&&b.Contains(a)

3

PHP - 49 characters

!(strlen($a)^strlen($b)|strlen(trim($a^$b,"\0")))

Couldn't something like this work: !strlen(str_replace($a,'',$b)); It should return 1 if two strings are equal?
Damir Kasipovic

@D.Kasipovic Interesting, but I think it fails for $a == 'foo' and $b = 'foofoo' :)
Jack

True, how about this then, it limits replace to one !strlen(preg_replace("/{$a}/", '', $b, 1)); and is 45 characters?
Damir Kasipovic

I suppose you could use anchors instead, but more importantly it would require preg_quote() as well :)
Jack

3

APL (8 9)

Update: the old one does not work for strings of different lengths.

{∧/∊⌿↑⍺⍵}
  • ↑⍺⍵: make a matrix with on the first line and on the second line, filling blanks with spaces.
  • ∊⌿: For each column, see if the upper row contains the lower row (as in the old version).
  • ∧/: Take the logical and of all the values.

Old one:

{∧/⍺∊¨⍵}
  • ⍺∊¨⍵: for each combination of elements in and , see if the element from contains the element from . Since in a string these will all be single characters, and a string contains itself, this is basically comparing each pair of characters.
  • ∧/: take the logical and of all the values (if all the characters match, the strings are equal)

3

Python - 12

not({a}-{b})

This solution uses sets. Subtracting equal sets will result in an empty set, which has a boolean value of False. Negating that will result in a True value for a and b being equal strings.

>>> a="string1"
>>> b="string2"
>>> not({a}-{b})
False

>>> a="string"
>>> b="string"
>>> not({a}-{b})
True

Edit: Thanks to Peter Taylor for pointing out the unnecessary whitespace.


What output does this give for a="s", b="ss"?
Peter Taylor

@PeterTaylor: Since "s"!="ss", it will output False. Case sensitivity is also preserved. It even works for a="", b="s". The code does not convert strings to sets, but creates sets containing the strings.
Varicus

Ah, {} isn't the same as set(). You can save 1 char by removing the whitespace.
Peter Taylor

@PeterTaylor: Thanks for pointing out the unnecessary whitespace. {a} is equivalent to set([a]).
Varicus

How about not {a}-{b}?
Winston Ewert

3

C — 62

e(char*p,char*q){for(;*p&*q&&!(*p^*q);q++,p++);return!(*p^*q);}

Tested. Call as e(str1, str2)

Come to think of it, if you don't count the char*p,char*q, which seems only fair, it's only 49 bytes :)


Welcome to the site! For code-golf challenges, we encourage you to trim as many bytes from your code as you can, and post the byte count in your answer header. Check out the Tips for Golfing in C thread for some good ideas.
Jonathan Van Matre

You don't really need np and nq. One loop will do, because if you reach the end of one string before the other they will have a different value.
Peter Taylor

Thanks. I realize that. I was working on my shortened version (above). Going back to see if I can shorten it further.
Emmet

*p&*q may stop the loop too early (e.g. '0'&'A'==0)
ugoren

@ugoren: If *p=='0' & *q=='A', we want the loop to stop early, as we know the strings are not equal.
Emmet

2

Haskell -- 9

elem a[b]

Note that this, just like many entries here, is just an expression. This is not a Haskell program.


2

Java - 162 147 characters

The idea is to compare the difference of each byte, same bytes will have difference 0. The program will throw java.lang.ArrayIndexOutOfBoundsException for when bytes are different (try to access a negative index) or when strings are of different length. It will catch the exception and return 0 (strings not equal), or return 1 otherwise (strings equal).

Compressed:

String a = "12345";
String b = "12345";
byte[]x=a.getBytes(),y=b.getBytes();int z,i=a.length()-b.length();try{for(byte d:x){z=d-y[i];z=x[-z*z];i++;}}catch(Exception e){return 0;}return 1;

Normal:

String a = "12345";
String b = "12345";
byte[] byteArrA = a.getBytes();
byte[] byteArrB = b.getBytes();

int byteDifference = 0;
int i = a.length() - b.length();

try {
    for (byte aByte : byteArrA) {
        byteDifference = aByte - byteArrB[i];
        byteDifference = byteArrA[-byteDifference*byteDifference];
        i++;
    }
} catch (Exception e){
    return 0;
}

return 1;

Comparison operators exist in the loop.
ζ--

Thank you @hexafraction, I updated answer to not include them.
Hopper Hunter

2

PHP

    $string = 'string';
    isset( ${'string'} );

This script may not have any utility, but atleast this provides a way to compare strings.

PHP

Aother one:

    $string = 'something';
    $text   = 'something';
    return count( array( $string => 1 , $text => 1 ) ) % 2;

1
Wow very lovely. And doing it like this can make it possible to use any string (with spaces and unicode).
David Chen

2

Prolog 7

e(A,A).

This makes use of the pattern matching feature in Prolog to unify the 2 arguments to the predicate, which effectively tests for equals equivalence when there is no unbound variable.

Sample usage:

?- e("abcd", "Abcd").
false.

?- e("abcd", "abcd").
true.

Technically speaking, the behavior of this solution is that of unification operator =/2, rather than that of ==/2, which checks for term equivalence. The difference shows when unbound variables are involved. In this solution, when unbound variable is supplied, the predicate will return true when unification is successful. In comparison, ==/2 will compare order of term without unification.


2

PHP, 21

This one is doing the job using variable indirection.

$$a=$b;!!$$b;

Or, if you don't need it to be bool

$$a=$b;$$b;

EDIT : I forgot to handle the case where you try to compare two empty strings, so the code now is

$$a=$b;!($a.$b)||$$b;

which is 21 chars.


I expected this to give errors when given strings which aren't valid identifiers, but to my surprise it doesn't.
Peter Taylor

Two problems: 1. Returns true when comparing "0" and "". 2. Returns true when $b is the name of an existing variable (in the current symbol table) having a value that converts to true (e.g. "GLOBALS" or "_SERVER" in global scope, or "b" in any scope), even when $b is not equal to $a.
PleaseStand

2

CPython: 6

a is b

>>> a = 'string'
>>> b = 'string'
>>> c = 'STRING'
>>> a is b
True
>>> a is c
False

The use of is is obviously pretty suspect, but since the task specifically calls out that we're to determine value equality rather than reference equality, and is only compares object identity, I feel like it may not fall under the list of banned operators.

Of course there's also some question as to whether this is even valid; it works on all of my systems, but it's implementation-specific and probably won't always work if the strings aren't defined by hand in the interactive interpreter.


2

Mathematica / Wolfram Language, 15 bytes

2 - Length[{a} ∪ {b}]

Pretty self explanatory, sets each string as a set, then checks the length of the union of the two sets. If the strings are the same, returns 1, otherwise returns 0. If I'm allowed to return '2' for "different" and '1' for "same", subtract two bytes.


2

C 342 golfed

#include <stdio.h>
#define N 100
#define P(x) printf("%s\n",x)
#define G(x) gets(x)
void e(int x){x?P("y"):P("n");}
int main(){
char s[N],t[N];char *p,*q;int r=0; int n=0,m=0;int i=1;p=s,q=t;
if((p=G(s))&&(q=G(t))){while (*p){n+=i*(int)*p;m+=i*(int)*q;i++;p++;q++;if(!(*q)){break;}}
if(!*p&!*q){if(!(m-n)){r=1;}}e(r);}
return 0;
}

Note: Visual Studio complains if you don't use their safe methods eg gets_s. CodeBlocks with mingw compiles without warnings.

C 655 not golfed

Code creates weighted sum of chars for each string. If the difference is zero then they are equal, including 2 empty strings:

    #include <stdio.h>
#define N 100
#define P(x) printf(x)
#define G(x) gets_s(x)

void e(int x){ x ? P("equal\n") : P("not equal\n"); }
int main()
{
    char s[N], t[N];//words
    char *p = 0, *q = 0;
    int r = 0; //result 0=false
    int n=0, m=0; //weighted sums
    int i = 1; //char pos start at 1
    if ((p=gets_s(s)) &&
        (q=gets_s(t)))
    {
        while (*p)
        {
            n += i*(int)*p;
            m += i*(int)*q;
            i++;
            p++;
            q++;
            if (!(*q)){
                break;
            }
        }

        if (!*p && !*q){ //both same length strings
            if (!(m - n)){ r = 1; } //weighted sums are equal           
        }//else r=0, false=>not equal

        e(r);
    }
    else{
        P("error\n");
    }
    getchar();
}

Nice job, but you should probably golf it.
Hosch250

I can't compile your submission. I get "Undefined symbols for architecture x86_64: "_gets_s", referenced from: _main in golf-310cf2.o ld: symbol(s) not found for architecture x86_64"
Stephen Melvin

2

Python

It's long and it's not beautiful, but this is my first entry!

def is_equal(a,b):
    i=0
    a,b=list(a),list(b)
    if len(a)>len(b):
        c=a
        lst=b
    else:
        c=b
        lst=a
    try:
        while i<len(c):
            for j in c:
                if j not in lst[i]:
                    return False
                i+=1
    except IndexError:
        return False
    return True

2

PHP, 68 Bytes

I assume you're prohibited to use any comparison operators. So < or > are included.

The idea is to use bitwise XOR. In different languages this operator has different syntax - I'll show an example for PHP. There it's available with ^. Unfortunately, its behavior with strings isn't as good as it could be, so you'll need to check string length before. That is because in PHP, xor will strip the longer string down to the length of the shorter string.

Next thing is to work with strings properly, because a single xor will not produce a result, available for further operations in PHP. That's why unpack() was used. So, the code would be:

return !(strlen($a)^strlen($b)) & !array_filter(unpack('c*', $a^$b))

It's longer than option with < / > but it won't use them. Also, the important thing is about PHP type juggling (so empty array will be cast to false). Or maybe there's a simpler way to check if an array contain non-zero members (Edit: while I've been typing this, there's a good catch with trim() in another answer, so we can get rid of array operations)

But I believe there are languages, where we can do just a ^ b - literally, getting the result. If it's 0 (treated from all resulted bytes) - then our strings are equal. It's very easy and even more simple than < or > stuff.


1

grep 14 characters

Of course, I only count the grep code; the two strings are on two consecutive lines in the input (either a pipe or a file or even an interactive session).

$ echo -e 'string\nstring' | grep -cPzo "(?s)^(\N*).\1$"
1
$ echo -e 'string\nstring1' | grep -cPzo "(?s)^(\N*).\1$"
0
$ echo -e 'string1\nstring' | grep -cPzo "(?s)^(\N*).\1$"
0

1

Matlab: 12 chars (after the strings are in variables)

~(x*x'-y*y')

The code including assignments would be:

x='string1'
y='string2'
~(x*x'-y*y')

1

The very crazy way

Just for the fun, but many ways for making it fail if one thinks about it. More over, don't forget the strings will be EXECUTED by the shell.

$ echo -e 'string\nstring1' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true
$ echo -e 'string\nstring' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true
true
$ echo -e 'string1\nstring' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true

A good counter-example is comparing "string" as first string and "rm -Rf /" as a second string; just check as root and see: it will say "true" though both strings obviously aren't the same.


1

JavaScript [18 bytes]

(_={})[a]=1,!!_[b]

OR

!!((_={})[a]=_)[b]

This will return true if a == b and false if a =/= b. The logic behind is creating an object with a value of a as a property and returning 1 or undefined in case if a property of b value exists or doesn't exist in that object.


The rules say you're allowed to return an object that evaluates to true or false, so the !! is not necessary
James_pic

@James_pic Yeah, but otherwise it will return 1 or undefined (or object/undefined for the second case).
VisioN

I interpreted the rules as saying that truth-y and false-y values would do in place of true and false, so I'd think that 1 or undefined were good enough.
James_pic

@James_pic I just wanted to be on the safe side :) If so, then 18-2 = 16 bytes.
VisioN

1

JavaScript [15 bytes]

![a].indexOf(b)

This will return true if a == b and false if a =/= b. The script is looking for the value of b in the array that holds a single element of value of a.


1

C - 86 83

main(int i,char**v){return*v[1]&!(*v[1]++^*v[2]++)?main(3,v):!(*--v[1]^*--v[2]);}

Obvioulsy not the shortest, but this doesn't work with string variables and instead takes the strings as input from the console. Also, I sort of like the recursive main, even if it's obviously not the shortest version. But certainly the least advisable.


You don't need spaces around many operators. For example, char** v can be written as char**v. There are some exceptions (like 42 / *pointer), but in most cases spaces can be safely removed near special characters.
Konrad Borowski

And an apersand too much. Not on top today.
SBI
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.