2010-07-15 4 views
3

Есть ли какая-либо реальная последовательность символов, которая всегда сравнивается больше, чем любая другая строка?Можно ли построить бесконечную строку?

Моя первая мысль была о том, что строка построена следующим образом:

std::basic_string<T>(std::string::max_size(), std::numeric_limits<T>::max()) 

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

Любые мысли о том, как достичь этого без possibly_infinite<basic_string<T>>?

+9

Зачем вам это нужно? – kennytm

+5

Опишите цель, а не шаг: http://catb.org/esr/faqs/smart-questions.html#goal – Cogwheel

+7

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

ответ

3

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

Есть ли какая-либо действительная последовательность символов, которая всегда сравнивается больше, чем любая другая строка?

Нет, потому что:

  1. Давайте предположим, что есть строка s что всегда больше, чем любая другая строка.
  2. Если вы сделаете копию с, копия будет равна s. Равный означает «не больше». Следовательно, может быть строка, которая не превышает с.
  3. Если вы делаете копию s и добавляете один символ в конце, он будет больше, чем оригинал s.Следовательно, может быть строка, которая больше s.
  4. Это означает, что невозможно сделать s.

I.e.

Строка s, которая всегда больше, чем любая другая строка, не может существовать. Копия s (копия == другая строка) будет равна s, а «equal» означает «не больше».
Строка s, которая всегда больше или равна любой другой строке, может существовать, если максимальный размер строки имеет разумный предел. Без ограничения по размеру можно будет взять копию s, добавить один символ в конце и получить строку, которая больше s.

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

Можно сделать строку, которая всегда меньше или равна любой другой строке. Строка нулевой длины будет точно такой, что всегда меньше, чем что-либо еще, и равна другим строкам нулевой длины.

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

Не знаете, зачем вам когда-нибудь понадобилось что-то подобное.

+0

Учитывая, что нет такого магического юникодного представления такой строки, и что невозможно на самом деле * использовать * строку максимальной длины, я думаю, это мой ответ. –

+0

Ненависть вызвать старый вопрос, но, конечно же, по этой логике не существует наибольшего целого числа? – katrielalex

+2

@katrielalex: «наибольший» означает «больше или равно» любому другому значению. Это не означает «всегда больше любой другой ценности». Для int32, int64, int16, будет целое число, которое больше или равно любому другому целому числу одного и того же типа. Для unsigned int32 будет 2^32-1 - то есть 0xffffffff. Для bignums, в зависимости от реализации, возможно, что не будет целого числа, которое всегда больше любого другого - вы можете взять это целое число и добавить 1 к нему, чтобы получить большее значение (до тех пор, пока у вас не закончится память). Хотя (для bignums) вы можете ввести константу «бесконечность», которая будет наибольшим целым числом. – SigTerm

2

Возможно, вам нужен пользовательский компаратор, для которого вы определяете значение «бесконечной строки» магии и которое всегда будет рассматривать это значение как большее, чем любое другое.

+0

Я ищу специально для не магического решения, будучи уже осведомленным о подходящем магическом. Спасибо хоть. –

+1

@Jon, что волшебного в написании собственного компаратора? –

+1

@JS: Ничего, особенно. На самом деле это то, что я уже сделал. Я просто искал альтернативные маршруты. И сначала ты сказал «волшебство». : P –

0

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

Или реализовать ленивые строки.

+0

Спасибо, это решение, которое я уже использовал. Под «ленивыми строками» вы подразумеваете строку, которая тайно является генератором? –

+0

Да, например, в синтаксисе haskell: [Data.Char.chr 255 | i <- [1 ..]] (просто не сравнивайте его с собой) – vlabrecque

0

Хорошо, если бы вы динамически построили строку равной длины, сравнимую с ней и заполнили ее самым высоким доступным кодом ASCII (7F для обычного ASCII или FF для расширенного), вам гарантируется, что эта строка будет сравнивать равную или большую, чем та, с которой вы сравниваете ее.

0

Какой у вас компаратор?

Исходя из этого, вы можете построить что-то, что является «вершиной» вашей решетки.

2

Unicode решает много проблем, но не тот. Unicode - это просто другая кодировка для символа, 1, 2 или 4 байта, они все еще хранятся в простом массиве. Вы можете использовать бесконечные строки, когда найдете машину с бесконечной памятью.

+0

Спасибо за окончательное развенчание идеи Unicode. –

2

Yes. Как вы это делаете, я понятия не имею :)

+0

Hah! ...черт. Благодаря? +1 –

+0

+1 для готового мышления! Но -1, потому что максимальный элемент в теоретико-множественном смысле все еще может сравниться с каким-то другим элементом, а Джон хочет строго больше. Так что, не стоит, но спасибо за смех! –

1

Вы должны попытаться указать, чего вы намереваетесь достичь и каковы ваши требования. В частности, есть строка? есть any ограничение на домен? их нужно сравнивать с <?

Вы можете использовать тип нестроковой:

struct infinite_string {}; 
bool operator<(std::string const & , infinite_string const &) { 
    return true; 
} 
bool operator<(infinite_string const &, std::string const &) { 
    return false; 
} 

Если вы можете использовать std::lexicographical_compare и вам не нужно хранить его в виде строки, то вы можете написать бесконечный итератор:

template <typename CharT> 
struct infinite_iterator 
{ 
    CharT operator*() { return std::numeric_limits<CharT>::max(); } 
    infinite_iterator& operator++() { return *this; } 
    bool operator<(const infinite_iterator&) { return true; } 
    // all other stuff to make it proper 
}; 
assert(std::lexicographical_compare(str.begin(), str.end(), 
           infinite_iterator, infinite_iterator)); 

Если вы можете использовать любой другой comparisson функтор и ваш домен имеет некоторые недействительны вы можете использовать это в свою пользу:

namespace detail { 
    // assume that "\0\0\0\0\0" is not valid in your domain 
    std::string const infinite(5, 0); 
} 
bool compare(std::string const & lhs, std::string const & rhs) { 
    if (lhs == detail::infinite) return false; 
    if (rhs == detail::infinite) return true; 
    return lhs < rhs; 
} 
Смежные вопросы