Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/21: Рейтинг темы: голосов - 21, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
1

Сравнить две строки на различия не учитывая кол-во пробелов и такие различия в буквах как о-и, н-т, в-д.

01.04.2015, 17:32. Показов 4373. Ответов 28
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Помогите пожалуйста дополнить программу. Суть программы -
нужно сравнить две строки на различия не учитывая кол-во пробелов и такие различия в буквах как о-и, н-т, в-д.
Это значит, что предложения:
Сова сидела на суку
и
Сида содела на суку
равны, а строки
Сова сидела на суку
и
Сова сидела на полу
не равны.
Имеется код игнорирующий кол-во пробелов.
Прошу помощи в добавлении к нему проверки по буквам для выполнения оставшейся части задачи.
Вот код:
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
int cmp( const char * c1, const char * c2 ){
    for(; *c1 && *c2 && !(( isalnum( *c1 ) && isalnum( *c2 ) || *c1 == ' ' || *c2 == ' ' ) && *c1 != *c2 ); c1++, c2++ );
    return !( *c1 + *c2 );
}
void RemoveSpaces(char* p)
{
    for(char* p1 = p; *p = *p1; ++p1)
    {
        if(*p != ' ')
            ++p;
    }
}
int main(int argc, char *argv[])
{
    char * c1 = "s-f   g.2";
    char * c2 = "s[f g]2";
    RemoveSpaces(c1);
    RemoveSpaces(c2);
    if( cmp( c1, c2 ))
        puts("True");
    else puts("False");
    getchar();
    return 0;
}
Выдаёт True так как строки схожи без учёта пробелов и спец символов.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.04.2015, 17:32
Ответы с готовыми решениями:

Как сравнить две строки игнорируя различия в регистрах?
Дело в том, что нельзя использовать основные функции, в моей случае tolower, я очень затрудняюсь в...

Функция сравнивает две строки, игнорируя различия в регистрах
Я студент 1 курса на зачёт сказали написать программку помогите!! не хочу вылететь из универа С++...

Функция сравнивает две строки, игнорируя различия в регистрах
Мне нужно написать программу в которой функция сравнивает две строки, игнорируя различия в...

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

28
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
03.04.2015, 20:21 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Istes Посмотреть сообщение
Следовательно при выводе результата в консоль будет три строки сравнения s1-s2, s3-s4, s4-s1. Но ведь суть задачи - сравнить две строки.
Предположение ошибочно.Я привел 3 разных вызовов функции сравнения.Это как если бы программу вызвали 3 раза для 3 пар строк.

Цитата Сообщение от Istes Посмотреть сообщение
Каким образом это связано?
Никаким.Ладно,давайте пойдем длинным путем.Прокомментируйте каждую строку первого варианта кода и его аналога.Будем искать соответствия.

Добавлено через 23 секунды
Цитата Сообщение от Istes Посмотреть сообщение
Но что такое mp.insert. Извлечение?
Наоборот.
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
03.04.2015, 20:22  [ТС] 22
Цитата Сообщение от S_el Посмотреть сообщение
Так показывайте попытки.Поверьте для вас будет намного полезнее,если вы эту задачу(перевод кода) решите сами.
Прочёл про контейнер map, что он в каком то роде эквивалентен set.
Попытался следуя ходу мысли в уроке о map преобразовать код, но при компиляции возникло много ошибок порождающих ещё больше вопросов из вопросов. Понял, что на данном этапе изучения c++ для меня это невыполнимо и нужно более углубляться и нарабатывать опыт чему увы не способствует срок для задачи. Согласитесь, что в ходе изучения такого сложного высшего языка программирования как C++ нужно следовать постепенному пути с повышением опыта. Посему Считаю, что Ваше мнение о полезности самостоятельного перевода одного кода в другой на моём этапе лишь больше запутало меня в языке. А некоторые вопросы я порой даже для себя не могу чётко сформулировать что бы задавать их к примеру Вам. На своём этапе в этой ситуации я могу лишь ассоциировать подходящий код igorrr37 и Ваш пример, что показалось мне более лёгким вариантов решения проблемы. Вот, что я обработал:
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
void Prepare(char* p)
{
    for(char* p1 = p, *p2 = p; *p1 = *p2; ++p2)
    {
        if(*p1 == 'о') *p1 = 'и';
        else if(*p1 == 'н') *p1 = 'т';
        else if(*p1 == 'в') *p1 = 'д';
        
        if(*p1 != ' ') ++p1;
    }
}
//-----------------------------------------------------------
//int cmp( const char * s1, const char * s2 ){
//    for(; *s1 && *s2 && !(( isalnum( *s1 ) && isalnum( *s2 ) || *s1 == ' ' || *s2 == ' ' ) && *s1 != *s2 ); s1++, s2++ );
//    return !( *s1 + *s2 );
//}
//-----------------------------------------------------------
//---------------------------------------------------------------------------
int main(void)
{
SetConsoleOutputCP(1251);
    char s1[]="  о = и  н = т  в = д  ", s2[] = "и=от=нд=в", s3[] = "  у = и  з = т  р = д  ", s4[] = "о = он = т  в = в";
    Prepare(s1);
    Prepare(s2);
    if(!strcmp(s1, s2)) cout<<("true")<<endl<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl;
    else cout<<("false")<<endl<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl;
    system ("pause");
return 0;
}
Программа выдаёт true. Строки становятся равными. Но ведь это по сути ложное решение задачи в её чистом виде. Так сказать не сравнение, а подстановка. Это как при необходимости сравнить апельсин и яблоко за место апельсина положить яблоко и сказать, что они же равны быстренько и незаметно заменяя обратно яблоко на апельсин. Хотя здесь яблоко так и остаётся яблоком. К чему тогда сравнивать разные строки? Можно заведомо записать одинаковые и постоянно видеть TRUE. Ведь суть моей задачи - взять абсолютно произвольные две строки к примеру S1 - Коть едет быстро и S2 - Кить едет быстри, сравнить их с условием, что о=и, н=т и выдав обе первоначальные строки выдать и результат сравнения (в этой ситуации - TRUE). Неужели нет иного решения задачи? А не псевдосравнение с подменой?
Несомненно Ваши решения хороши, но всё же я опять же убедился в их не принадлежности именно к этой задаче, начав разбираться в логике выполнения. Понадеюсь на Ваш разум, опыт и наличие других идей решения.
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
03.04.2015, 20:33 23
Цитата Сообщение от Istes Посмотреть сообщение
Согласитесь, что в ходе изучения такого сложного высшего языка программирования как C++ нужно следовать постепенному пути с повышением опыта. Посему
Нужно просто решать как можно больше задач,постепенно повышая уровень сложности.

Цитата Сообщение от Istes Посмотреть сообщение
Но ведь это по сути ложное решение задачи в её чистом виде.
Почему?Задача звучит так сравнить 2 строки,по заданному правилу сравнения.В предложенном мной решении нет никакого псевдосравнения. Давайте вернемся к вашей аналогии с апельсином.Дан апельсин и нечто похожее.У вас есть набор правил,согласно которым можно однозначно определить является нечто апельсином или нет.Я предлагаю клонировать оба объекта провести исследования на них и на этом строить вывод.Естественно можно строить решение и по-другому.
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
03.04.2015, 20:49  [ТС] 24
Цитата Сообщение от S_el Посмотреть сообщение
Никаким.Ладно,давайте пойдем длинным путем.Прокомментируйте каждую строку первого варианта кода и его аналога.Будем искать соответствия.
Что ж.
Вот адаптированный мной код igorrr37 под мой компилятор. По крайней мере он у меня запустился на выполнение в консоли:
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
void Prepare(char* p)  // Вводим процедуру, задаём тип (забыл как называется переменная со *) свободной переменной
{
    for(char* p1 = p, *p2 = p; *p1 = *p2; ++p2)  //Цикл сопоставляющий строки с символами как я понял, сравнивающий строки и прибавляющий 1 к 2 строке.
    {
        if(*p1 == 'о') *p1 = 'и'; // условие если p1 = о, то p1 присваивается замена на и 
        else if(*p1 == 'н') *p1 = 'т'; // то же самое с н и т
        else if(*p1 == 'в') *p1 = 'д'; // в и д
        
        if(*p1 != ' ') ++p1; //чистим от пробелов
    }
}
//-----------------------------------------------------------
//int cmp( const char * s1, const char * s2 ){
//    for(; *s1 && *s2 && !(( isalnum( *s1 ) && isalnum( *s2 ) || *s1 == ' ' || *s2 == ' ' ) && *s1 != *s2 ); s1++, s2++ );
//    return !( *s1 + *s2 );
//}
//-----------------------------------------------------------
//---------------------------------------------------------------------------
int main(void)
{
SetConsoleOutputCP(1251); //поддержка языка из windows в консоли
    char s1[]="  о = и  н = т  в = д  ", s2[] = "и=от=нд=в", s3[] = "  у = и  з = т  р = д  ", s4[] = "о = он = т  в = в"; // задаём переменные и присваиваем им строки.
    Prepare(s1); //прогоняем через процедуру строку 1
    Prepare(s2); //строку 2
    if(!strcmp(s1, s2)) cout<<("true")<<endl<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl; // если при сравнении S1 и S2 не ноль, то TRUE
    else cout<<("false")<<endl<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl; // иначе FALSE
    system ("pause"); //пауза ожидания
return 0; // возврат о успешном выполнении.
}
//---------------------------------------------------------------------------
Добавлено через 2 минуты
Цитата Сообщение от S_el Посмотреть сообщение
Нужно просто решать как можно больше задач,постепенно повышая уровень сложности.
Конечно это так, и в своё оправдание могу сказать, что это последняя 14 задача из всех заданных мне и именно над ней я уже бьюсь 4 дня мало по малу с помощью знающих продвигаюсь к успеху. Остальные скажу честно решал самостоятельно конечно с помощью кое каких уроков и интернета.. Но тем не менее..

Добавлено через 9 минут
Цитата Сообщение от S_el Посмотреть сообщение
Я предлагаю клонировать оба объекта провести исследования на них и на этом строить вывод.Естественно можно строить решение и по-другому.
Но ведь на сколько я понял, Вы предлагаете сделать из того нечто гибрид. Половина апельсина, а половина нечто.
Смотрите. Следуя Вашей мысли... Есть апельсин и нечто. Берём апельсин и делаем копию, ложем в отдельную тарелку т2 и тоже самое с нечто. Теперь у нас две тарелки с одинаковым содержимым. Теперь в т2 мы копируем от апельсина его половину и заменяем лицевую к нам сторону нечто на апельсиновую половину. Сравниваем - TRUE. Но для чего тогда тарелка 1 с оригиналами? Лишь для вывода пользователю? Да и в т2 от оригинального варианта остался лишь клон апельсина.

Добавлено через 1 минуту
Всё же прошу Вас ещё раз обратить внимание на мою задачу в шапке. И примеры там же.
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
03.04.2015, 21:01 25
Цитата Сообщение от Istes Посмотреть сообщение
Но ведь на сколько я понял, Вы предлагаете сделать из того нечто гибрид.
Нет.Делаем копии,над ними проводим все нужные операции.Делаем вывод об оригинале.Гибрид уничтожается после проведения всех исследований.

Цитата Сообщение от Istes Посмотреть сообщение
Всё же прошу Вас ещё раз обратить внимание на мою задачу в шапке. И примеры там же.
Обращаю.Привожу пример на примерах из шапки.Заодно демонстрирую 2-ой способ решения.

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
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <string.h>
 
bool isEquals(const std::string &first,const std::string &second);
void Prepare(std::string& s);
bool func(char first,char second);
bool isEqualsC(char* pf,char *ps);
std::map<char, char> mp;
 
int main()
{
 setlocale(LC_ALL,"rus");
 mp.insert(std::make_pair('о', 'и'));
 mp.insert(std::make_pair('н', 'т'));
 mp.insert(std::make_pair('в', 'д'));
 std::string s1("Сова сид ела на су ку");
 std::string s2("Сида содела на суку");
 std::string s3("Сова сид ела на су ку");
 std::string s4("Сова сидела на полу");
 char ch1[] = "Сова сид ела на су ку";
 char ch2[] = "Сида содела на суку";
 char ch3[] = "Сова сид ела на су ку";
 char ch4[] = "Сова сидела на полу";
 std::cout<<isEquals(s1,s2)<<std::endl;
 std::cout<<isEquals(s3,s4)<<std::endl;
 std::cout<<isEqualsC(ch1,ch2)<<std::endl;
 std::cout<<isEqualsC(ch3,ch4)<<std::endl;
 
return 0;
}
 
bool isEquals(const std::string &first,const std::string &second)
{
    std::string s1(first);
    std::string s2(second);
    Prepare(s1);
    Prepare(s2);
    return (s1==s2);
}
 
void Prepare(std::string& s)
{
 s.assign(s.begin(), std::remove(s.begin(), s.end(), ' '));
 for(std::map<char, char>::const_iterator ib(mp.begin()), ie(mp.end()); ib != ie; ++ib)
 {
 std::replace(s.begin(), s.end(), ib->first, ib->second);
 }
}
 
bool func(char first,char second)
{
    if(first==second) return true;
    if((first=='о' && second=='и')||(first=='и' && second=='о')) return true;
    if((first=='н' && second=='т')||(first=='т' && second=='н')) return true;
    if((first=='в' && second=='д')||(first=='д' && second=='в')) return true;
    return false;
}
 
bool isEqualsC(char* pf,char *ps)
{
    for(; (*pf != '\0' && *ps != '\0'); )
    {
        while(*pf==' '){pf++;}
        while(*ps==' '){ps++;}
        if(!func(*pf,*ps))
        return false;
        pf++;
        ps++;
    }
return true;
}
Вывод:
Код
1
0
1
0
как видите полная эквивалентность.Естественно подобный подход можно использовать и для string.
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
03.04.2015, 21:05  [ТС] 26
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
bool isEquals(const std::string &first,const std::string &second); //не понял что это
void Prepare(std::string& s); // опять же процедура с типом стринг и переменной с
 
std::map<char, char> mp;//обьявляем мап, тип и имя его
 
int main()
{
    setlocale(LC_ALL,"rus");
 mp.insert(std::make_pair('о', 'и'));//заполняем постепенно контейнер мап (не понял, что значит std::make_pair и как она выражается в моём компиляторе) на эти строки выдаётся ошибка.
 mp.insert(std::make_pair('н', 'т'));//заполняем постепенно контейнер мап (не понял, что значит std::make_pair и как она выражается в моём компиляторе) на эти строки выдаётся ошибка.
 mp.insert(std::make_pair('в', 'д'));//заполняем постепенно контейнер мап (не понял, что значит std::make_pair и как она выражается в моём компиляторе) на эти строки выдаётся ошибка.
 std::string s1("  о = и  н = т  в = д  "); //присвоение строковым переменным данных.
 std::string s2("и=от=нд=в");//присвоение строковым переменным данных.
 std::string s3("  у = и  з = т  р = д  ");//присвоение строковым переменным данных.
 std::string s4("о = он = т  в = в");//присвоение строковым переменным данных.
 
 std::cout<<isEquals(s1,s2)<<std::endl;//вывод эквивалентности s1 и s2
 std::cout<<isEquals(s3,s4)<<std::endl;//вывод эквивалентности s3 и s4
 std::cout<<isEquals(s1,s4)<<std::endl;//вывод эквивалентности s1 и s4
 
return 0;
}
 
bool isEquals(const std::string &first,const std::string &second)//не имею представления как это выразить в моём компиляторе
{
    std::string s1(first);//строки с чем то ассоциируются?
    std::string s2(second);//строки с чем то ассоциируются?
    Prepare(s1);//проводим с1 через процедуру
    Prepare(s2);//проводим с2 через процедуру
    return (s1==s2);//возврат равенства строк?
}
 
void Prepare(std::string& s)//далее тёмный лес. Могу лишь догадываться по аналогии с подошедшим мне кодом Игоря.
{
 s.assign(s.begin(), std::remove(s.begin(), s.end(), ' '));
 for(std::map<char, char>::const_iterator ib(mp.begin()), ie(mp.end()); ib != ie; ++ib)
 {
 std::replace(s.begin(), s.end(), ib->first, ib->second);
 }
}
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
03.04.2015, 21:14  [ТС] 27
Цитата Сообщение от S_el Посмотреть сообщение
Обращаю.Привожу пример на примерах из шапки.Заодно демонстрирую 2-ой способ решения.
Печальный веер ошибок при попытке компиляции. Которые ещё больше меня запутали. Расскажите мне о причинах ошибок?
Сравнить две строки на различия не учитывая кол-во пробелов и такие различия в буквах как о-и, н-т, в-д.
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
03.04.2015, 21:24 28
Лучший ответ Сообщение было отмечено Istes как решение

Решение

Цитата Сообщение от Istes Посмотреть сообщение
Печальный веер ошибок при попытке компиляции. Которые ещё больше меня запутали. Расскажите мне о причинах ошибок?
Да ошибки все те-же из-за вашей среды. Закомментируйте функции
C++
1
2
bool isEquals(const std::string &first,const std::string &second);
void Prepare(std::string& s);
их вызов и создание std::map и std::string.Ну и заголовочные файлы.

Добавлено через 6 минут
Закомментировал и прокомментировал:

Кликните здесь для просмотра всего текста
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//подключение заголовочных файлов
 
#include <iostream>
//#include <algorithm>
//#include <string>
//#include <map>
#include <string.h>
 
//объявление прототипов
//bool isEquals(const std::string &first,const std::string &second);
//void Prepare(std::string& s);
bool func(char first,char second);
bool isEqualsC(char* pf,char *ps);
 
//объект mp типа map с аргументами шаблона типа char
//std::map<char, char> mp;
 
int main()
{
 setlocale(LC_ALL,"rus");
 //добавляем в map созданный пар
 /*
 mp.insert(std::make_pair('о', 'и'));
 mp.insert(std::make_pair('н', 'т'));
 mp.insert(std::make_pair('в', 'д'));
 //создаем объект типа string,строка передается конструктору
 std::string s1("Сова сид ела на су ку");
 std::string s2("Сида содела на суку");
 std::string s3("Сова сид ела на су ку");
 std::string s4("Сова сидела на полу");
 */
 char ch1[] = "Сова сид ела на су ку";
 char ch2[] = "Сида содела на суку";
 char ch3[] = "Сова сид ела на су ку";
 char ch4[] = "Сова сидела на полу";
 //std::cout<<isEquals(s1,s2)<<std::endl;
 //std::cout<<isEquals(s3,s4)<<std::endl;
 std::cout<<isEqualsC(ch1,ch2)<<std::endl;
 std::cout<<isEqualsC(ch3,ch4)<<std::endl;
 
return 0;
}
/*
//аргументы функции - 2 константные ссылки на объекты std::string
bool isEquals(const std::string &first,const std::string &second)
{
    std::string s1(first);
    std::string s2(second);
    Prepare(s1);
    Prepare(s2);
    return (s1==s2);
}
 
 
void Prepare(std::string& s)
{
 s.assign(s.begin(), std::remove(s.begin(), s.end(), ' '));
 for(std::map<char, char>::const_iterator ib(mp.begin()), ie(mp.end()); ib != ie; ++ib)
 {
 //проводим замену
 std::replace(s.begin(), s.end(), ib->first, ib->second);
 }
}
*/
bool func(char first,char second)
{
    if(first==second) return true;
    if((first=='о' && second=='и')||(first=='и' && second=='о')) return true;
    if((first=='н' && second=='т')||(first=='т' && second=='н')) return true;
    if((first=='в' && second=='д')||(first=='д' && second=='в')) return true;
    return false;
}
 
bool isEqualsC(char* pf,char *ps)
{
    for(; (*pf != '\0' && *ps != '\0'); )
    {
        while(*pf==' '){pf++;}
        while(*ps==' '){ps++;}
        if(!func(*pf,*ps))
        return false;
        pf++;
        ps++;
    }
return true;
}
2
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 16
03.04.2015, 22:07  [ТС] 29
Цитата Сообщение от S_el Посмотреть сообщение
Закомментировал и прокомментировал:
Большое спасибо! Просмотрел Ваш код, сделал изменения рекомендованные Вами и проверил работоспособность в действии. Теперь осталось добавить не статичные строки, а вводимые пользователем. Но это я уже сам. Наконец я получил именно то, до чего мой разум ещё не дошёл.
0
03.04.2015, 22:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.04.2015, 22:07
Помогаю со студенческими работами здесь

Сравнить два Excel файла и показать различия на втором файле выделив другим цветом
Здравствуйте, форумчане. Есть два Excel файла с уже записанной таблицей(скрин). Надо их сравнить...


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

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru