Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
paradox_1326
0 / 0 / 3
Регистрация: 17.12.2014
Сообщений: 111
#1

Можно ли написать этот код более компактно? - C++

03.01.2015, 17:12. Просмотров 787. Ответов 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
#include <iostream>
#include <cmath>
using namespace std;
void main()
{
    int x, y;
    cout << "input x = ";
    cin >> x;
    cout << "input y = ";
    cin >> y;
    if (x > 0 && y > 0)
        cout << "Tochka nahoditsa v 1-oy chetverty " << '\n';
    else if (x < 0 && y>0)
        cout << "Tochka vo 2-oy chetverty " << '\n';
    else if (x < 0 && y < 0)
        cout << "Tochka v 3-ey chetverty " << '\n';
    else if (x > 0 && y < 0)
        cout << "Tochka v 4-oy chetverty " << '\n';
    else if(x>0 && y == 0)
        cout << "Tochka nahoditsa na osi X kotoraya razdelaet 1-uu i 4-uu chetverti " << '\n';
    else if (x<0 && y == 0)
        cout << "Tochka nahoditsa na osi X kotoraya razdelaet 2-uu i 3-u chetverti " << '\n';
    else if(x == 0 && y > 0)
        cout << "Tochka nahoditsa na osi Y kotoraya razdelaet 1-uu i 2-uu chetverti " << '\n';
    else if (x == 0 && y < 0)
        cout << "Tochka nahoditsa na osi Y kotoraya razdelaet 3-u i 4-uu chetverti " << '\n';
    else if(x == 0 && y == 0)
        cout << "Tochka nahoditsa v nachale koordinat " << '\n';
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2015, 17:12
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Можно ли написать этот код более компактно? (C++):

Можно ли написать более оптимальный код, используя цикл while?
собственно сабж. #include &lt;iostream&gt; using namespace std; int main() {...

Можно ли написать более оптимальный или простой код, используя цикл for?
собственно сабж. #include &lt;iostream&gt; using namespace std; int main() {...

как можно более просто написать эту программку(более понятным языком для начинающего)
7. Установить, четным или нечетным является число цифр в записи данного...

Можно как-то оптимизировать этот код?
#include &lt;iostream&gt; using namespace std; int main() { unsigned int num,...

Как можно перевести этот код с паскаля в с++?
uses crt; const n=10; var a:array of integer; i,j,p,k:byte; ...

Как можно перевести этот код с паскаля в с++?
program razbienie_mnozhestwa(input,output); var i,j,k,n:byte;wper:arrayof...

26
rikimaru2013
C++ Game Dev
2471 / 1140 / 348
Регистрация: 30.11.2013
Сообщений: 3,709
03.01.2015, 17:28 #2
Лучший ответ Сообщение было отмечено paradox_1326 как решение

Решение

нет
1
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
03.01.2015, 17:47 #3
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
char* c[] = 
{
    "Tochka nahoditsa v nachale koordinat",
    "Tochka nahoditsa na osi Y kotoraya razdelaet 3-u i 4-uu chetverti",
    "Tochka nahoditsa na osi Y kotoraya razdelaet 1-uu i 2-uu chetverti",
    "Tochka nahoditsa na osi X kotoraya razdelaet 2-uu i 3-u chetverti",
    "Tochka v 3-ey chetverty ",
    "Tochka vo 2-oy chetverty ",
    "Tochka nahoditsa na osi X kotoraya razdelaet 1-uu i 4-uu chetverti ",
    "Tochka v 4-oy chetverty ",
    "Tochka nahoditsa v 1-oy chetverty "
};
 
int _tmain(int argc, _TCHAR* argv[])
{   
    int x, y, z;
    cout << "input x = ";   cin >> x;
    x= (x<0?1:x>0?2:0)*3; 
    cout << "input y = ";   cin >> y;
    y= (y<0?1:y>0?2:0);
    z=y+x;  
    cout << c[z] << '\n';
    return 0;
}
1
Croessmah
++Ͻ
14160 / 8085 / 1513
Регистрация: 27.09.2012
Сообщений: 19,925
Записей в блоге: 3
Завершенные тесты: 1
03.01.2015, 18:55 #4
подобное:
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
#include <iostream>
 
using namespace std;
 
int main()
{
    int x, y;
    cout << "input x = ";
    cin >> x;
    cout << "input y = ";
    cin >> y;
    int val [ 4 ] = { 3 , 2 , 4 , 1 } ;
    if (  x == 0 || y == 0 )
    {
        bool f_x = (x!=0) ;
        bool f_y = (y!=0) ;
        int f_xy = ( ( int(x>0) + (y>0) ) << f_x ) ;
        if ( x==0 && y == 0 )
            cout << "Tochka nahoditsa v nachale koordinat " << '\n' ;
        else
            cout << "Tochka nahoditsa na osi " << (f_x?"X":"Y") << " kotoraya razdelaet chetverti " << val[f_xy+(0 << f_y)] << " i " << val[f_xy+(1 << f_y)] << "\n" ;
    } else
        cout << "Tochka nahoditsa v chetverty " << val[int( (x>0) << 1 ) + (y>0)] << "\n" ;
}
1
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
03.01.2015, 19:26 #5
Croessmah, у ТС первая четверть особенная ("nahoditsa").
По-моему, этот код намного очевиднее выглядит в первоначальной интерпретации. Хотя попытка обобщения кода занятие, безусловно, полезное и интересное, наверное, для любого программиста. Но в данном случае, это имхо скорее спорт, чем реальная потребность в какой-то оптимизации и/или исключении копи-пасты.
Цитата Сообщение от maxillion Посмотреть сообщение
C++
1
char* c[]
Справедливости ради, замечу, что тип элементов массива должен быть const char*.
2
Croessmah
++Ͻ
14160 / 8085 / 1513
Регистрация: 27.09.2012
Сообщений: 19,925
Записей в блоге: 3
Завершенные тесты: 1
03.01.2015, 19:32 #6
Цитата Сообщение от Tulosba Посмотреть сообщение
Croessmah, у ТС первая четверть особенная ("nahoditsa").
Цитата Сообщение от Croessmah Посмотреть сообщение
подобное:
что не нравится?

Добавлено через 37 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
Но в данном случае, это имхо скорее спорт, чем реальная потребность в какой-то оптимизации и/или исключении копи-пасты.
ну так сугубо для интереса и писалось
1
maxillion
273 / 183 / 52
Регистрация: 25.12.2012
Сообщений: 616
03.01.2015, 19:44 #7
Ещё вот так можно
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
#define d(x,y)  ( ((x < 0 )*2 + (x < 0)^(y < 0))+1 )
 
int _tmain(int argc, _TCHAR* argv[])
{   
    int x, y, z;
    cout << "input x = ";   cin >> x;
    cout << "input y = ";   cin >> y;       
 
    if(x != 0 && y != 0)
    {
        cout << "Tochka nahoditsa v chetverty " << d(x,y) << "\n" ;
    }
    else if( x == 0 ^ y == 0 )
    {
        cout << "Tochka nahoditsa na osi " << (x>0?"Y":"X") << " kotoraya razdelaet chetverti ";
        if(x>0)
             cout << d(x,y+1) << " i " << d(x,y-1) << "\n" ;
        else
            cout << d(x+1,y) << " i " << d(x-1,y) << "\n" ;
    }
    else
    {
        cout << "Tochka nahoditsa v nachale koordinat \n";
    }
    return 0;
}
Правда мне больше нравится вариант ТС, потому что его легче понять
1
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
03.01.2015, 19:54 #8
maxillion, а в чем сакральный смысл использования побитового xor для булевских аргументов? Экономия символа вместо "!=" ?
0
rikimaru2013
03.01.2015, 20:18
  #9

Не по теме:


C++
1
2
3
4
5
6
7
8
9
10
11
int isTrue(int x)
{
    if (x == 0)
    {
        return 0;
    }
    else if (x != 0)
    {
        return 1;
    }
}
кого-то вы меня напоминаете - в попытках сделать код не читабельным, но короче)

0
Croessmah
++Ͻ
14160 / 8085 / 1513
Регистрация: 27.09.2012
Сообщений: 19,925
Записей в блоге: 3
Завершенные тесты: 1
03.01.2015, 20:25 #10
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
кого-то вы меня напоминаете - в попытках сделать код не читабельным, но короче
где написано о читабельности?
можно ли написть этот код более компактно
1
ValeryS
Модератор
7133 / 5401 / 669
Регистрация: 14.02.2011
Сообщений: 18,223
03.01.2015, 20:32 #11
rikimaru2013,
Вот твоя же функция
C++
1
2
3
4
int isTrue(int x)
{
    return (int)(x != 0);
}
а вот она же с более логичным возвращаемым значением(логическое)

C++
1
2
3
4
bool isTrue(int x)
{
    return x != 0;
}
короче? Да Быстрее? да, нет ветвлений
не понятней? трудно сказать
вот еще более непонятная но делает тоже самое
C++
1
2
3
4
bool isTrue(int x)
{
    return !!x;
}
0
Croessmah
++Ͻ
14160 / 8085 / 1513
Регистрация: 27.09.2012
Сообщений: 19,925
Записей в блоге: 3
Завершенные тесты: 1
03.01.2015, 20:33 #12
ValeryS, а еще преобразование bool в int даст такой же результат, но это просто пример, что нечитабельно )))
0
ValeryS
03.01.2015, 20:35
  #13

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
ValeryS, а еще преобразование bool в int даст такой же результат
а кто спорит
просто написал явное приведение, но можно и без него

0
hoggy
Заблокирован
03.01.2015, 21:04 #14
Как то так:

http://rextester.com/DGY9511

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
#include <iostream>
using namespace std;
 
 
const char* msg[3][3] = 
{
    "4 четверть"                              , "на оси ординат между 4й и 1й чертвертями"  ,  "1 чертверть"  ,
    "на оси абцисс между 4й и 3ю чертвертями" , "в начале координат"                        ,  " на оси абцисс между 1й и 2й чертвертями",
    "3 четверть"                              , "на оси ординат между 3й и 2й чертвертями"  ,  "2 четверть"  ,
};
 
 
void detected(const int x, const int y)
{
    const int xx = 1 + (x<0 ? -1: int(bool(x)));
    const int yy = 1 - (y<0 ? -1: int(bool(y)));
    
    cout<<"----------------\n";
    cout<<"detected: "<< msg[yy][xx] << "\n";
}
 
 
int main()
{
    detected(0,0);        // начало координат
    detected(10,10);      // 1-я чертверть
    detected(10,0);       // между 1-2 
    detected(10,-10);     // 2-я чертверть
    detected(0,-10);      // между 3-2 
    detected(-10,-10);    // 3-я чертверть
    detected(-10,0);      // между 4-3 
    detected(-10,10);     // 4-я чертверть
}
1
ValeryS
Модератор
7133 / 5401 / 669
Регистрация: 14.02.2011
Сообщений: 18,223
03.01.2015, 22:25 #15
вот реализация с if
не знаю как насчет короче, но быстрее точно

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
 if (x > 0)
{
      if( y > 0) // x>0&&y>0
          cout << "Tochka nahoditsa v 1-oy chetverty " << '\n';
      else
        {
        if( y < 0)  // x>0&&y<0 
          cout << "Tochka v 4-oy chetverty " << '\n';      
        else   //x>0 &&y==0
          cout << "Tochka nahoditsa na osi X kotoraya razdelaet 1-uu i 4-uu chetverti " << '\n';
  
        }
 } 
else
  {
     if (x < 0)
     {
         if( y>0) //x<0&&y>0
            cout << "Tochka vo 2-oy chetverty " << '\n';
    else 
        {
         if(y < 0) // x<0&&y<0
           cout << "Tochka v 3-ey chetverty " << '\n';  
        else //x<0&&y==0
           cout << "Tochka nahoditsa na osi X kotoraya razdelaet 2-uu i 3-u chetverti " << '\n';
        }
     }
     else  //x==0
     {
        if( y > 0) //x==0&&y>0
        cout << "Tochka nahoditsa na osi Y kotoraya razdelaet 1-uu i 2-uu chetverti " << '\n';
        else
        {
         if(y < 0)//x==0&&y<0
          cout << "Tochka nahoditsa na osi Y kotoraya razdelaet 3-u i 4-uu chetverti " << '\n';
        else //x==0&&y==0
            cout << "Tochka nahoditsa v nachale koordinat " << '\n';
        } 
     }     
}
в самом пиковом случае x==0 и y==0 пройдет 4 сравнения (два по x и два по y)
в отличии от оригинала где пройдет 9
0
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
04.01.2015, 01:28 #16
hoggy, я бы подсократил чутка:
C++
1
2
3
4
5
6
7
8
void detected(int x, int y)
{
    x = 1 + (x<0 ? -1: bool(x));
    y = 1 - (y<0 ? -1: bool(y));
    
    cout<<"----------------\n";
    cout<<"detected: "<< msg[y][x] << "\n";
}
Хотя изменение значения аргумента функции далеко не для всех является приемлемым вариантом.
Особенно, если вдруг захочется получить исходное значение, переданное в функцию.

Ну а преобразование bool к int будет выполнено неявно в тернарном выражении.

И ещё фигурные скобки для группировки эл-ов массива хорошо бы добавить.
clang, например, ругается на это:
warning: suggest braces around initialization of subobject [-Wmissing-braces]
1
hoggy
Заблокирован
04.01.2015, 02:30 #17
Цитата Сообщение от Tulosba Посмотреть сообщение
hoggy, я бы подсократил чутка:
1. Нарушение строгих гарантий функции.
(не критично)

Цитата Сообщение от Tulosba Посмотреть сообщение
Ну а преобразование bool к int будет выполнено неявно в тернарном выражении.
Да, только компиляторы обижаются и сыпят ворнингами.

Поэтому я продакшене даже сишного приведения не допускаю (на него компиляторы так же реагируют)

2.
Цитата Сообщение от Tulosba Посмотреть сообщение
И ещё фигурные скобки для группировки эл-ов массива хорошо бы добавить.
Это справедливое замечание.
Действительно, лучше делать с фигурными скобками.
Однако онлайн-gcc предупреждения не сделал, и я это прошляпил.
Спасибо за критику кода.



Исправленная версия:
http://rextester.com/GHQ3255

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
#include <iostream>
using namespace std;
 
 
const char* msg[3][3] = 
{
    {"4 четверть"                              , "на оси ординат между 4й и 1й чертвертями"  ,  "1 чертверть"  },
    {"на оси абцисс между 4й и 3ю чертвертями" , "в начале координат"                        ,  " на оси абцисс между 1й и 2й чертвертями"},
    {"3 четверть"                              , "на оси ординат между 3й и 2й чертвертями"  ,  "2 четверть"}  ,
};
 
 
inline int cast(const int v)
{
    const bool tmp = static_cast<bool>(v);
    return static_cast<int>(tmp);
}
 
void detected(const int x, const int y)
{
    const int xx = 1 + ( x<0 ? -1: cast(x) );
    const int yy = 1 - ( y<0 ? -1: cast(y) );
    
    cout<<"----------------\n";
    cout<<"detected: "<< msg[yy][xx] << "\n";
}
 
 
int main()
{
    detected(0,0);        // начало координат
    detected(10,10);      // 1-я чертверть
    detected(10,0);       // между 1-2 
    detected(10,-10);     // 2-я чертверть
    detected(0,-10);      // между 3-2 
    detected(-10,-10);    // 3-я чертверть
    detected(-10,0);      // между 4-3 
    detected(-10,10);     // 4-я чертверть
}
Специально проверил: cl/gcc/clang
На максимальных уровнях предупреждений.
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
04.01.2015, 03:31 #18
У автора логично, но нечитаемо. В ответах автору нелогично и нечитаемо.
Если попытаться совместить логичность с читаемостью, то вот так можно:
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
#include <iostream>
#include <string>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string     T_str;
/////////////////////////////////////////////////////////////////////////////////////////
int     sign_to_ind( int  coord )
{
    return      coord   <   0
                    ?   0
                    :   coord   ==  0
                        ?   1
                        :   2;
}
/////////////////////////////////////////////////////////////////////////////////////////
T_str   get_information_about_point_position
    (
        int     x,
        int     y
    )
{
    T_str   pos_strings[]
        =   {
                //y > 0
                "Tochka vo 2-oy chetverty",                                             //x     <   0
                "Tochka nahoditsa na osi Y kotoraya razdelaet 1-uu i 2-uu chetverti",   //x     ==  0
                "Tochka v 1-oy chetverty",                                              //x     >   0
 
                //y == 0
                "Tochka nahoditsa na osi X kotoraya razdelaet 2-uu i 3-u chetverti",
                "Tochka nahoditsa v nachale koordinat",
                "Tochka nahoditsa na osi X kotoraya razdelaet 1-uu i 4-uu chetverti",
 
                //y < 0
                "Tochka v 3-ey chetverty",
                "Tochka nahoditsa na osi Y kotoraya razdelaet 3-u i 4-uu chetverti",
                "Tochka v 4-oy chetverty"
            };
 
    return  pos_strings
                [
                        sign_to_ind(  x )
                    +   sign_to_ind( -y ) * 3
                ];
}
/////////////////////////////////////////////////////////////////////////////////////////
void main()
{
    int     x;
    int     y;
 
    for(;;)
    {
        std::cout   <<  "x = ";
        std::cin    >>  x;
        std::cout   <<  "y = ";
        std::cin    >>  y;
 
        std::cout   <<  get_information_about_point_position( x, y )
                    <<  "."
                    <<  std::endl
                    <<  std::endl;
    }//for
}
0
ValeryS
Модератор
7133 / 5401 / 669
Регистрация: 14.02.2011
Сообщений: 18,223
04.01.2015, 03:55 #19
Цитата Сообщение от hoggy Посмотреть сообщение
const int xx = 1 + ( x<0 ? -1: cast(x) );
вот это можно сделать так
C++
1
int xx= (x>=0)+(x>0);
поскольку ? замаскированный if, тоже ветвление
а здесь только сравнения никакого ветвления
0
hoggy
Заблокирован
04.01.2015, 04:32 #20
Цитата Сообщение от ValeryS Посмотреть сообщение
вот это можно сделать так
C++
1
int xx= (x>=0)+(x>0);
Технически - можно.
Но я так не делаю.

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

И даже те люди, которые в курсе, что такое "промоушин типов с++"

4.5 Integral promotions [conv.prom]
1 An rvalue of type char, signed char, unsigned char, short int, or unsigned short int can be converted to
an rvalue of type int if int rvalue can be converted to an rvalue of type int if int can represent all the values of the
source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int.

2 An rvalue of type wchar_t (3.9.1) can be converted to an rvalue of the first of the following types that can represent
all the values of its underlying type: int, unsigned int, long, orint, unsigned long int, long long int, or
unsigned long long int. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the
following types that can represent all the values of the enumeration (i.e. the values in the range bmin to bmax as described
in 7.2: int, unsigned int, long, orint, unsigned long int, long long int, or unsigned long long int.

3 An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all the values of the
bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field.
If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any
other value of that type for promotion purposes.

4 An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one.

5 These conversions are called integral promotions
Тем не менее затрудняются дать четкий ответ: почему это так?

С чем связанно? То есть, понятно, что такое имеет место быть. Не понятно по какой такой логике? Для чего это нужно?

Единственное, более менее вразумительное объяснение, что я слышал:

Оптимизация. На современных процах арифметические операции над целыми, не совпадающими с разрядной сеткой машины, работают медленно.
(Ц)Один очень хороший человек.
Я не специалист по ассемблеру, поэтому мне сложно сказать чем на самом деле является такой код.
В общем, лично я избегаю подобного рода "писсимизаций".
Экономия на спичках ценой чрезмерного ухудшения читабельности, имхо.
0
04.01.2015, 04:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2015, 04:32
Привет! Вот еще темы с решениями:

На каком языке этот код и можно ли его переделать?
Добрый день Дамы и Господа Программисты. Вот тут мне дали код и попросили...

Как этот код написать грамотно?
__int64 __fastcall api::LicCheckUpdate(api *this) { __int64 v1; // rdi@1 ...

Как можно записать код в более компактном виде?
Вывести столбиком след. числа 3,2, 3,2, 3,3, 3,3,........3,9 у меня вышло...

код, который прекрасно выполняет Code::Blocks не выполняеться в Студии, как сделатьь так чтобы Студия воспринимала этот код??
Ребята, обьясните мне чего код, который прекрасно выполняет Code::Blocks не...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru