подскажите по чистописанию)
От: Аноним  
Дата: 13.06.08 15:50
Оценка:
Вот к примеру у меня в проге свич с кучей кейсов, но в этих кейсах относительно одинаковые действия нужно выполнять. Т.е. меняются только значения положений символов в строчке, как это можно компактнее оформить?
switch(Type){
case one
printf("1\n");
break;
case two:
printf("2\n");
break;
case three:
printf("3\n");
break;
case four:
printf("4\n");
break;
case five:
printf("5n");
default:
break;
}// switch

Как напистаь так, что-бы можно было подставлять разые значения в принт? В целом пока от кейсов избавляться не хочу, слишком много менять сразу, буду постепенно
Re: подскажите по чистописанию)
От: Аноним  
Дата: 13.06.08 15:55
Оценка:
map<ClassType,int> m;
m[one] = 1;
...
m[five] = 5;

printf("%d\n",m[Type]);
Re[2]: подскажите по чистописанию)
От: Аноним  
Дата: 14.06.08 02:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>map<ClassType,int> m;

А>m[one] = 1;
А>...
А>m[five] = 5;

А>printf("%d\n",m[Type]);

А если у меня СИ, там вроде нет классов?!
Re[3]: подскажите по чистописанию)
От: FR  
Дата: 14.06.08 03:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А если у меня СИ, там вроде нет классов?!


А у тебя Type что?
Если его интервал не очень большой, то просто:

const char* m[MaxType];
m[one] = "one";
m[two] = "two";
Re: подскажите по чистописанию)
От: jazzer Россия Skype: enerjazzer
Дата: 14.06.08 07:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вот к примеру у меня в проге свич с кучей кейсов, но в этих кейсах относительно одинаковые действия нужно выполнять. Т.е. меняются только значения положений символов в строчке, как это можно компактнее оформить?

А>
А>switch(Type){
А>case one
А>printf("1\n");
А>break;
А>case two:
А>printf("2\n");
А>break;
А>case three:
А>printf("3\n");
А>break;
А>case four:
А>printf("4\n");
А>break;
А>case five:
А>printf("5n");
А>default:
А>break;
А>}// switch
А>

А>Как напистаь так, что-бы можно было подставлять разые значения в принт? В целом пока от кейсов избавляться не хочу, слишком много менять сразу, буду постепенно

если у тебя все одинаковое абсолютно и нет функции, по которой можно было бы вычислить из кейса получить то, что нужно напечатать (или что там у тебя), то макросы рулят, делая код значительно чище (не компилировал):
switch (Type)
{
  #define PROCESS(a,b) case a: printf(b##"\n"); /*еще куча одинаковых действий*/ break;
  PROCESS(one, 1);
  PROCESS(two, 2);
  PROCESS(three, 3);
  PROCESS(four, 4);
  PROCESS(five, 5);
  #undef PROCESS
} // switch

естественно, макросы можно комбинировать с функциями
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: подскажите по чистописанию)
От: andrey.desman  
Дата: 14.06.08 07:27
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Вот к примеру у меня в проге свич с кучей кейсов, но в этих кейсах относительно одинаковые действия нужно выполнять. Т.е. меняются только значения положений символов в строчке, как это можно компактнее оформить?

А>Как напистаь так, что-бы можно было подставлять разые значения в принт? В целом пока от кейсов избавляться не хочу, слишком много менять сразу, буду постепенно

Можно табличку сделать:

typedef struct
{
    Type m;
    const char *str;
} TABLE;

TABLE map_table[] =
{
    {one, "1\n"},
    // ...
    {one_million, "1000000\n"},
};


и функцию для поиска. Если поиск линейный, то это эквивалент switch. А если можно отсортировать таблицу, то это даже будет быстрее.
Re[2]: подскажите по чистописанию)
От: andrey.desman  
Дата: 14.06.08 07:29
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>и функцию для поиска. Если поиск линейный, то это эквивалент switch. А если можно отсортировать таблицу, то это даже будет быстрее.


Я имел в виду, что если бинарный поиск будет уместен, то это будет быстрее чем обычный switch.
Re[3]: подскажите по чистописанию)
От: FR  
Дата: 14.06.08 08:00
Оценка: +1
Здравствуйте, andrey.desman, Вы писали:

AD>Я имел в виду, что если бинарный поиск будет уместен, то это будет быстрее чем обычный switch.


На современных компиляторах быстрее не будет они сволочи большой switch тоже в табличку превращают
Re[2]: подскажите по чистописанию)
От: Аноним  
Дата: 14.06.08 14:23
Оценка:
AD>Можно табличку сделать:
вот это уже интереснее
У меня есть куча ифов которые возвращают определенные значения в другую функцию, например
if (!one |  !two)
                return one;
        else if (!tree | four )
                return tree;
..etc..

Потом значение попадает в нужный кейс и выполняет все действия в нем. Как это для арреев будет выглядеть?
const char * Type[] = {
    "1\n", "2\n", "3\n", "4\n", "5\n", "", "", ""
};
...
printf(array[(Type - 1) & 7]);


>Я имел в виду, что если бинарный поиск будет уместен, то это будет быстрее чем обычный switch.

"бинарный поиск"- это как?
Re[3]: подскажите по чистописанию)
От: Кодёнок  
Дата: 16.06.08 07:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>map<ClassType,int> m;

А>>m[one] = 1;
А>>...
А>>m[five] = 5;

А>>printf("%d\n",m[Type]);

А>А если у меня СИ, там вроде нет классов?!

int keys   = { one, two, three, five, };
int values = {   1,   2,     3,    5, };
// search keys[index]==T and use values[index]

// если так можно в С99, то
struct { int k, v; } = { {one,1}, {two,2}, };
// search
Re[3]: подскажите по чистописанию)
От: Кодт Россия  
Дата: 16.06.08 11:32
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>У меня есть куча ифов которые возвращают определенные значения в другую функцию, например

А>
А>if (!one |  !two)
А>                return one;
А>        else if (!tree | four )
А>                return tree;
А>..etc..
А>

Наверное, всё-таки не такие условия, а if(x!=one && x!=two)... Потому что иначе это сплошное trueЪ.
Очень легко построить табличку MyEnumType->MyEnumType, реализующую твою функцию.
typedef enum
{
    one,
    two,
    .....,
    seven,
    
    MyEnumType_min = one,
    MyEnumType_max = seven,
    MyEnumType_range = MyEnumType_max-MyEnumType_min+1,
} MyEnumType;


MyEnumType f(MyEnumType x)
{
    if(x!=one && x!=two)    return one;
    .....
}

MyEnumType f_table[MyEnumType_range];
void init_f_table()
{
    for(int x=MyEnumType_min; x!=MyEnumType_max+1; ++x)
        f_tabulated[x-MyEnumType_min] = f((MyEnumType)x);
}
MyEnumType f_tabulated(MyEnumType x)
{
    assert(x >= MyEnumType_min && x <= MyEnumType_max); // или ещё как-то надавать по пальцам за выход из диапазона
    return f_table[x-MyEnumType_min];
}


А>Потом значение попадает в нужный кейс и выполняет все действия в нем. Как это для арреев будет выглядеть?

А>
А>const char * Type[] = {
А>    "1\n", "2\n", "3\n", "4\n", "5\n", "", "", ""
А>};
А>...
А>printf(array[(Type - 1) & 7]);
А>

Только в буквах не путайся:
const char * const show[MyEnumType_range] = { "1", "2", ..... }; // не надо сюда пихать лишнего - \n, в частности

MyEnum x;
...
assert(x >= MyEnumType_min && x <= MyEnumType_max);

int i = x-MyEnumType_min;
// если очень хочется устойчивости ценой возможного абсурда, то
i %= MyEnumType_range;

printf("x = %s\n", show[i]);


>>Я имел в виду, что если бинарный поиск будет уместен, то это будет быстрее чем обычный switch.

А>"бинарный поиск"- это как?

Это вот так, если закодировать намертво
if(x < five)
    if(x < three)
        if(x < two)
            return "1";
        else
            return "2";
    else
        if(x < four)
            return "3";
        else
            return "4";
else
    .....

или так
MyEnumType all[] = { one, two, ....., };
pos = search_lower_bound(all, 0, _countof(all), x);

// где 
int search_lower_bound(MyEnumType const* data, int i, int j, MyEnumType value) // ищем в полуинтервале [i,j)
{
    int m; // медиана
    while(i+1<j) // пока полуинтервал не пуст и не состоит из единственного элемента
    {
        m = (i+j)/2;
        if(data[m]<value)
            j=m;
        else
            i=m;
    }
    return i;
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.