Форум программистов, компьютерный форум CyberForum.ru

Как сравнить 2 массива - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
MMt
0 / 0 / 0
Регистрация: 29.04.2014
Сообщений: 168
22.06.2014, 19:04     Как сравнить 2 массива #1
в общем идея.
есть строчный массив не инициализирвоанный. Массив я заполняю сам через син.
Вопрос - можно ли в зависимости от того что я введу потом сравнить через свич с доступными в свиче константами?

например. я массиву задаю данные kvadrat. и така я строка встречается в свиче... Так можно делать?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main(){
    setlocale(0,"");
    
    char s;
    int param;
    char mChoice[50];
    
    
    
    cout    << "Выберите фигуру:\n"
            <<"Квадрат(kvadrat) \n"
            <<"Круг(krug)\n"
            <<"Прямоугольник(pryamougolnik)\n"
            <<"Триугольник(rtiugolnik)\n";
            
    cin >> mChoice;
    cout    << mChoice;
 
    switch(mChoice){
        case 'kvadrat':
                cout    <<"verno - kvadrat. \n";
        case "krug":
                cout    <<"verno krug. \n";
                
    }
return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2014, 19:04     Как сравнить 2 массива
Посмотрите здесь:

C++ Помогите сравнить 2 массива.
Сравнить 2 массива C++
C++ как сравнить сумму элементов массива?
Как сравнить два массива C++
C++ Как сравнить элемент двумерного массива?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
29.06.2014, 16:49     Как сравнить 2 массива #41
Цитата Сообщение от IGPIGP Посмотреть сообщение
Совершенно верно, длинные и короткие строки отыщутся за примерно одно и тоже время, в отличие от прямого сравнения. И вывод: чем длиннее строки тем лучше использовать словарь. Там на построение придётся один раз раскошелиться.
Остаёмся при своих мнениях..., но с взаимной симпатией. Исправляю недочёт в предыдущем фрагменте:
Ладно, теперь уже в самый-самый последний раз В шарпе строка имеет дополнительные поля, в которых лежат заранее посчитанное значение хэша (потому что строки неизменяемые), заранее посчитанная длина строки (по той же причине) и прочее. Поэтому длина строки не влияет от слова вообще
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
30.06.2014, 00:28     Как сравнить 2 массива #42
Цитата Сообщение от Psilon Посмотреть сообщение
В шарпе строка имеет дополнительные поля, в которых лежат заранее посчитанное значение хэша (потому что строки неизменяемые), заранее посчитанная длина строки (по той же причине) и прочее.
Ну и если совпал хэш (длина) для двух килобайтовых строк, их что не придётся по-символьно сравнивать? Можно конечно придумать хэш, который будет уникален, но объем этого хэша будет сопоставим с объёмом строки. Можно реализовать промежуточный вариант сокращающий работу, но хэш нужен для проверки на неравенство и если она не проходит... и т.д. и т.п. Строки можно изменять передавая по ссылке если я правильно помню, но не суть. Вот длина строк, - недорогой способ избавиться от проверки при заведомом неравенстве, но если получение близких по размеру строк наиболее вероятно, то работать будет слабо. А чем лучше хэш, тем больше затрат на создание строки. В пределе он может стать ключом словаря. () Потом конечно экономия при сравнении, сортировке и поиске, но это же от убеждённости в разумности бытия так делается. Я хоть и не программист в твёрдом понимании, этого слова и тем более не системный, но сдаётся мне, что затраты на создание подобных объектов это не в духе C++.
Я подумаю и покопаюсь, а пока что не убедили Вы меня.
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
30.06.2014, 02:29     Как сравнить 2 массива #43
IGPIGP, сначала сравнивается длина, потом хэш. Если и то и то совпало, тогда да, придется посимвольно проверять, что еще делать-то . Вернее, насколько я помню, там сравнение идет по-умному, сразу по 4 байта за раз.

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

Я никого не убеждаю, я говорю, как оно есть. Насчет плюсов я бы не стал спорить, но вот спецификацию CLR и C# я знаю назубок, чуть хуже Рихтера

Добавлено через 3 минуты
Если уж очень интересно, то вот кишки фреймворка, сравнение двух строк:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    [__DynamicallyInvokable]
    public bool Equals(string value)
    {
      if (this == null)
        throw new NullReferenceException();
      if (value == null)
        return false;
      if (object.ReferenceEquals((object) this, (object) value))
        return true;
      if (this.Length != value.Length)
        return false;
      else
        return string.EqualsHelper(this, value);
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SecuritySafeCritical]
private static unsafe bool EqualsHelper(string strA, string strB)
{
    int length = strA.Length;
    if (length != strB.Length)
    {
        return false;
    }
    fixed (char* chRef = &strA.m_firstChar)
    {
        fixed (char* chRef2 = &strB.m_firstChar)
        {
            char* chPtr = chRef;
            char* chPtr2 = chRef2;
            while (length >= 10)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 2))) != *(((int*) (chPtr2 + 2))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 4))) != *(((int*) (chPtr2 + 4))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 6))) != *(((int*) (chPtr2 + 6))))
                {
                    return false;
                }
                if (*(((int*) (chPtr + 8))) != *(((int*) (chPtr2 + 8))))
                {
                    return false;
                }
                chPtr += 10;
                chPtr2 += 10;
                length -= 10;
            }
            while (length > 0)
            {
                if (*(((int*) chPtr)) != *(((int*) chPtr2)))
                {
                    break;
                }
                chPtr += 2;
                chPtr2 += 2;
                length -= 2;
            }
            return (length <= 0);
        }
    }
}
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
30.06.2014, 02:58     Как сравнить 2 массива #44
Цитата Сообщение от Psilon Посмотреть сообщение
Хэш создается не сразу, а после первого обращения к нему.
Всё равно создаётся же. Я не стану спорить о том как измерить statement, не понимаю я чем две ветки с большущими строковыми ключами не подарок, если switch в здоровущем цикле закрутится. Количество оборотов же в рантайме может определяться. Что же тогда определит болевой порог компилятора? Терпеть будет?

Не по теме:

Спасибо за компанию Psilon, но боюсь болевой порог модераторов раздела не беспределен. В целом где-то и по теме поговорили, но думаю пора закругляться.

Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
30.06.2014, 06:02     Как сравнить 2 массива #45
Цитата Сообщение от IGPIGP Посмотреть сообщение
Всё равно создаётся же. Я не стану спорить о том как измерить statement, не понимаю я чем две ветки с большущими строковыми ключами не подарок, если switch в здоровущем цикле закрутится. Количество оборотов же в рантайме может определяться. Что же тогда определит болевой порог компилятора? Терпеть будет?
какой болевой порог? Все просто, меньше, допустим, 10 веток - будет if else, больше - создастся словарь (причем словарь будет скорее всего создан статически на этапе компиляции), а затем будем по словарю бегать. При числе switch-ветвлений меньше тысячи коллизий не будет точно, а 1000 кейзов... Такого я еще не видал

Не по теме:

Спасибо за компанию Psilon, но боюсь болевой порог модераторов раздела не беспределен. В целом где-то и по теме поговорили, но думаю пора закругляться.
да мне тоже приятно пообщаться, в любом случае, проясняю для себя что-то, Rubber duck метод же
насчет модераторов, возможно, просто перенесут в тему типа "Оператор switch для строк в C++ и C# [Holywar]" и все. Тем более, что это имеет смысл. Но пока они не решили, что это нужно - можно писать здесь ятп

IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
01.07.2014, 01:18     Как сравнить 2 массива #46
Цитата Сообщение от Psilon Посмотреть сообщение
10 веток - будет if else,
Я уже спрашивал про односимвольные строки, которые сравнивать не намного труднее целых чисел... Последний вопрос я задал о том же, но иначе: представьте длинные строки в качестве ключей в двух ветках всего. А свитч в цикле работает, то есть сравнивать часто приходится. Строчки для сравнения часто приходят на 50-70% совпадающие с ключами вначале. Пусть это пути к ресурсу, например.
Цитата Сообщение от Psilon Посмотреть сообщение
о создан статически на этапе компиляции),
Тут не могу сказать уверенно, но из того что мне попадалось, следует вроде, что может и перекомпиляция происходить или это я выдумал?
Код меня гипнотизирует... Не на берегах ли могучего Ганга сотворён?
Вот строка:
C#
1
2
 if (this.Length != value.Length)
        return false;
среди других проверок. Потом если не прошло вызывается EqualsHelper(this, value) и в нём снова:

C#
1
2
3
4
5
int length = strA.Length;
    if (length != strB.Length)
    {
        return false;
    }
Боязнь, что в процессе "неизменяемая строка" изменится? Это ночной кошмар конечно, если такое случится. Удар в спину просто. Может и не зря перестраховались, - нервы дороже.
Или читаю я его неверно...
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
01.07.2014, 03:03     Как сравнить 2 массива #47
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я уже спрашивал про односимвольные строки, которые сравнивать не намного труднее целых чисел... Последний вопрос я задал о том же, но иначе: представьте длинные строки в качестве ключей в двух ветках всего. А свитч в цикле работает, то есть сравнивать часто приходится. Строчки для сравнения часто приходят на 50-70% совпадающие с ключами вначале. Пусть это пути к ресурсу, например.
Нам-то понятно, что односимвольные строки можно сравнивать как числа. Но компилятору плевать, какая там длина Тем более, что шарп оперирует исключительно UTF8-строками, поэтому "один символ" - понятие растяжимое...

Цитата Сообщение от IGPIGP Посмотреть сообщение
Боязнь, что в процессе "неизменяемая строка" изменится? Это ночной кошмар конечно, если такое случится. Удар в спину просто. Может и не зря перестраховались, - нервы дороже.
Или читаю я его неверно...
просто метод EqualsHelper может вызываться откуда угодно (в пределах класса). А т.к. это стандартная библиотека, то она работает в предположении полного отказа любой части, все функции максимально независимы и всегда проверяют предусловия, не перекладывая это на вызывающий код. Тем более, что сравнить 2 числа не такая уж проблема. А вот возможные баги намного печальнее. Ну и в крайнейм случае компилятор может заинлайнить метод, увидеть две одинаковых проверки и одну выкинуть за ненадобностью.

Добавлено через 33 секунды
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я уже спрашивал про односимвольные строки, которые сравнивать не намного труднее целых чисел... Последний вопрос я задал о том же, но иначе: представьте длинные строки в качестве ключей в двух ветках всего. А свитч в цикле работает, то есть сравнивать часто приходится. Строчки для сравнения часто приходят на 50-70% совпадающие с ключами вначале. Пусть это пути к ресурсу, например.
Нам-то понятно, что односимвольные строки можно сравнивать как числа. Но компилятору плевать, какая там длина Тем более, что шарп оперирует исключительно UTF8-строками, поэтому "один символ" - понятие растяжимое...

Цитата Сообщение от IGPIGP Посмотреть сообщение
Боязнь, что в процессе "неизменяемая строка" изменится? Это ночной кошмар конечно, если такое случится. Удар в спину просто.
просто метод EqualsHelper может вызываться откуда угодно (в пределах класса). А т.к. это стандартная библиотека, то она работает в предположении полного отказа любой части, все функции максимально независимы и всегда проверяют предусловия, не перекладывая это на вызывающий код. Тем более, что сравнить 2 числа не такая уж проблема. А вот возможные баги намного печальнее. Ну и в крайнейм случае компилятор может заинлайнить метод, увидеть две одинаковых проверки и одну выкинуть за ненадобностью.
одним словом:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Может и не зря перестраховались, - нервы дороже.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
01.07.2014, 14:54     Как сравнить 2 массива #48
Цитата Сообщение от Psilon Посмотреть сообщение
Но компилятору плевать, какая там длина
Это вряд ли нормально. Также как и:
Цитата Сообщение от Psilon Посмотреть сообщение
просто метод EqualsHelper может вызываться откуда угодно
Сравнение строк даже не предполагая их использования ключами в switch штука актуальная для производительности и не сотворить отдельный метод просто плохо. Так можно дойти до того, чтобы создать один метод который можно вызвать куда угодно и все библиотеки в него поместить. Назвать LibHelperUniversal или вроде того.
Цитата Сообщение от Psilon Посмотреть сообщение
Ну и в крайнейм случае компилятор может заинлайнить метод, увидеть две одинаковых проверки и одну выкинуть за ненадобностью.
Компилятор всегда прав. Если компилятор неправ см п.1.
Последние посты уже не о сравнении строк. Предлагаю остановиться, - не подтягивается никто.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
01.07.2014, 15:12     Как сравнить 2 массива #49

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Предлагаю остановиться, - не подтягивается никто.
Нормы ГТО ввели, скоро все будут подтягиваться.


Ну а вообще, офтоп знатный получился у вас
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
01.07.2014, 15:29     Как сравнить 2 массива #50
Цитата Сообщение от IGPIGP Посмотреть сообщение
Это вряд ли нормально. Также как и:
для .Net - нормально. Слоган "безопасность любой ценой" - это про него. Тем более, как я уже сказал, компилятор вполне может выпилить лишнюю проверку, если увидит еще одну, или оставить, если её не будет

Цитата Сообщение от IGPIGP Посмотреть сообщение
Последние посты уже не о сравнении строк. Предлагаю остановиться, - не подтягивается никто.
IGPIGP
02.07.2014, 00:24
  #51

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
Нормы ГТО ввели, скоро все будут подтягиваться.
Всегда готов! Подтягивание, - отличный аргумент, хоть в данный момент и лень. Посудите, - нужно выйти из медитации, ноги из лотоса развязать... Медитирую на метод сравнения. Пытаюсь понять откуда число 10 для первого шага проверки. Магическая длина.
На 10-й минуте начал проникать внутренним взором сквозь материю и сразу понял. Руки расслаблены и лежат на коленях ладонями вверх. Интересно, что пальцев ровно 10 штук выходит, - вот оно. Индия полна мудрости и простоты.

Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
02.07.2014, 00:33     Как сравнить 2 массива #52
IGPIGP, на самом деле константы наверняка поименованы, просто при декомпиляции они теряются, т.к. компилятор их инлайнит

Добавлено через 2 минуты
Сравнивают, кстати, по 20 байт, если заметили. Ятп они эвристически определяет оптимальный шаг)
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
02.07.2014, 00:34     Как сравнить 2 массива #53
Цитата Сообщение от Psilon Посмотреть сообщение
на самом деле константы наверняка поименованы,
Я тоже оптимист!
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
02.07.2014, 00:38     Как сравнить 2 массива #54
IGPIGP, нужно посмотреть будет на сайте фреймворка. Просто я вытаскиваю код системных классов через рефлектор, так быстрее выходит просто у меня инет умер, пишу с телефона в макдаке. Завтра постараюсь заглянуть нормально
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,715
Записей в блоге: 3
02.07.2014, 00:39     Как сравнить 2 массива #55
Цитата Сообщение от Psilon Посмотреть сообщение
Сравнивают, кстати, по 20 байт, если заметили. Ятп они эвристически определяет оптимальный шаг)
Учитывая разрядность процессора (размер машинного слова) можно бы компилировать в зависимости от аппаратуры. Сейчас вряд ли у кого найдётся система ниже 32 бит. Побайтово этоже легче написать чем выполнить.
Но 10 шагов, это 10 шагов. Наверное это совершенно правильно.
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
02.07.2014, 02:28     Как сравнить 2 массива #56
IGPIGP, я когда смотрел нутри фреймворка, там методы внутри кстати используют преимущества аппаратуры. Например, встречаются записи #ifdef AMD64. Так что я склоняюсь к мысли, что дураки мы. а не они

Добавлено через 3 минуты
только я сказал, и вот действительно
исходники фреймворка:
http://referencesource.microsoft.com...stem/string.cs

тот же код, но в исходниках (а не при декомпиляции) выглядит так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
        //
        //
        // NATIVE INSTANCE METHODS
        //
        //
    
        //
        // Search/Query methods
        //
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        private unsafe static bool EqualsHelper(String strA, String strB)
        {
            Contract.Requires(strA != null);
            Contract.Requires(strB != null);
            Contract.Requires(strA.Length == strB.Length);
 
            int length = strA.Length;
 
            fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
            {
                char* a = ap;
                char* b = bp;
 
                // unroll the loop
#if AMD64
                // for AMD64 bit platform we unroll by 12 and
                // check 3 qword at a time. This is less code
                // than the 32 bit case and is shorter
                // pathlength
 
                while (length >= 12)
                {
                    if (*(long*)a     != *(long*)b) return false;
                    if (*(long*)(a+4) != *(long*)(b+4)) return false;
                    if (*(long*)(a+8) != *(long*)(b+8)) return false;
                    a += 12; b += 12; length -= 12;
                }
#else
                while (length >= 10)
                {
                    if (*(int*)a != *(int*)b) return false;
                    if (*(int*)(a+2) != *(int*)(b+2)) return false;
                    if (*(int*)(a+4) != *(int*)(b+4)) return false;
                    if (*(int*)(a+6) != *(int*)(b+6)) return false;
                    if (*(int*)(a+8) != *(int*)(b+8)) return false;
                    a += 10; b += 10; length -= 10;
                }
#endif
 
                // This depends on the fact that the String objects are
                // always zero terminated and that the terminating zero is not included
                // in the length. For odd string sizes, the last compare will include
                // the zero terminator.
                while (length > 0) 
                {
                    if (*(int*)a != *(int*)b) break;
                    a += 2; b += 2; length -= 2;
                }
 
                return (length <= 0);
            }
        }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2014, 08:15     Как сравнить 2 массива
Еще ссылки по теме:

Как сравнить элемент массива? C++
C++ Найти среднее арифметическое элементов массива, сравнить два массива поэлементно
C++ Как сравнить два элемента массива типа string?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
zss
Модератор
Эксперт С++
 Аватар для zss
5950 / 5555 / 1786
Регистрация: 18.12.2011
Сообщений: 14,196
Завершенные тесты: 1
02.07.2014, 08:15     Как сравнить 2 массива #57
IGPIGP, Psilon, Перенесите обсуждение в кулуары.
Тему закрываю.
Yandex
Объявления
02.07.2014, 08:15     Как сравнить 2 массива
Закрытая тема Создать тему
Опции темы

Текущее время: 10:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru