Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Ромб

3.6K
29 ноября 2005 года
Denton
41 / / 18.08.2004
Задача примитивная, но мне всё же интересно как решили бы ее опытные кодеры.

Вот мой вариант зарисовки ромба n-размера в консоле:
Код:
main()
{
int i,j,n;
int size=27;

// Рисуем вверх ромба (то есть обычный треугольник)
for(n=0;n<=size;n++){

    for(i=size-1;i>=n-1;i--)
       cout<<" ";
           cout<<"*";
          for(j=0;j<=n-1;j++)
             cout<<"**";

  cout<<endl;
}

//----------------------------------
//Середина
for(int z=0;z<=j+n+1;z++)
    cout<<"*";
   cout<<endl;
//----------------------------------

// Низ ромба (перевернутый треугольник)
for(n=0;n<=size;n++){

    for(i=0;i<=n;i++)
       cout<<" ";
         cout<<"*";
          for(j=size-1;j>=n;j--)
             cout<<"**";

  cout<<endl;
}


}


Если кто подскажет где и как можно оптимизировать (сжать код, избавиться от мусора), буду благодарен....
292
29 ноября 2005 года
Matush
726 / / 14.01.2004
Вот, то что получилось у меня. Код стал меньше, но более не понятен. Ну и быстродействиее меньше.
Но все равно прикольно получилось :)

Код:
const int Size = 15;
for(int y=0; y<Size; y++)
{
    for(int x=0; x<Size; x++)
    {
        if(((x>=Size/2) && (y >= x-Size/2) && (y-Size/2 <= Size-x-1)) ||
            ((x<=Size/2) && (y >= Size/2-x) && (y-Size/2 <= x)))
        {
            cout << "*";
        }
        else
            cout << " ";
    }
    cout << endl;
}


P.S Код годится для ромбов с углами 45. И с нечетным размером.
3
29 ноября 2005 года
Green
4.8K / / 20.01.2000
Мои пять копеек:
Код:
void rhomb(unsigned int width)
{
    unsigned int half = width/2;
    for(int i=0; i < half; ++i) {
        cout << setw(half-i) << setfill(' ') << ' ' << setw(i*2+1) << setfill('*') << '*' << endl;
    }
    cout << setw(half*2+1) << setfill('*') << '*' << endl;
    for(int i=half-1; i>=0; --i) {
        cout << setw(half-i) << setfill(' ') << ' ' << setw(i*2+1) << setfill('*') << '*' << endl;
    }
}

или такой вариант:
Код:
void rhomb(unsigned int width)
{
    unsigned int half = width/2;
    for(int i=0; i < half; ++i) {
        cout << string(half-i, ' ') << string(i*2+1, '*') << endl;
    }
    cout << string(half*2+1, '*') << endl;
    for(int i=half-1; i>=0; --i) {
        cout << string(half-i,' ') << string(i*2+1, '*') << endl;
    }
}
292
29 ноября 2005 года
Matush
726 / / 14.01.2004
to Green:
Я так понимаю у Тебя ВЦ7, он позволяет переопределять переменную (у Тебя int i).
Мое мнение - это плохо, что он такое позволяет. Или у Тебя другие соображения по этому поводу?
2.2K
29 ноября 2005 года
123tk
57 / / 28.06.2003
Код:
void main()
{
  const int size=27;
  char *a = new char[size+2];
  strnset(a, 32, size+1);
  char *chl = a + size/2;
  char *chr = chl;
  a[size+1] = 0;
  *chl = '*';
  while(chl>a)
  {
    cout << a << endl;  
    chr++;
    *chr = '*';
    chl--;
    *chl = '*';
  }
  while(chl<=chr)
  {
    cout << a << endl;  
    *chr = ' ';
    chr--;
    *chl = ' ';
    chl++;
  }
  delete[] a;
}
3
29 ноября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Matush
to Green:
Я так понимаю у Тебя ВЦ7, он позволяет переопределять переменную (у Тебя int i).
Мое мнение - это плохо, что он такое позволяет. Или у Тебя другие соображения по этому поводу?


По стандарту все ОК.
Я считаю, что это хорошо. :)
Т.к. четко видно, что i используется только внутри цикла.

292
29 ноября 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by Green
четко видно, что i используется только внутри цикла.


Ну, если так смотреть, то да, все ОК.
Просто ВЦ6 считал по другому.

P.S. Любиш ты подъ####

3
29 ноября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by 123tk
Код:
void main()
{
  const int size=27;
  char *a = new char[size+2];
  strnset(a, 32, size+1);
  char *chl = a + size/2;
  char *chr = chl;
  a[size+1] = 0;
  *chl = '*';
  while(chl>a)
  {
    cout << a << endl;  
    chr++;
    *chr = '*';
    chl--;
    *chl = '*';
  }
  while(chl<=chr)
  {
    cout << a << endl;  
    *chr = ' ';
    chr--;
    *chl = ' ';
    chl++;
  }
  delete[] a;
}


Хорошее решение. Подрехтовать, так вообще классное.

2.2K
29 ноября 2005 года
123tk
57 / / 28.06.2003
Цитата:
Originally posted by Green
Хорошее решение. Подрехтовать, так вообще классное.

По просьбе трудящихся.

Код:
const int size=27;

void main()
{
  char *a = new char[size+2];
  strnset(a, 32, size/2);
  char *chl = a + size/2;
  char *chr = chl;
  while(chl>a)
  {
    *chr = '*';
    chr++;
    *chr = 0;
    cout << a << endl;  
    chl--;
    *chl = '*';
  }
  *chr = '*';
  chr++;
  *chr = 0;
  while(chl<=chr)
  {
    cout << a << endl;  
    chr--;
    *chr = 0;
    *chl = ' ';
    chl++;
  }
  delete[] a;
}
Мин.число операций/мин. память. Программа настолько прямолинейна, что даже теореме Лобачевского: "прямые пересекаются в безкончности" - не удовлетворяет.
6.4K
30 ноября 2005 года
Host
122 / / 22.09.2005
Или такой вариант:
Код:
main()
{
COORD coord;
int size=25;
int k;
coord.X=size/2+1;
coord.Y=0;
HANDLE hout = ::GetStdHandle(STD_OUTPUT_HANDLE);
for(int j=0;j<size;j++)
{
    ::SetConsoleCursorPosition(hout,coord);
    k=j<size/2?(2*j+1):k=j==size/2?k+2:k-2;
    for(int i=0;i<k;i++)cout<<"*";
    coord.X= j<size/2?coord.X-1:coord.X+1;
    coord.Y=coord.Y+1;
}
}
292
30 ноября 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by 123tk
Мин.число операций/мин. память. Программа настолько прямолинейна, что даже теореме Лобачевского: "прямые пересекаются в безкончности" - не удовлетворяет.



Программа и правду классная.
Но сейчас прийдет Грин и скажет, мол учитесь писать на С++, и т.д. и т.п.
Хотя может после моего поста, он этого не скажет.

2.2K
30 ноября 2005 года
123tk
57 / / 28.06.2003
Цитата:
Originally posted by Matush
Программа и правду классная.
Но сейчас прийдет Грин и скажет, мол учитесь писать на С++, и т.д. и т.п.
Хотя может после моего поста, он этого не скажет.

На месте этого Green-а я бы срочно доработал, никуда не годяющуюся програмку с топика "Разминка для ума", чтоб сильно не краснеть, после того как я выставлю свою.

3
30 ноября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by 123tk
На месте этого Green-а я бы срочно доработал, никуда не годяющуюся програмку с топика "Разминка для ума", чтоб сильно не краснеть, после того как я выставлю свою.


Этот Green говорит: давай, выставляй, а там посмотрим, кому краснеть.

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

Код:
void rhomb(int size)
{
    char* str = new char[size+2];
    strnset(str, ' ', size);
    str[size] = '\0';
    str[size+1] = '\0';

    char* left  = str + size/2;
    char* right = left;

    while(left > str)
    {
        *right++ = '*';
        *left--  = '*';
        cout << str << endl;  
    }

    *right = '*';
    *left  = '*';
    cout << str << endl;  

    while(left < right)
    {
        *right-- = ' ';
        *left++  = ' ';
        cout << str << endl;  
    }

    delete[] str;
}
3.6K
30 ноября 2005 года
Denton
41 / / 18.08.2004
Cпасибо парни, за ваши варианты. Есть чему поучится.....
2.2K
30 ноября 2005 года
123tk
57 / / 28.06.2003
Цитата:
Originally posted by Green
Этот Green говорит: давай, выставляй, а там посмотрим, кому краснеть.

Слушай сюда, Этот Green! Ты не смотри на то, что у меня 30 с чем-то ответов, а у Тебя более 1700. А на мой ник вообще не обращай внимание, так как я был заграницей и забыл пароль от моего нормального ника. И благодаря одной недоделке mike-а, мне проще было определить чужой пароль, чем вспомнить свой. В выходные хотел уже войти под старым ником, но не получилось. Подумал, что mike заметил мое нахальство и забанил мой IP. Даже хотел отправить ему email и извиниться. Но вместо это mike извинился (извинение принимается :)), и пообещал, что больше это не повторится (Ok, будем надеяться :)).

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

Значит. Твоя прога:

1. Выделяется память 4*N*N байт.
2. Копируется матрица в эту память.
3. Определяется высота для каждой ячейки.
4. Определяется макс.область.

Вопрос, для чего выделять память, потом копировать значения, если каждый раз нужна высота только для текущей строки?

1. Выделяется память 4*N байт.
2. Первая строка копируется в эту память и сразу же имеем высоту для ячеек первой строки.
3. Определение макс. области начинается с 2й строки. Если текущий элемент = 0, тогда просто пишется в соответствующую позицию выделенной памяти 0. Если не 0, тогда берется значение из соотв. позиции, увеличивается на 1 и пишется обратно и ячейка обрабатывается.
4. Если в конце проверки макс.площадь меньше n, тогда проверяется первая строка.

Качество алгоритма определяет не только быстродействие, но и требуемая доп. память. У моей проге это будет порядка N, у твоей N^2.
Напр. для матриц с N=8192 моя прога выделит 32kB, твоя 256МБ.
[color=white]__ __[/color]32 768 байт против
268 435 456 байт.
Т.е. относительно памяти, твоя прога просто нигде.

На счет быстродействия.
Пару месяцев тому назад переделывал одну программу. В ней проверялся допустимы ли координаты x,y и если да, тогда значение ячейки менялось на 1. a[x][y] = 1;
[x][y] заменил на int* и убрал проверку диапозона. Только из-за этого прога начала работать быстрее более чем 5 раз.

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

3
01 декабря 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by 123tk
Слушай сюда, Этот Green! Ты не смотри на то, что у меня 30 с чем-то ответов, а у Тебя более 1700. А на мой ник вообще не обращай внимание, так как я был заграницей и забыл пароль от моего нормального ника. И благодаря одной недоделке mike-а, мне проще было определить чужой пароль, чем вспомнить свой. В выходные хотел уже войти под старым ником, но не получилось. Подумал, что mike заметил мое нахальство и забанил мой IP. Даже хотел отправить ему email и извиниться. Но вместо это mike извинился (извинение принимается :)), и пообещал, что больше это не повторится (Ok, будем надеяться :)).


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

Цитата:
Originally posted by 123tk

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


Мы, если ты мимоходом это не заметил, обсуждали алгоритм, а не реализацию (программу).

Цитата:
Originally posted by 123tk

Значит. Твоя прога:

1. Выделяется память 4*N*N байт.


Ну если быть точнее, то (N+2)*(N+2)... :)

Цитата:
Originally posted by 123tk

1. Выделяется память 4*N байт.
2. Первая строка копируется в эту память и сразу же имеем высоту для ячеек первой строки.
3. Определение макс. области начинается с 2й строки. Если текущий элемент = 0, тогда просто пишется в соответствующую позицию выделенной памяти 0. Если не 0, тогда берется значение из соотв. позиции, увеличивается на 1 и пишется обратно и ячейка обрабатывается.
4. Если в конце проверки макс.площадь меньше n, тогда проверяется первая строка.


Ты описал реализацию, предложенного мной алгоритма. Только и всего.
Совместил вместе два раздельных шага, что уже делал по-своему REmindER.

Реализаций этого алгоритма может быть множество, суть одна - два шага: нахождение проекций и обход этих проекций.
Я же доводил этот алгоритм в наиболее понятной форме. Для тех, кто в танке, ещё раз обращаю внимание:
"Во-первых, требовался оптимальный по сложности (скорости) АЛГОРИТМ, о реализации пока речи не было."
Ну и в топике соотв. ветки это указано.

Цитата:
Originally posted by 123tk

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


Ну во-первых, это зависит от критериев оценки.
В топике критерием значилась сложность, т.е. зависимоть кол-ва итераций от размеров матрицы.
Во-вторых, память - это вопрос реализации.

Цитата:
Originally posted by 123tk

У моей проге это будет порядка N, у твоей N^2.
Напр. для матриц с N=8192 моя прога выделит 32kB, твоя 256МБ.
[color=white]__ __[/color]32 768 байт против
268 435 456 байт.
Т.е. относительно памяти, твоя прога просто нигде.


Ну пока твоей проги просто нет нигде... :D :D :D
Кроме того, я ещё раз говорю (до чего же люди бывают твердолобы):
Это всего-лишь интуитивно понятная реализация очень близкая к простому описанию.

Кстати, практика показывает, а умы программирования рекомендуют, что первая реализация должна быть наиболее простой. Оптимизация - это последующие шаги. Для начала надо удостовериться в работоспособности алгоритма.

Цитата:
Originally posted by 123tk

На счет быстродействия.
Пару месяцев тому назад переделывал одну программу. В ней проверялся допустимы ли координаты x,y и если да, тогда значение ячейки менялось на 1. a[x][y] = 1;
[x][y] заменил на int* и убрал проверку диапозона. Только из-за этого прога начала работать быстрее более чем 5 раз.


Ну чтож , молодец. Этот процесс называется оптимизацией и начинается, когда есть работоспособный код.
Кстати, ты использовал unitesting?
А как определил увеличение производительности?
Каким способом профилировал программу?
Ты уверен, что в 5 раз, а не в 4.75 или 5.25 раз?
Это было самое слабое место в программе?
Какие ещё типы оптимизации рассматривались?

Цитата:
Originally posted by 123tk

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


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

Цитата:
Originally posted by 123tk

Так что всеж таки я на твоем месте срочно исправил бы программу. :)


"Исправил"?
Я не вижу ошибок, а сл-но она на данный момент может считаться исправной.

Может, ты путаешься в терминах? Хотел сказать "я на твоем месте срочно ОПТИМИЗИРОВАЛ бы программу " ?

Вопрос: а зачем?
Цель достигнута, - получена рабочая реализация алгоритма, которая интуитивно понятна.
Оптимизировать можно до бесконечности, был ла бы необходимость и были бы определены критерии оптимизации.
Я такой задачи в теме не ставил. Реализацию и то привел, для наглядности.

P.S. Если есть вопросы, предложения, мысли и ещё неинтересные истории из твоей нелегкой жизни, то пиши в соотв. теме. Эта тема "Ромб", на сколько мне известно.

2.2K
01 декабря 2005 года
123tk
57 / / 28.06.2003
1. На счет чужого ника. Я где-то год тому назад писал mike-у об этом. Может он это не получил. Типа не нужно разрешить ввод любого пароля. Должна быть проверка на несовпадение с ником и пароль должен содержать хотя бы 2 различные символы.

2. На счет всего остального. Take it easy. ;)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог