Хотя это не решение для списков напрямую, numpy
действительно сияет для такого рода вещей:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]
возвращает:
ii ==>array([2, 8])
Это может быть значительно быстрее для списки (массивы) с большим количеством элементов по сравнению с некоторыми другими решениями.
Я рекомендую избегать std::wstring
в Windows или в другом месте, за исключением случаев, когда это требуется интерфейсом, или где-нибудь рядом с вызовами Windows API и соответствующими преобразованиями кодировки в качестве синтаксического сахара.
Мой взгляд обобщен в http://utf8everywhere.org , из которых я являюсь соавтором.
Если ваше приложение не ориентировано на API, например. в основном приложение UI, рекомендуется хранить строки Unicode в std :: string и кодироваться в UTF-8, выполняя преобразование около вызовов API. Преимущества, изложенные в статье, перевешивают явное раздражение конверсии, особенно в сложных приложениях. Это вдвойне подходит для многоплатформенной и библиотечной разработки.
И теперь, отвечая на ваши вопросы:
Итак, каждый читатель здесь должен иметь четкое представление о фактах, ситуации.
Мое прагматическое заключение шокирует просто: все, что C ++ (и STL) «кодирование символов» существенно нарушено и бесполезно. Виноват это в Microsoft или нет, это все равно не поможет.
Мое решение, после глубокого расследования, много разочарования и последующего опыта заключается в следующем:
typedef std::string UTF8String
) typedef std::wstring UCS2String
) - это компромисс , и концессию на беспорядок, введенный WIN32 API). UCS-2 является достаточным для большинства из нас (подробнее об этом позже ...). UCS2String ConvertToUCS2( const UTF8String &str );
UTF8String ConvertToUTF8( const UCS2String &str );
Преобразования просты, Google должен помочь здесь ...
Вот и все. Используйте UTF8String везде, где важна память, и для всех входов / выходов UTF-8. Используйте UCS2String везде, где строка должна анализироваться и / или обрабатываться. Вы можете конвертировать между этими двумя представлениями в любое время.
Альтернативы & amp; Улучшения
const wchar_t tt_iso88951[256] = {0,1,2,...};
и соответствующий код для преобразования в & amp; из UCS2. typedef std::basic_string<uint32_t> UCS2String
) ICU или другие библиотеки Unicode?
wide
зависит от реализации. Visual C ++ по умолчанию имеет значение 16 бит, если я правильно помню, в то время как настройки GCC по умолчанию зависят от цели. Здесь 32 бита. Обратите внимание: wchar_t (широкий тип символа) не имеет ничего общего с юникодом. Просто гарантируется, что он может хранить все элементы самого большого набора символов, поддерживаемые реализацией его локалями, и, по крайней мере, до тех пор, пока char. Вы можете сохранить строки unicode в std::string
с помощью кодировки utf-8
. Но это не будет понимать смысл кодов Unicode. Таким образом, str.size()
не даст вам количество логических символов в вашей строке, а просто количество элементов char или wchar_t, хранящихся в этой строке / wstring. По этой причине пользователи обложек gtk / glib C ++ разработали класс Glib::ustring
, который может обрабатывать utf-8. Если ваш wchar_t имеет длину 32 бита, вы можете использовать utf-32
в качестве кодировки в Юникоде, и вы можете хранить строки с кодом юникода и с использованием фиксированного (utf-32 фиксированной длины). Это означает, что функция s.size()
вашей wstring будет , затем вернет правильное количество логических символов wchar_t элементов и . std::wstring
.
– Deduplicator
8 January 2015 в 23:20
Хороший вопрос! Я думаю, что DATA ENCODING (иногда CHARSET также участвует) является MEMORY EXPRESSION MECHANISM, чтобы сохранить данные в файл или передавать данные по сети, поэтому я отвечаю на этот вопрос следующим образом:
1.Когда я должен использовать std: : wstring over std :: string?
Если платформа программирования или функция API являются однобайтными, и мы хотим обрабатывать или анализировать некоторые данные в формате unicode, например, читать из файла Windows .REG или сети Windows 2-байтовый поток, мы должны объявить переменную std :: wstring, чтобы упростить их обработку. например: wstring ws = L "中国 a" (6 октетов: 0x4E2D 0x56FD 0x0061), мы можем использовать ws [0] для получения символов '中' и ws [1] для получения символов '国' и ws [2] get character 'a' и т. д.
2.Can std :: string содержит весь набор символов ASCII, включая специальные символы?
Да. Но обратите внимание: American ASCII означает, что каждый октет 0x00 ~ 0xFF для одного символа, включая печатный текст, такой как «123abc & amp; * _ & amp;» и вы сказали специальный, в основном напечатайте его как «.». избегайте запутывания редакторов или терминалов. И некоторые другие страны расширяют свою собственную кодировку «ASCII», например. Китайцы, используют 2 октета для обозначения одного персонажа.
3.Is std :: wstring поддерживается всеми популярными компиляторами C ++?
Возможно, или в основном. Я использовал: VC ++ 6 и GCC 3.3, YES
4. Что такое «широкий символ»?
Широкий символ в основном указывает использование 2 октетов или 4 октета всех стран. 2 октета UCS2 представляет собой репрезентативную выборку, а далее, например, Английский 'a', его память составляет 2 октета 0x0061 (vs в ASCII 'a - 1 октет 0x61)
1) Как упоминалось Грегом, wstring полезна для интернационализации, то есть когда вы будете выпускать свой продукт на других языках, кроме английского
4) Проверьте это для широкого символа http: / /en.wikipedia.org/wiki/Wide_character
Приложения, которые не удовлетворяются только 256 различными символами, имеют варианты использования широких символов (более 8 бит) или кодирования переменной длины (многобайтовая кодировка в терминологии C ++), таких как UTF-8. Широким символам обычно требуется больше места, чем кодирование с переменной длиной, но они быстрее обрабатываются. Многоязычные приложения, которые обрабатывают большие объемы текста, обычно используют широкие символы при обработке текста, но преобразуют его в UTF-8, когда хранят его на диске.
Единственное отличие между string
и wstring
- тип данных символов, которые они хранят. Строка хранит char
s, размер которой должен быть не менее 8 бит, поэтому вы можете использовать строки для обработки, например. ASCII, ISO-8859-15 или UTF-8. В стандарте ничего не говорится о наборе символов или кодировке.
Практически каждый компилятор использует набор символов, первые 128 символов которого соответствуют ASCII. Это также относится к компиляторам, использующим кодировку UTF-8. Важное значение, которое следует учитывать при использовании строк в UTF-8 или какой-либо другой кодировке переменной длины, состоит в том, что индексы и длины измеряются в байтах, а не в символах.
Тип данных wstring wchar_t
, размер которого не определен в стандарте, за исключением того, что он должен быть как минимум равным char, обычно 16 бит или 32 бита. wstring может использоваться для обработки текста в реализации, определенной широкосимвольной кодировкой. Поскольку кодировка не определена в стандарте, преобразовать между строками и wstrings непросто. Нельзя предположить, что wstrings также будет иметь кодировку с фиксированной длиной.
Если вам не нужна поддержка нескольких языков, вам может быть хорошо, если вы используете только обычные строки. С другой стороны, если вы пишете графическое приложение, часто бывает, что API поддерживает только широкие символы. Тогда вы, вероятно, захотите использовать те же самые широкие символы при обработке текста. Имейте в виду, что UTF-16 является кодировкой переменной длины, что означает, что вы не можете считать length()
, чтобы вернуть количество символов. Если API использует кодировку с фиксированной длиной, такую как UCS-2, обработка становится легкой. Преобразование между широкими символами и UTF-8 трудно сделать переносимым образом, но, опять же, API вашего пользовательского интерфейса, вероятно, поддерживает преобразование.
Когда вы НЕ используете широкие символы?
Когда вы пишете код до 1990 года.
Очевидно, я переворачиваюсь, но на самом деле это 21-й век. 127 символов уже давно перестали быть достаточными. Да, вы можете использовать UTF8, но зачем беспокоиться о головных болях?
wchar_t
заключается в том, что ее размер и значение специфичны для ОС. Это просто сводит старые проблемы с новыми. В то время как char
является char
независимо от ОС (по крайней мере, на подобных платформах). Поэтому мы могли бы просто использовать UTF-8, упаковать все в последовательности из char
s и заплакать, как C ++ оставляет нас полностью самостоятельно без каких-либо стандартных методов измерения, индексации, поиска и т. Д. В таких последовательностях.
– underscore_d
21 May 2017 в 14:16
wchar_t
- тип данных с фиксированной шириной, поэтому массив из 10 wchar_t
всегда будет занимать байты платформы sizeof(wchar_t) * 10
. И UTF-16 представляет собой кодировку с переменной шириной, в которой символы могут состоять из 1 или 2 16-битных кодовых точек (и s / 16/8 / g для UTF-8).
– underscore_d
21 May 2017 в 14:42