Определите, равны ли строки


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 (или что-то, что оценивается в языке как true или false, например 0 или 1), чтобы указать, совпадают ли строки. Строки должны быть жестко закодированы, как видно из приведенного выше примера. Строки не должны учитываться в гольфе, поэтому, если вы объявите переменную заранее, не считайте объявление.


1
Нужно ли выводить результат или просто написать функцию, возвращающую bool? Если требуется написание полной программы, это может дать ответы типа «взлом» или «сломать» на языках с (относительно) значительным образцом для создания функционирующего исполняемого файла, такого как Java и C # (такова природа зверя, но эта проблема мало что дает. конкретных руководящих принципов, оставляя многое для интерпретации / выбора). И как нам взять струны? Жесткое кодирование, чтение из STDIN, передача в качестве аргументов командной строки?
Тони Эллис

Это [код-гольф] или [конкурс на популярность]? Это не может быть и то и другое.
Гарет

Извините, я изменил свои вопросы, чтобы отразить оба комментария.
Дэвид Чен

Значит, неравенство разрешено?
user80551

Если строки должны быть жестко закодированы более одного раза (каждая), нужно ли считать их длину?
user80551

Ответы:


34

Python 49 45 18 22 15 14

(+ 3, если рассматриваются строковые переменные)

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

Строка должна быть жестко запрограммирована в двух aи в одном экземплярах в bкавычках.

aи bдолжен быть предварительно инициализирован для строк.


Оболочка Python, 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 заменяется значением second. Наконец, мы печатаем значение первого ключа.

РЕДАКТИРОВАТЬ: OP допускает 0/1 вместо False / True, а также с использованием предварительно инициализированных переменных.


@manatwork Golfscript и Perl ниже используют 0/1, я не могу это использовать?
user80551

@manatwork Done
user80551

Я рассчитываю 16 вместо 13, для вашего второго решения.
Абхиджит,

@Abhijit aи bне должны быть включены, строки должны быть там жестко закодированы, поэтому я добавил + 2 * len (str1) + len (str2) + 6 (')
user80551

+1 для умных, но это уже далеко не самое короткое время;)
avalancha

20

Python ( 17 11):

b in a in b

(Проверяет, содержится ли b в a, а a содержится в b, если это не было ясно из кода.)

Альтернативный питон: ( 8 7)

получено из решения Go из Tom Verelst:

b in[a]

Бонус: это работает для любого типа.

РЕДАКТИРОВАТЬ:

Подождите секунду, просто прочитайте, что вы также можете напрямую программировать в строках, и вам не нужно считать кавычки ... (или, по крайней мере, это то, что делает golfscript). Итак ... Python наравне с гольф-скриптом? Боже мой!

Альтернативная альтернатива Python ( 5 4):

(спасибо Клавдиу)

"string"in["string"]

оригинал:

"string" in["string"]

Альтернатива Альтернатива Альтернатива Бенди-рули Питон (2):

"string"is"string"

Ничего не было сказано о сравнительных ключевых словах (это не серьезное представление, просто то, что пришло мне в голову ...)


2
Вы могли бы использовать b in a in b. В и нет необходимости ...
Джордж

2
Теперь это дубликат ответа Виллема .
Манатворк

Вы можете уменьшить его до семи символов, удалив пробел между inи [a]. т.е. b in[a]должен работать.
user3002473

О, не знал этого. Спасибо :)
Marı 19:uʎs

Впечатляет! Также не знал, что
Виллем

14

JavaScript, 11 10

Строки должны храниться в a и b.

!(a>b|a<b)

Редактировать: спасибо Дэнни за указание, |достаточно вместо||


5
Нет, я использую больше и меньше, чем операторы. Те не были запрещены в конкурсе.
Адам Сабо,

2
+1. Это будет работать одинаково и на многих других языках.
Архетип Павел

3
Я могу ошибаться, но вы не можете удалить один |?
Дэнни

3
Определенно, это недосмотр правил - запрещены функции сравнения , равно как и операторы равенства и неравенства , но операторы сравнения не упоминаются.
user2357112 поддерживает Monica

2
@philcolbourn Да, вчера правила изменились, но ответу уже 2 дня.
Бакуриу

8

Руби, 11

s = 'string'
t = 'string'
!!s[t]&t[s]

Проверяет, содержится ли каждая строка в другой.


1
!(a<b||b<a)было бы то же самое ...
Дэвид Херрманн

за исключением того, что вы не можете использовать <>
Philcolbourn

8

Python - 11 (без строк)

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

В том же духе: a<=b<=aвсего 7 символов. Хотя я не знаю, будет ли это сравнение <=считаться «неравенством». Из вопроса видно, что любое сравнение, которое не является проверкой равенства, это нормально, что позволило бы <=.
Бакуриу

да, это здорово @Bakuriu, и я согласен, не совсем ясно, когда правила нарушены или нет. 'in' в конце концов также, как содержит равное утверждение.
Виллем

6

GolfScript (5 символов)

'string1''string1'].&,(

Довольно простой порт реализации PHP-ссылок. Оставляет 0(= false) в стеке, если строки одинаковые, или 1(= true), если они разные.


не работает для меня: 1если строки одинаковы, и 2если они разные. 'string1''string1'].&,1&работает
guy777

@ guy777, это предполагает, что стек пуст в начале. Вопрос довольно расплывчат по фрагментам программы. Вы, вероятно, тестируете ее как целую программу и начинаете с пустой строки в стеке из stdin.
Питер Тейлор

5

Javascript (45 байт):

Вот еще одно решение в Javascript.

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

Пространство важно.

cдолжно быть true.


Только !a.replace(b,'') считается. Таким образом, количество символов должно быть 16. На самом деле, некоторые люди даже считают это 14, так как вы можете указать строку напрямую.
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
Не могли бы вы сойти с рук autoвместо const char*?
aldo

Я думаю, что да, но так как правила гласят, что строковые переменные не учитываются при подсчете символов, я не удосужился поиграть в них.
mattnewport

Не могли бы вы сложить приращения во время теста и оставить тело пустым? И если вы идете для c вместо c ++, удалите int в начале.
Орион

Я не вижу способа уменьшить количество символов, складывая приращения в тесте while, не сталкиваясь с той же ошибкой доступа к строке за концом, которую я указал в ответе Abhijit's C. Вы хотите увеличивать a и b, только если оба теста пройдены (ни a, ни b не указывают на нулевой терминатор, а a равно b). Вероятно, есть способ улучшить это, но я не смог найти его!
mattnewport

3

coreutils: uniq -d

Просто введите две строки в качестве стандартного ввода канала и uniq -d | grep -q .ничего не напечатает, но будет иметь возвращаемое значение успеха или ошибки. Если вы хотите напечатать логическое значение, просто замените наuniq -d | grep -c .

Сколько персонажей? Я позволю тебе считать; uniq -d|grep -q .без лишних пробелов содержит 17 символов, но так как вся работа выполняется uniq, я бы сказал, что это 0-символьное решение на ... uniqсвоем языке!

На самом деле, uniq -dнапечатает одну строку, если две строки идентичны, и ничего, если они разные.


3

Строки должны храниться в a и b. Не будет работать, если есть null.

C #, 53

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

C #, 28

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

3

PHP - 49 символов

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

Может ли что-то подобное работать: !strlen(str_replace($a,'',$b));должно возвращаться 1, если две строки равны?
Дамир Касипович

@ D.Kasipovic Интересно, но я думаю, что это не для $a == 'foo'и $b = 'foofoo':)
Джек

Правда, как насчет этого, он ограничивает замену до одного !strlen(preg_replace("/{$a}/", '', $b, 1));и составляет 45 символов?
Дамир Касипович

Я полагаю , вы могли бы использовать якоря вместо этого, но что более важно , это потребует preg_quote (), а :)
Jack

3

APL ( 8 9)

Обновление: старый не работает для строк разной длины.

{∧/∊⌿↑⍺⍵}
  • ↑⍺⍵: сделать матрицу с первой и второй строкой, заполняя пробелы.
  • ∊⌿: Для каждого столбца посмотрите, содержит ли верхний ряд нижний ряд (как в старой версии).
  • ∧/: Взять логическое andиз всех значений.

Старый:

{∧/⍺∊¨⍵}
  • ⍺∊¨⍵: для каждой комбинации элементов в и , посмотрите, содержит ли элемент из элемента из . Так как в строке все они будут одиночными символами, а строка содержит себя, это в основном сравнивает каждую пару символов.
  • ∧/: взять логическое и все значения (если все символы совпадают, строки равны)

3

Питон - 12

not({a}-{b})

Это решение использует наборы. Вычитание равных наборов приведет к пустому набору, который имеет логическое значение False. Отрицание этого приведет к тому, что значения True для a и b будут равными строками.

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

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

Изменить: Спасибо Питер Тейлор за указание на ненужные пробелы.


Какой выход это дает a="s", b="ss"?
Питер Тейлор

@PeterTaylor: Так как "s"!="ss", это будет выводить False. Чувствительность к регистру также сохраняется. Это даже работает для a="", b="s". Код не преобразует строки в наборы, но создает наборы, содержащие строки.
Varicus

Ах, {}это не то же самое, что set(). Вы можете сохранить 1 символ, удалив пробел.
Питер Тейлор

@PeterTaylor: Спасибо, что указали на ненужные пробелы. {a}эквивалентно set([a]).
Varicus

Как насчет not {a}-{b}?
Уинстон Эверт

3

С - 62

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

Проверено. Позвонить какe(str1, str2)

Если подумать, если не считать char*p,char*q, что кажется справедливым, это всего 49 байтов :)


Добро пожаловать на сайт! В случае проблем с гольф-кодом мы рекомендуем вам вырезать как можно больше байтов из своего кода и указывать количество байтов в заголовке ответа. Проверьте Советы для игры в гольф в C нить для некоторых хороших идей.
Джонатан Ван Матре

Вы действительно не нужно , npи nq. Подойдет один цикл, потому что если вы достигнете конца одной строки раньше другой, они будут иметь другое значение.
Питер Тейлор

Спасибо. Я понимаю это. Я работал над своей сокращенной версией (выше). Возвращаясь, чтобы увидеть, смогу ли я сократить его дальше.
Эммет

*p&*qможет остановить цикл слишком рано (например '0'&'A'==0)
Угорен

@ugoren: Если *p=='0'& *q=='A', мы хотим, чтобы цикл остановился раньше, поскольку мы знаем, что строки не равны.
Эммет

2

Haskell - 9

elem a[b]

Обратите внимание, что это, как и многие другие записи здесь, является просто выражением. Это не программа на Haskell.


2

Ява - 162 147 символов

Идея состоит в том, чтобы сравнить разность каждого байта, одинаковые байты будут иметь разность 0. Программа сгенерирует, java.lang.ArrayIndexOutOfBoundsExceptionкогда байты различаются (попробуйте получить доступ к отрицательному индексу) или когда строки имеют разную длину. Он поймает исключение и вернет 0 (строки не равны) или вернет 1 в противном случае (строки равны).

Сжатый:

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;

Обычный:

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;

Операторы сравнения существуют в цикле.
ζ--

Спасибо @hexafraction, я обновил ответ, чтобы не включать их.
Охотник Хоппера

2

PHP

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

Этот сценарий может не иметь никакой утилиты, но, по крайней мере, это позволяет сравнивать строки.

PHP

Еще один:

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

1
Вау, очень мило. И выполнение этого может сделать возможным использование любой строки (с пробелами и юникодом).
Дэвид Чен

2

Пролог 7

e(A,A).

Это позволяет использовать функцию сопоставления с образцом в Прологе, чтобы объединить 2 аргумента с предикатом, что эффективно проверяет эквивалентность эквивалентности, когда нет несвязанной переменной .

Пример использования:

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

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

Технически говоря, поведение этого решения - поведение оператора объединения =/2, а не оператора ==/2, который проверяет эквивалентность терминов. Разница показывает, когда задействованы несвязанные переменные. В этом решении, когда указана несвязанная переменная, предикат вернется trueпосле успешного объединения. Для сравнения, ==/2сравним порядок сроков без унификации.


2

PHP, 21

Этот делает работу, используя переменную косвенность.

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

Или, если вам не нужно быть булой

$$a=$b;$$b;

РЕДАКТИРОВАТЬ : я забыл обработать случай, когда вы пытаетесь сравнить две пустые строки, поэтому код сейчас

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

что составляет 21 символ.


Я ожидал, что это приведет к ошибкам при задании строк, которые не являются допустимыми идентификаторами, но, к моему удивлению, это не так.
Питер Тейлор

Две проблемы: 1. Возвращает true при сравнении "0" и "". 2. Возвращает true, когда $ b - это имя существующей переменной (в текущей таблице символов), значение которой преобразуется в true (например, «GLOBALS» или «_SERVER» в глобальной области видимости или «b» в любой области видимости), даже когда $ b не равно $ a.
Пожалуйста, установите

2

CPython: 6

a is b

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

Использование, isочевидно, довольно подозрительно, но поскольку задача специально призывает к тому, чтобы мы определяли равенство значений, а не эталонное равенство, а isсравнивала только идентичность объекта, я чувствую, что она может не попасть в список запрещенных операторов.

Конечно, есть также некоторый вопрос относительно того, действительно ли это даже; это работает на всех моих системах, но это зависит от реализации и, вероятно, не всегда будет работать, если строки не определены вручную в интерактивном интерпретаторе.


2

Mathematica / Wolfram Language, 15 байтов

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

Довольно понятно, устанавливает каждую строку как набор, а затем проверяет длину объединения двух наборов. Если строки совпадают, возвращает 1, в противном случае возвращает 0. Если мне разрешено возвращать «2» для «другого» и «1» для «одного и того же», вычтите два байта.


2

C 342 в гольфе

#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;
}

Примечание: Visual Studio жалуется, если вы не используете их безопасные методы, например gets_s. CodeBlocks с Mingw компилируется без предупреждений.

C 655 не в гольф

Код создает взвешенную сумму символов для каждой строки. Если разница равна нулю, то они равны, включая 2 пустые строки:

    #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();
}

Хорошая работа, но вы, вероятно, должны играть в гольф.
Hosch250

Я не могу скомпилировать ваше представление. Я получаю "Неопределенные символы для архитектуры x86_64:" _gets_s ", на которые ссылается: _main in golf-310cf2.o ld: символ (ы) не найден для архитектуры x86_64"
Стивен Мелвин,

2

питон

Это долго и не красиво, но это моя первая запись!

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 байт

Я предполагаю, что вам запрещено использовать любые операторы сравнения. Так <или >включены.

Идея состоит в том, чтобы использовать побитовый XOR. В разных языках этот оператор имеет разный синтаксис - я покажу пример для PHP. Там это доступно с ^. К сожалению, его поведение со строками не так хорошо, как могло бы быть, поэтому вам нужно проверить длину строки раньше. Это связано с тем, что в PHP xor обрезает более длинную строку до длины более короткой.

Следующим шагом является правильная работа со строками, потому что один xorне даст результата, доступного для дальнейших операций в PHP. Вот почему unpack()был использован. Итак, код будет:

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

Это длиннее, чем опция с </, >но он не будет их использовать. Кроме того, важна жонглирование типов PHP (поэтому будет приведен пустой массив false). Или, может быть, есть более простой способ проверить, содержит ли массив ненулевые члены ( Правка : хотя я уже набирал это, есть хороший улов trim()в другом ответе, поэтому мы можем избавиться от операций с массивами)

Но я верю, что есть языки, на которых мы можем просто a ^ b- буквально, получить результат. Если это 0(обрабатывается из всех приведенных байтов) - тогда наши строки равны . Это очень легко и даже проще, чем <или >вещи.


1

grep 14 символов

Конечно, я считаю только код grep; эти две строки находятся на двух последовательных строках ввода (либо канал, либо файл, либо даже интерактивный сеанс).

$ 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 символов (после того, как строки в переменных)

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

Код, включающий присвоения, будет:

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

1

Очень сумасшедший путь

Просто для удовольствия, но есть много способов заставить его потерпеть неудачу, если задуматься. Более того, не забывайте, что строки будут исполняться оболочкой.

$ 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

Хорошим контрпримером является сравнение «string» в качестве первой строки и «rm -Rf /» в качестве второй строки; просто проверьте как root и посмотрите: он скажет "true", хотя обе строки явно не одинаковы.


1

JavaScript [18 байт]

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

ИЛИ

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

Это вернется, trueесли a == bи falseесли a =/= b. Логика заключается в создании объекта со значением aкак свойство и возвращении 1или undefinedв случае, если свойство bзначения существует или не существует в этом объекте.


Правила гласят, что вам разрешено возвращать объект, который оценивается как true или false, поэтому в !!этом нет необходимости
James_pic

@James_pic Да, но в противном случае он вернет 1или undefined(или объект / undefinedдля второго случая).
VisioN

Я интерпретировал правила как высказывание, что значения true-y и false-y подойдут вместо true и false, поэтому я думаю, что 1 или undefined были достаточно хорошими.
James_pic

@James_pic Я просто хотел быть в безопасности :) Если так, то 18-2 = 16 bytes.
VisioN

1

JavaScript [15 байт]

![a].indexOf(b)

Это вернется, trueесли a == bи falseесли a =/= b. Скрипт ищет значение bв массиве, который содержит единственный элемент значения a.


1

С - 86 83

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

Obvioulsy не самый короткий, но это не работает со строковыми переменными и вместо этого принимает строки в качестве ввода из консоли. Кроме того, мне нравится рекурсивный main, даже если это явно не самая короткая версия. Но, безусловно, наименее рекомендуется.


Вам не нужно пробелов вокруг многих операторов. Например, char** vможно записать как char**v. Есть некоторые исключения (например 42 / *pointer), но в большинстве случаев пробелы могут быть безопасно удалены возле специальных символов.
Конрад Боровски

И аперсанд слишком большой. Не на вершине сегодня.
ВОО
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.