PDA

Просмотр полной версии : [C/C++] ЗАДАНИЯ


Fata1ex
21.06.2009, 15:46
По аналогии с темой (http://forum.antichat.ru/thread126194.html) Krist_ALL'a решил создать отдельный топик с заданиями по С/С++. Надеюсь что вы enjoy it ;)

Задание 1.
int a, sum=0; char buf[4096];
printf("Tell me your name:"); gets(buf);
for(a=0; a<100; a++) sum+=0;
//(с) мыщьх

Как оптимизировать программу с точки зрения использования ею оперативной памяти? И что в ней не так?

Верное решение (http://forum.antichat.ru/showpost.php?p=1345045&postcount=5)


Задание 2.

Мы создаем класс без конструкторов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор без аргументов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор копии. Что сгенерирует компилятор дополнительно?


Задание 3.
class SimpleClass {
private:
int a;
int b;
public:
SimpleClass(int x) : b(x), a(b) {}
void print() {
std::cout << "a=" << a << " b=" << b << std::endl;
}
};

int main() {
SimpleClass a(42);
a.print();
return 0;
}

Что здесь не так?

Верное решение (http://forum.antichat.ru/showpost.php?p=1346178&postcount=29)


Задание 4.

class A {
public:
virtual void Foo (int n = 10) {
cout << "A::Foo, n = " << n << endl;
}
};

class B : public A {
public:
virtual void Foo (int n = 20) {
cout << "B::Foo, n = " << n << endl;
}
};

int main() {
A * pa = new B ();
pa->Foo ();

return 0;
}
//(c) habrahabr//h1ppo

Что выведет программа и почему?

Верное решение (http://forum.antichat.ru/showpost.php?p=1345980&postcount=24)


Задание 5.
foo() {
char a;
char b;
char c;
char d[5];
}
(c) мыщьх

Сколько байт локальной памяти мы израсходовали? Почему? Как оптимизировать эту "оптимизированную"(здесь подсказка;)) программу?

Верное решение (http://forum.antichat.ru/showpost.php?p=1345457&postcount=8)


Задание 6.

void display(int in) {
// What im doing here????????/
cout << ++in;
}

void foo() {
int a=10;
display(a);
}



Что выведет программа?

Верное решение (http://forum.antichat.ru/showpost.php?p=1346176&postcount=28)


Задание 7. (by slesh)


struct _REC {
unsigned char data1;
unsigned short data2;
bool data3;
bool data4;
bool data5;
bool data6;
bool data7;
unsigned short data8;
} REC;

Как оптимизировать данную структуру чтобы она занимала в памяти 6 байта, то есть sizeof(REC) = 6
В таком виде структура занимает 12 байт.
При этом не был потерян функционал!!!

Верное решение (http://forum.antichat.ru/showpost.php?p=1345788&postcount=10)
Верное решение (http://forum.antichat.ru/showpost.php?p=1345981&postcount=25)



Задание 8. (by slesh)

Необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!

#include "stdio.h"
void _stdcall Sleep(unsigned long dwMilliseconds);
int main(int argc, char* argv[]) {
printf("START PAUSE");
Sleep(2000);
printf("STOP PAUSE");
return 0;
}

ПОДСКАЗКА: решение требует дописания одной строки.

Верное решение (http://forum.antichat.ru/showpost.php?p=1345862&postcount=17)


Задание 9. (by slesh)


#include "stdio.h"
#include "windows.h"
int main(int argc, char* argv[]) {
printf("SRART\n");
__asm
{
hlt
}
return 0;
}


При выполнении появляется ошибка из-за того, что команда hlt является привилегированной и недоступной из пользовательского режима.
Необходимо обработать это исключение, выдать на экран сообщение об ошибке и завершить работу программы.
И Главное - решение не должно использовать конструкцию try except и должно иметь глобальные характер. т.е. даже если это исключение появится в отдельном потоке, то действия программы должны быть такими же.
P.S. Решение требует примерно 5 строчек кода.

Верное решение (http://forum.antichat.ru/showpost.php?p=1352055&postcount=77)


Задание 10.

Создать динамический двумерный массив размерностью N. Заполнить его значениями. Вывести значения массива на экран. Запрещается использовать символы '[' и ']'.

Верное решение (http://forum.antichat.ru/showpost.php?p=1351452&postcount=68)
Верное решение (http://forum.antichat.ru/showpost.php?p=1351598&postcount=71)


Задание 11.

Как можно выполнить эффективное побайтовое сравнение структур, не используя прагмы компилятора и группировку членов?

Верное решение (http://forum.antichat.ru/showpost.php?p=1348763&postcount=57)


Задание 12.

for (int k=0, int A=0; k < strlen(str); k++)
A+=str[k];

Оптимизировать код.

Верное решение (http://forum.antichat.ru/showpost.php?p=1348067&postcount=43)
Особое решение slesh'a (http://forum.antichat.ru/showpost.php?p=1348033&postcount=39) :)


Задание 13.

Что эффективней использовать и почему:
strcpy(str, "bytes "); strcat(str, very_long_string);
или
strcpy(str, "bytes: "); strcat(str, very_long_string);
?

Верное решение (http://forum.antichat.ru/showpost.php?p=1353540&postcount=85)


Задание 14.

Создать массив, начальный индекс которого есть произвольное число (например, 1, а не с 0).

Верное решение (http://forum.antichat.ru/showpost.php?p=1353102&postcount=83)


Задание 15.

const int x = 1; {
enum { x = x + 1, y, z = x };
std::cout << x << ' ' << y << ' ' << z << std::endl;
}

Что выведет программа и почему? Без компиляции, пожалуйста )

Верное решение (http://forum.antichat.ru/showpost.php?p=1348165&postcount=51)


Задание 16. (by desTiny)

Что будет в переменной после выполнения кода (не компилить!)
/*very very long not ever overflowable*/ int a = 5+765432l;
?

Верное решение (http://forum.antichat.ru/showpost.php?p=1358618&postcount=90)


Задание 17. (by fker)

Ввести число n, и заполнить двухмерный массив размерностью n числами от 1 до n*n по спирали.

Верное решение (http://forum.antichat.ru/showpost.php?p=1376678&postcount=103)


Задание 18.

Привести три эффективных варианта выхода из большого количества вложенных циклов без использования операторов break.

Верное решение (Part 1) (http://forum.antichat.ru/showpost.php?p=1376663&postcount=101) + Верное решение (Part 2) (http://forum.antichat.ru/showpost.php?p=1376923&postcount=115)


################################################## ###########################

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

Еще хочу добавить: если вам интересны интересные(оО) и нестандартные задачи по С/С++, вам понравится книги
Г. Саттер - Решение сложных задач C++
Г. Саттер - Новые сложные задачи C++
М.В. Мозговой - 85 нетривиальных проектов, решений и задач

Gar|k
21.06.2009, 16:26
задание одын

int sum=0; char buf[]="Tell me your name:";
puts(buf); fgets(buf, sizeof(buf), stdin);
??

Fata1ex
21.06.2009, 16:31
Нет, имелось в виду несколько не это ) Присмотрись к циклу, к порядку появления переменных.
PS Переполнение здесь роли не играет.

nemaniak
21.06.2009, 21:22
может быть так?

int a, sum=0; char buf[4096];
printf("Tell me your name:"); gets(buf);
for(a=0; a<100; a++, sum++);

jawbreaker
21.06.2009, 21:37
В первой задаче для локальных переменных будет использовано слишком много стековой памяти (8 килобайт вместо 4). Бороться с этим можно если запихать данные в структурку

Fata1ex
21.06.2009, 21:42
Совершенно верно )

Fata1ex
21.06.2009, 22:13
Добавил пару задачек

FireFenix
22.06.2009, 01:04
foo() {
char a;
char b;
char c;
char d[5];
}

За счёт выравнивания будет 20 байт (3[a,b,c] по 4 байта, d выравняет на 8 байт = 20 байт)
Если всё запихнуть в структуру, то будет оптимизированно

void display(int in) {
// What im doing here????????/
cout << ++in;
}

void foo() {
int a=10;
display(a);
}

Поидее должно вывести 11, т.е. вначале выполнится инкремент (т.к. знак инкремента стоит слева, если справа - то после вывода), птом вывод

slesh
22.06.2009, 09:25
А вот задачка от меня



struct _REC
{
unsigned char data1;
unsigned short data2;
bool data3;
bool data4;
bool data5;
bool data6;
bool data7;
unsigned short data8;
} REC;


Как оптимизировать данную структуру чтобы она занимала в памяти 6 байта. т.е. sizeof(REC) = 6
В таком виде структура занимает 12 байт.
При этом небыл потерян функционал!!!

Ra$cal
22.06.2009, 09:50
struct _REC
{
unsigned short data2;
unsigned short data8;
unsigned char data1;
bool data3:1;
bool data4:1;
bool data5:1;
bool data6:1;
bool data7:1;
} REC;

=)

slesh
22.06.2009, 09:54
Практически правильно, но есть способо без изменения позиции переменных

Его необходимо применить чтобы данная структура стала 7 байт и не потерялся функционал

struct _REC
{
struct
{
unsigned char data1;
unsigned short data2;
bool data3;
bool data4;
bool data5;
} first_rec;
bool data6;
bool data7;
unsigned short data8;
} REC;


Также более наглядно будет в этом примере:
Размер должен быть 7 байт!!

struct _REC
{
unsigned short data1;
unsigned short data2;
unsigned short data3;
bool data4;
bool data5;
bool data6;
bool data7;
bool data8;
} REC;

slesh
22.06.2009, 10:05
P.S. Существуют 2 решения, оба сводятся к одному и томуже, но реализуются соверщенно по разному

FireFenix
22.06.2009, 10:13
Практически правильно, но есть способо без изменения позиции переменных
Использовать вместо структуры - объединения (union)?

slesh
22.06.2009, 10:17
Нет union делает другое

slesh
22.06.2009, 10:20
А вот еще одно задание довольно интерестное, если сразу задуматься, то быстро можно решить.

ЗАДАЧА: необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!

#include "stdio.h"

void _stdcall Sleep(unsigned long dwMilliseconds);

int main(int argc, char* argv[])
{
printf("START PAUSE");
Sleep(2000);
printf("STOP PAUSE");
return 0;
}



ПОДСКАЗКА: решение требует дописания одной строки.

Ra$cal
22.06.2009, 10:29
вот вам моя задачка. есть класс с перегруженным оператором <. есть вектор, который хранит shared_ptr'ы на объекты этого класса. задача - поюзать std::sort не создавая левые функции, только при помощи stl b boost::bind. второй день не могу понять в чем дело =\ был бы вектор чистых объектов - можно было отсортировать строкой

std::sort(state_lines.begin(), state_lines.end());

а я уже опустился до дублирования сравнения в статик методе less

std::sort(state_lines.begin(), state_lines.end(),
boost::bind<bool>(&HorizontalStateLine::less, _1, _2));

все равно не компилится =\
e:\Program Files\boost\boost_1_38\boost\bind.hpp(282): error C2664: 'bool (const geometry::HorizontalStateLine &,const geometry::HorizontalStateLine &)' : cannot convert parameter 2 from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine &'
with
[
_Ty=geometry::HORIZONTALSTATELINE_PTR
]
e:\Program Files\boost\boost_1_38\boost\bind.hpp(282): error C2664: 'bool (const geometry::HorizontalStateLine &,const geometry::HorizontalStateLine &)' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine &'
with
[
_Ty=geometry::HORIZONTALSTATELINE_PTR
]
Reason: cannot convert from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine'
with
[
_Ty=geometry::HORIZONTALSTATELINE_PTR
]
No constructor could take the source type, or constructor overload resolution was ambiguous



люто бешено не понимаю почему от простого изменения типа элемента с объекта на указатель творится такая жопа


[ADDED]
сцуко скомпилелось =\\\ пришлось сделать внутри класса такое вот

static bool less (const HORIZONTALSTATELINE_PTR& left, const HORIZONTALSTATELINE_PTR& right);

FireFenix
22.06.2009, 10:37
А вот еще одно задание довольно интерестное, если сразу задуматься, то быстро можно решить.

ЗАДАЧА: необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!

#include "stdio.h"

void _stdcall Sleep(unsigned long dwMilliseconds);

int main(int argc, char* argv[])
{
printf("START PAUSE");
Sleep(2000);
printf("STOP PAUSE");
return 0;
}



ПОДСКАЗКА: решение требует дописания одной строки.

extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long dwMilliseconds);

slesh
22.06.2009, 10:41
Ну и вот еще одна задачка от меня, если заюзать поиск то можно быстро решить её.
ЗАДАЧА: существует програмка

#include "stdio.h"
#include "windows.h"

int main(int argc, char* argv[])
{
printf("SRART\n");
__asm
{
hlt
}
return 0;
}


При выполненни вылезит ошибка из-за того что команда hlt является привелегированной и недоступной и пользопательноского режима.

Необходи обработать это исключение и выдать на экран сообщение об ошибке и завершить работу программы.

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

P.S. Решение требует примерно 5 строчек кода.

desTiny
22.06.2009, 11:20
Практически правильно, но есть способо без изменения позиции переменных

Его необходимо применить чтобы данная структура стала 7 байт и не потерялся функционал

Размер должен быть 7 байт!!
[code]
struct _REC
{
unsigned short data1;
unsigned short data2;
unsigned short data3;
struct{
unsigned data4:1;
unsigned data5:1;
unsigned data6:1;
unsigned data7:1;
unsigned data8:1;
} noch_eine_struktur;
} REC;

неявное преобразование типа должно сжевать.

только чушь это всё конечно)

slesh
22.06.2009, 11:41
2 desTiny всё делает намного проще )
И то что ты показал, то 12 байт вообще )

rudvil
22.06.2009, 12:03
Извиняюсь за глупый вопрос, но что делает эта единица в конце? bool data7:1;
Ведь таким же образом наследуют структуры и классы, а тут мистическая цифра "1" =/

slesh
22.06.2009, 12:06
это значит что ты эта переменная будит занимать 1 бит.
И по этому конструкция в структуре типа
bool data1:1;
bool data2:1;
bool data3:1;
bool data4:1;
bool data5:1;
bool data6:1;
bool data7:1;
bool data8:1;
тудет занимать 1 байт

rudvil
22.06.2009, 12:13
Интерестно, спасибо.

jawbreaker
22.06.2009, 12:13
Задание 4.

class A {
public:
virtual void Foo (int n = 10) {
cout << "A::Foo, n = " << n << endl;
}
};

class B : public A {
public:
virtual void Foo (int n = 20) {
cout << "B::Foo, n = " << n << endl;
}
};

int main() {
A * pa = new B ();
pa->Foo ();

return 0;
}
//(c) habrahabr//h1ppo

Что выведет программа и почему?

Ну видимо B::Foo, n = 10 потому что значение по умолчанию будет взято из другой функции?

desTiny
22.06.2009, 12:13
ок, так: struct _REC
{
unsigned data1:16;
unsigned data2:16;
unsigned data3:16;
unsigned data4:1;
unsigned data5:1;
unsigned data6:1;
unsigned data7:1;
unsigned data8:1;
} REC;

//его почему-то short смущал

slesh
22.06.2009, 12:16
2 desTiny Это правильный, но некрасивый способо. Есть более красивый и удобный)

Fata1ex
22.06.2009, 12:57
Спасибо всем, кто поддержал тред. Обновил первый пост: есть нерешенные задачи!

Lee_fx
22.06.2009, 13:32
void display(int in) {
// What im doing here????????/
cout << ++in;
}

void foo() {
int a=10;
display(a);
}

Ничего не выведет, ??/ - триграф = \(конкатенация), в итоге получится функция void display(int in) {}

Lee_fx
22.06.2009, 13:33
class SimpleClass {
private:
int a;
int b;
public:
SimpleClass(int x) : b(x), a(b) {}
void print() {
std::cout << "a=" << a << " b=" << b << std::endl;
}
};

int main() {
SimpleClass a(42);
a.print();
return 0;
}

Насколько помню тут первой инициализируется переменная a, так как стоит первая в объявлении в private и инициализируется соответственно мусором из b. Короче SimpleClass(int x) : b(x), a(b), порядок b(x), a(b) или a(b), b(x) не важен.

Fata1ex
22.06.2009, 13:43
Немного поправлю:
Списки инициализаторов инициализируют члены данных в порядке их следования в определении класса. Отсюда проблемы = )
Решения приняты )

desTiny
22.06.2009, 20:33
2 desTiny Это правильный, но некрасивый способо. Есть более красивый и удобный)
разумеется, он убогий) как и вся идея сожрать 4 байта

Кстати, мой VS сказал про него "8 байт". и про такое тоже:
struct _REC
{
unsigned short a,b,z;
bool c:1,d:1,e:1,f:1,g:1;
} REC;

slesh
22.06.2009, 21:19
Вижу что мало кто юзает данный способ по этому напишу правильный ответ сам )
Это директивы компилятора, которые на время могут менять выравнение структур.
Подефолту выравнение идет на 4 байта. т.е. если структура будет 9 байт, то выравнеется на 12.
#pragma pack(1) - выравнение 1 байт
#pragma pack() - дефолтовое выранение. вот и выходит код типа

#pragma pack(1)
struct .....
#pragma pack()

Fata1ex
22.06.2009, 21:22
Кстати, одним из решений другого задания (5) тоже были директивы и никто не написал :(
Забыли их, бедняжек (
Added: перечитал пару статей: действительно, скорость при использовании прагм компилятора падает. Иногда значительно.

slesh
22.06.2009, 21:26
А вешь очень удобная для оптимизации работы программы.
А если писать свой клиент-сервер которые общаются по своему протоколу, то такое просто необходимо юзать для снижения трафа

Fata1ex
22.06.2009, 21:28
Вообще это можно использовать не только в сетевых приложениях, а везде ) Лишних пару сэкономленных байт еще никому не мешали.
Added: перечитал пару статей: действительно, скорость при использовании прагм компилятора падает. Иногда значительно.

slesh
22.06.2009, 23:46
Кстати не всегда это делать желательно, потому как бываются случае что
адрес переменной должен быть выравнен на 4 байта иначе будет ошибка.
Такое встречается в некоторых WinAPI функцих которые просто убивают приложение если адрес буфера не выравненн на 4 байта

Ra$cal
23.06.2009, 00:27
это еще приводит к замедлению работы, ибо обращение к невыравненной ячейке памяти дает штраф

При этом различные процессоры по-разному подходят к адресации слов.
Во-первых, некоторые процессоры (PDP-11, SPARC) запрещают обращения к словам, адрес которых не кратен размеру слова, и генерируют при попытках такого обращения исключительную ситуацию ошибки шины. Другие процессоры, например VAX и х86 такие обращения разрешают, но в документации есть честное предупреждение, что обращения к невыровненным словам будут минимум в два раза медленнее, чем к выровненным (рис. 2.4).

Fata1ex
23.06.2009, 09:04
Добавил несколько несложных задачек. Не решены задания 2, 9, 10, 11, 12, 13, 14.
С радостью выслушаю любые ваши предложения и замечания )

slesh
23.06.2009, 11:01
здание 12 хочу решить так ))


int a = 0;
char * k = str;
while (k[0])
{
a += k[0];
k++;
}

Fata1ex
23.06.2009, 11:07
Нужно отредактировать исходный код )) Хотя твоя версия, безусловно, верна.

Roston
23.06.2009, 11:09
14) не совсем понял но всё же можно так

srand(time(NULL));
for(i=0;i<n;i++)
a[i]=random(20)+1;
/*random(20) будет делать рендом от 0 до 19 а так если прибавить единицу то от 1 до 20*/

Fata1ex
23.06.2009, 11:11
Отредактировал условие 14 задания, спасибо )

Roston
23.06.2009, 11:15
12)
в цикле каждый раз идет обьявление и каждый раз считаеться размер str
моя версия

int k=0,A=0,n=strlen(str);
for(k=0;k<n;k++)
A+=str[k];


З.Ы. Заметь у тя счётчик масива k а ты в условии сколько выполнять цикл поставил i=)

Fata1ex
23.06.2009, 11:17
Совершенно верно )
Баг со счетчиком был already героически пофикшен :)

Хочу добавить, что добавил(оО) слишком много репутации в за последние пару часов, поэтому дополнительное вознаграждение за участие будет позже = )

Roston
23.06.2009, 11:32
в 13) вся заковиренка в символе :?

Fata1ex
23.06.2009, 11:48
Странный вопрос. Разумеется да, потому что это единственное, чем отличаются два случая.

Roston
23.06.2009, 11:51
тогда мой окончательный ответ что использовать

strcpy(str, "bytes "); strcat(str, very_long_string);
чем

strcpy(str, "bytes: "); strcat(str, very_long_string);

Fata1ex
23.06.2009, 11:54
Главным является вопрос "почему?" )
Добавил задачку.

Roston
23.06.2009, 11:58
оно занимает на один байт больше

Fata1ex
23.06.2009, 12:01
Нет, имелось в виду не это )

Roston
23.06.2009, 12:17
15)
2 3 2
Обьяснение:
перечисления... если б Х ничего не присваивалось тогда бы вывод значения был бы в зависимости от расположения переменной и каждое следуещее значение инкрементировалось на 1, тобишь если б

enum {x,y,z}
cout<<x<<" "<<y<<" "<<z;

то результат быд 0 1 2

а так Х=1+1, тогда Y=x+1=3; z=x=2

Fata1ex
23.06.2009, 12:29
Верно :)

slesh
23.06.2009, 13:19
Fata1ex в моё случае экономия времяни идет раза в 2 потому как strlen - проходит и сравнивате каждый символ с нулем. Так что если юзать strlen то это двойной проход строки. Для доказательства всег овышеслудующего приведу ассемблерный код который созддает компилятор MS

случай

int a = 0;
char * k = str;
while (k[0])
{
a += k[0];
k++;
}


; int a = 0;
xor edx, edx
mov BYTE PTR _str$[esp+10], cl
mov WORD PTR _str$[esp+8], ax
; char * k = str;
lea ecx, DWORD PTR _str$[esp+8]
; while (k[0])
test al, al
je SHORT $LN1@main
$LL2@main:
; a += k[0];
movsx eax, al
; 24 : k++;
inc ecx
add edx, eax
mov al, BYTE PTR [ecx]
test al, al
jne SHORT $LL2@main
$LN1@main:


Итого 31 байт.


А теперь рассмотрим код в случае

int k=0,A=0,n=strlen(str);
for(k=0;k<n;k++)
A+=str[k];


выходит

00024 8d 44 24 10 lea eax, DWORD PTR _str$[esp+20]
00028 83 c4 04 add esp, 4
0002b 88 4c 24 0e mov BYTE PTR _str$[esp+18], cl
0002f 33 db xor ebx, ebx
00031 8d 50 01 lea edx, DWORD PTR [eax+1]
$LL11@main: /// <== вот это типа код strlen==========
00034 8a 08 mov cl, BYTE PTR [eax]
00036 40 inc eax
00037 84 c9 test cl, cl
00039 75 f9 jne SHORT $LL11@main
/// <=========================================
0003b 2b c2 sub eax, edx
0003d 8b d0 mov edx, eax

; 23 :
; 24 : for(k=0;k<n;k++)

0003f 33 c0 xor eax, eax
00041 83 fa 02 cmp edx, 2
00044 7c 20 jl SHORT $LC9@main
00046 8d 4a ff lea ecx, DWORD PTR [edx-1]
00049 55 push ebp
0004a 8d 9b 00 00 00
00 npad 6
$LL10@main:

; 25 : A+=str[k];

00050 0f be 6c 04 10 movsx ebp, BYTE PTR _str$[esp+eax+20]
00055 03 f5 add esi, ebp
00057 0f be 6c 04 11 movsx ebp, BYTE PTR _str$[esp+eax+21]
0005c 83 c0 02 add eax, 2
0005f 03 fd add edi, ebp
00061 3b c1 cmp eax, ecx
00063 7c eb jl SHORT $LL10@main
00065 5d pop ebp
$LC9@main:

; 23 :
; 24 : for(k=0;k<n;k++)

00066 3b c2 cmp eax, edx
00068 7d 05 jge SHORT $LN8@main

; 25 : A+=str[k];

0006a 0f be 5c 04 0c movsx ebx, BYTE PTR _str$[esp+eax+16]
$LN8@main:
0006f 03 fe add edi, esi


выходит 77 байт.
что выходит почти в 2,5 раза больше по коду и следовательно по скорости.

Из этого можно сказать что при работе со строковыми функциями лучше использоват собственные методы

Lee_fx
23.06.2009, 13:21
Как можно выполнить эффективное побайтовое сравнение структур, не используя прагмы компилятора и группировку членов?
memset, memcmp?

desTiny
23.06.2009, 14:31
что выходит почти в 2,5 раза больше по коду и следовательно по скорости.
следование неверно)
@here: mov ecx, 10;
loop @here;

вообще несколько байт) а time = \infty

Fata1ex
23.06.2009, 15:16
Lee_fx, подробнее )

Lee_fx
23.06.2009, 17:18
struct A {
int x;
char y;
};
int main() {
A a, b;
memset(&a, NULL, sizeof(a));
memset(&b, NULL, sizeof(b));
a.x = 10; a.y = 'q';
a.x = 10; a.y = 'q';

if(memcmp(&a, &b, sizeof(a)))
cout << "!=";
else
cout << "=";

return 0;
}

sizeof(a) и sizeof(b) - 12 байт, хотя int+char = 5 => остальные 7 занимает мусор, его и заNULLяем и сравниваем.

Fata1ex
23.06.2009, 17:22
Точно )
Нерешенные задачи: 2 9 10 13 14

slesh
23.06.2009, 22:18
Мне вот еще нравилась старая задачка одна, которая даже не зависела от языка программирования.
А Задачка такая:
Есть 2 числа
int a = 12;
int b = 7;

необходимо обменять значения между этими переменными при этом нельзя использовать третью переменную.
P.S. числа роли не играют.

[n]-c0der
23.06.2009, 22:34
Мне вот еще нравилась старая задачка одна, которая даже не зависела от языка программирования.
А Задачка такая:
Есть 2 числа
int a = 12;
int b = 7;

необходимо обменять значения между этими переменными при этом нельзя использовать третью переменную.
P.S. числа роли не играют.

ASM xchg...

Ну и собсна алгоритм:

a = a - b;
b = b + a;
a = b - a;

Реализация :):

procedure _XCHG(var a,b:integer);
Begin
a:= a - b;
b:=b + a;
a:=b - a;
End;

void _XCHG(int a, int b){
a = a - b;
b = b + a;
a = b - a;
};

slesh
24.06.2009, 09:31
Правильно.
Хотя красивее будет

void _XCHG(int a, int b)
{
a -= b;
b += a;
a = b - a;
};

desTiny
24.06.2009, 12:16
а над этими сложениями и вычитаниями правда ещё кто-то задумывается? кстати ещё хорошо бы по ссылке передавать аргументы
void _XCHG(int& a, int& b)
{
a ^= b;
b ^= a;
a ^= b;
};

Fata1ex
24.06.2009, 23:01
2 9 10 13 14
Каждое решенное задание это:
+1 mind (intelligence)
+1 carma
+1 experience
+5 reputation
work it!

Roston
24.06.2009, 23:39
а в 10 при обьявлении можно использовать [ и ]???

desTiny
24.06.2009, 23:43
нет, от тебя зачем-то(зачем?) хотят всяких maloc'ов и указателей

Ra$cal
24.06.2009, 23:48
согласен десятое задание по сути не очень хорошее. суть задания - сделать решение через жопу в стиле асма, с арифметикой указателей и разыменовывниями. не очень понимаю смысл

Roston
24.06.2009, 23:56
нет, от тебя зачем-то(зачем?) хотят всяких maloc'ов и указателей
совсем не понял твоего поста

slesh
25.06.2009, 00:55
эх.. чтото все заглохли с 10м заданием. Так уж и быть покажу сам )
Я сделал по хитрее. у меня так называемый массив состоит не из 8 битных элементов(байт), а из 32-х битный (ulong) что дает его спокойно юзать даже при значение N = 20

#define N 10
int main(int argc, char* argv[])
{
char * mas = (char*)malloc(N*N*4);
char * tmp = mas;
int x;
for (x = 1; x < N*N+1; x++, tmp += 4)
{
*(unsigned long *)tmp = x;
}
tmp = mas;
for (x = 1; x < N*N+1; x++, tmp += 4)
{
printf("%i\t",*(unsigned long*) tmp);
if (x % N == 0) printf("\n");
}
return 0;
}

desTiny
25.06.2009, 01:09
Я сделал по хитрее
м? а в чём хитрость и хитрее чего?)

Ra$cal
25.06.2009, 01:44
видимо задача была перехитрить себя, чтобы потом ломать голову над кодом =)

Fata1ex
25.06.2009, 02:47
Насчет 10-ой задачи:
цель этих заданий, по-моему, состоит в том, чтобы показать решающим нечто, чего они раньше не видели, о чем не задумывались и что, возможно (!=точно), поможет им в дальнейшем.

Ай-ай! Я перепутал 10 и 14 задания ) Сорри

const int N = 3;
int** buf = new int*;
int z = 0;

for (int i=0; i<N; i++) {
*(buf + i) = new int;
for (int k=0; k<N; k++) {
*(*(buf + i) + k) = z++;
std::cout << *(*(buf + i) + k) << std::endl;
}
}

Ra$cal
25.06.2009, 03:13
ну хзхз. тут не вижу ничего интересного. все итак очевидно - юзать сишный способ работы с памятью + арифметика указателей. это как раз то, что должен обходить за километр программист на с++.

Fata1ex
25.06.2009, 03:20
[C/C++] ЗАДАНИЯ
Я не очень верно выразился: чтобы показать решающим нечто, чего они, по-моему, раньше не видели, о чем не задумывались и что, возможно (!=точно), поможет им в дальнейшем.

slesh
25.06.2009, 10:24
Кстати, чтото пока никто не решил мою задачку с обработкой исключений

desTiny
25.06.2009, 11:39
Кстати, чтото пока никто не решил мою задачку с обработкой исключений
а одна строчка "VEH" тебя устроит?) //add: кстати, ты ведь не хотел застаить людей хучить KiUserExceptionDispatcher?
просто все чего-нть интересного ждут - вдруг появится?

кстати - скопипастю задачку из того, что я зачем-то в задания по пхп кинул:
что будет в переменной после выполнения кода (не компилить!)

/*very very long not ever overflowable*/ int a = 5+765432l;

slesh
25.06.2009, 12:51
2 desTiny вообще это решается без ассемблера и без разного рода ядерных функций.
Чисто только API функции (даже одна функция)

slesh
25.06.2009, 13:07
т.к. судя по всему мало кто это использует или комуто неинтерестно это придется рассказать самому )
Есть такая апишка - SetUnhandledExceptionFilter. Через неё можно устанавливать собственный обработчик исключений для процесса.
Т.е. даже если ошибка произошла в каком либо потоке приложения, то всё равно будет вызван этот обработчик. Дригими словами это типа try except но в глобальном масштабе всего приложения. Вообще эта функция какбы заменяет обработчик ошибок который есть в винде (который показывает сообщение что прога выполнила некорректрую операцию итд).

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

// наш фильтр
LONG MyExceptHandle(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
char buf[256];
GetModuleFileNameA(0,buf,256); // получим имя нашей проги
printf("ERROR\n");
WinExec(buf,SW_SHOW); // запустим заново её
ExitProcess(0); // завершим процесс
return 0;
}

int main(int argc, char* argv[])
{
printf("SRART\n");
// ставим свой фильтр исключений
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION _FILTER)&MyExceptHandle);
__asm
{
hlt // делаем ошибку
}
return 0;
}


Хоть перезапуск лучше делать с следящем процесс.
Лично я иногда использую слудующего рода конструкцию


LONG MyExceptHandle(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
SYSTEMTIME lt;
char NAME[512];

GetModuleFileNameA(0, NAME, 512); // получим имя нашей проги
GetLocalTime(&lt); // получим системное время
sprintf(NAME, "%s_%i-%i-%i_%i-%i-%i.dmp", NAME, lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);

ExInfo.ThreadId = GetCurrentThreadId(); // зададим ID потока
ExInfo.ExceptionPointers = pExceptionInfo; // зададим исключение
ExInfo.ClientPointers = 0;
// создадим файл для дампа
HANDLE hFile = CreateFileA(NAME, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL );
// скинем дамп в файл
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile,MiniDumpNormal,&ExInfo,0,0);
// закроем файл
CloseHandle(hFile);
// завершим процес с кодом появившейся ошибки
ExitProcess(pExceptionInfo->ExceptionRecord->ExceptionCode);
return 0;
}


В этоге при ошибке в прогамме, в папке с прогой появится файл
имяпроги_дата_время.dmp в котором будет содержаться дамп программы на момент ошибки.
Далее этот файл можно свободно подгрузить в отладчик или даже в VC++ 2008 открыть и подробно изучить причину ошибки (при наличии исходников вообще можно видеть строку где произошла ошибка итд итп) Очень удобная вешь для отладки больших проектов.

slesh
25.06.2009, 13:12
2 desTiny какой пакостник, людей дурить нехорошо. Ониже голову сломают без капса )

Fata1ex
25.06.2009, 13:24
Обновил задания ) Обновил решение 10 задания ( теперь это решение 10 задания, а не другого (: ).

2 13 14 16

desTiny
25.06.2009, 19:21
slesh, SetUnhandledExceptionFilter делает не то, что ты просил. он добавит обработчик в самый низ, а ты, как я понял, просил добавить его наверх. И, к тому же, твой код трёт уже установленный exceptionfilter.
а
LONG NTAPI VEHproc(PEXCEPTION_POINTERS param){
printf("error!!");
return EXCEPTION_CONTINUE_EXECUTION;
}
...
AddVectoredExceptionHandler(1, VEHProc);
...
должен вполне нормально справляться со всем.

Gar|k
25.06.2009, 21:18
задание 14

char data[]={1,2,3,4,5,6};
char *mas=&data[2]; // массив начинающийся с произвольного числа ))

Fata1ex
25.06.2009, 21:23
Нене, это фэйк ))

desTiny
25.06.2009, 22:18
ну блин, ведь уже написали даже - неужели трудно переписать
int a[100];
a-=10;

desTiny
25.06.2009, 23:56
задание 13:
так и не понял, в чём суть

char str[100], very_long_string[] = "helllllllllooolllloollollooll";

for (int i=0; i<10000000; i++)
strcpy(str, "bytes "); strcat(str, very_long_string);

работает 5512мс, а с ":" 5544мс. Так что, если разница и есть, то только в памяти, но понятия не имею, с чего бы.

Fata1ex
26.06.2009, 02:32
2 desTiny
Наиболее эффективно обрабатываются строки, начинающиеся с адреса, кратного четырем. Именно так компилятор размещает их в стеке и статической памяти. отсюда функция strlen(s) выполняются эффективно, а вот strlen(s+1) — не очень. Тоже самое относится и ко всем остальным функциям. Поэтому, всегда стремитесь выравнивать строки, когда это только возможно. Скажем, "strcpy(s, "bytes "); strcat(s, very_long_string);" выполняется неэффективно, но если переписать код так: "strcpy(s, "bytes: "); strcat(s, very_long_string);", то скорость его выполнения значительно возрастет, за счет того, что адрес конца строки s станет кратен 4 байтам.

Ra$cal
26.06.2009, 02:46
очень спорно. некоторые компиляторы делают оптимизированное копирование числа байтов, кратных четырем, а остаток спокойно ифом и выбором из 3х условий - длина = 1, 2, 3. Все очень сильно зависит от компилятора и его настроек. Вот мсный компиль практически всегда дает while(*dst++ = *src++) и ему глубоко чихать на выравнивание =)

Fata1ex
26.06.2009, 18:39
2 16
Всем желающим написать задание писать мне в ПМ или прямо сюда.

desTiny
26.06.2009, 20:24
2 desTiny
по-моему 30 миллисекунд за +миллион символов (вроде в дизасме без всяких доп. выравниваний) - это по-моему достаточно, чтобы оспорить это утверждение:)
и к тому же в первом случае (если обозначить адрес начала за 0) конец на позиции 6, а во втором 7 - то есть тут вроде нет никакого выравнивания. Но если даже добавить ещё один символ - получаем 5614мс - и никакого выигрыша.

Busted :)

Fata1ex
26.06.2009, 21:32
desTiny, наверно, как и сказал Ra$cal, все зависит от реализации )
Busted :)
:(

desTiny
28.06.2009, 21:46
#16 будем считать, что слеш написал решение)
утверждение l != 1 - там в один пиксель разница:) Поэтому a=765437

Roston
06.07.2009, 10:50
чё больше не будет заданий?

Ch3ck
06.07.2009, 12:01
Не помню где нашёл... было сохранено в txt файле:
Что выведет данная программа?(Не hello, world точно...)

/*
* HELLO WORLD program
* by Jack Applin and Robert Heckendorn, 1985
*/
main(v,c)char**c;{for(v[c++]="Hello, world!\n)";
(!!c)[*c]&&(v--||--c&&execlp(*c,*c,c[!!c]+!!c,!c));
**c=!c)write(!!*c,*c,!!**c);}

P.S Tckb не в тему удалите пост...

Fata1ex
06.07.2009, 14:10
Roston, тема к сожалению не пользуется большой популярностью ( поэтому и нет.
Ch3ck, это ацкей изврат :(

Balvan
08.07.2009, 18:54
Я постоянно эту темку читаю) вот тока у самого опыта маловато => интересных задачек нет. =\

Fata1ex
08.07.2009, 19:07
Я думаю, что, наверное, можно постить сюда не только интересные задания, но и просто обычные задания, так как не у всех есть желание и возможность покупать и читать практикумы и задачники. Как вам такая идея? Например, задание написать парсер небольшой или создать эффективную функцию? Если есть предложения по развитию треда вы пишите: все пожелания учитываются, а то тема увядает, так как никакой инициативы со стороны нет :(

fker
08.07.2009, 23:19
Задачка не сложная, для начинающих типа Balvan-а . (циклы и масиивы)

1.
Ввести число n и заполнить 2мерный массив размеров n*n числами 1,2,3 по спирали.
Например n=4

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7

Balvan
09.07.2009, 10:40
fker Спасибо! =D


int SpiralArray (int n)
{
int k = 1;
int j;
int m;
for (int i=1; i==n; i++) {
if (i%2<>0 and j<=n)
for (j=m; j==1; i--){
int a[i][j]=k++;};
else for (j=1; j==n; j++) {
int[i][j]=k++
};
for (i=1;i==n;i++) {
for (j=1;j==n;j++){
cout << a[i][j] << " ";
}
}
}
return 0;
}

fker
09.07.2009, 12:11
Удивительно... а как это может скомпилироваться? %)

Fata1ex
09.07.2009, 12:48
2 17 18

Balvan
09.07.2009, 13:25
ой =)

fker
09.07.2009, 13:27
Задание 18.

Привести два эффективных варианта выхода из большого количества вложенных циклов без использования операторов break.
1. использовать метки и оператор goto

2. создать переменную-флаг и проверять в каждом цикле не равна ли она значению, для выхода из цикла

например:

int flag=0;
for(i=z; i<n && flag!=1; i++){
blabla;
for( ; df!=n && flag!=1;)
if(что то)
flag=1;
}
}

Fata1ex
09.07.2009, 13:31
Ладно :)
Есть третий вариант.

\\ChaOs//
09.07.2009, 13:31
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7

#include <iostream>
#include <fstream>
using namespace std;

void Array(int num)
{
int **arr,i=0,j=0,n=1,d=1;
arr=new int*[num];
for(int a=0;a<num;a++)
arr[a]=new int[num];

while(d!=((num/2)+1))
{
for(;i<(num-d);i++,n++)
{
arr[i][j]=n;
}
for(;j<(num-d);j++,n++)
{
arr[i][j]=n;
}
for(;i!=(-1+d);i--,n++)
{
arr[i][j]=n;
}
for(;j!=d;j--,n++)
{
arr[i][j]=n;
}
d++;
if(d==(num/2+1))
{
arr[i][j]=n;
if(num & 1)
{
i++;
n++;
arr[i][j]=n;
}
}
}
char name[80];
up:
cout<<"Вывод в файл. Введите имя\n";
cin>>name;

ofstream file(name);
if(!file) goto up;
for(int a=0;a<num;a++)
{
for(int b=0;b<num;b++)
{
file<<arr[b][a]<<"\t";
}
file<<endl;
}
delete arr;
}


int _tmain()
{
setlocale(0,".1251");
int n;
begin:
cout<<"Введите размерность массива n*n"<<endl;
try{
cin>>n;

Array(n);
}
catch(...){cin.clear(); _flushall();cout<<"Ошибко!!! ):\n"; goto begin;}
system("pause");
return 0;
}

Fata1ex
09.07.2009, 13:33
\\ChaOs//, размерность нужно ввести, а не задать изначально.

bons
09.07.2009, 14:13
мой вариант про спираль на поцкале:
program spiral;

const n = 5;
type matrix = array of array of cardinal;

//----------------------------------------------------------------------
procedure fill_spiral(var m : matrix; n : cardinal);
var i, num_circle, start: integer;
begin
start := 1;
for num_circle := 0 to n div 2 -1 do begin
for i := num_circle to n - num_circle - 1 do begin
m[num_circle, i] := start + i;
m[n - num_circle - 1, n - i - 1] := 2 * n - num_circle * 4 - 2 + start + i;
end;
for i := num_circle + 1 to n - num_circle - 2 do begin
m[i, n - num_circle - 1] := start + n - num_circle * 2 + i - 1;
m[n - i - 1, num_circle] := start + 3 * n - num_circle * 6 - 3 + i;
end;
start := start + 4 * n - num_circle * 7 - 5;
end;
if n mod 2 <> 0 then m[n div 2, n div 2] := start + 1;
end;

//----------------------------------------------------------------------
var i, j: integer;
s: matrix;
BEGIN
SetLength(s, n, n);
fill_spiral(s, n);
for i := 0 to n - 1 do begin
for j := 0 to n - 1 do
write(s[i, j] : 4, ' ');
writeln;
end;
END.

Fata1ex
09.07.2009, 14:28
bons, это, конечно, замечательно, что ты знаешь паскаль, но, к сожалению, тема называется [C/C++] ЗАДАНИЯ :(
Тем более, что решение все равно не верное. Повторяю: размерность нужно ввести с клавиатуры!

fker
09.07.2009, 14:30
\\ChaOs//
решение верно
моё

#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int n;
int **a;
int v,g,j,i=1;
printf("BBegu n -> ");
scanf("%d",&n);
a=new int*[n];
for(v=0; v<n; v++)
a[v]=new int[n];
g=n/2+1;
for(v=1; v<=g; v++){
for(j=v-1; j<n-v+1; a[v-1][j]=i++, j++);
for(j=v; j<n-v+1; a[j][n-v]=i++, j++);
for(j=n-v-1; j>=v-1; a[n-v][j]=i++, --j);
for(j=n-v-1; j>=v; a[j][v-1]=i++, --j);
}
for(i=0; i<n; i++){
for(j=0; j<n; j++)
printf("%3d",a[i][j]);
printf("\n\n");
}
getch();
}

\\fixed =)

Fata1ex
09.07.2009, 14:34
fker, омг, а если число будет больше 100? Это детский сад, а не решение ) Или уже делать размерность константой изначально или вводить с клавиатуры и использовать динамический массив или векторы.

bons
09.07.2009, 14:48
bons, это, конечно, замечательно, что ты знаешь паскаль, но, к сожалению, тема называется [C/C++] ЗАДАНИЯ :(
Тем более, что решение все равно не верное. Повторяю: размерность нужно ввести с клавиатуры!
и правда, не заметил )) ну и пусть, алгоритм все равно верный хоть и не лаконичный

\\ChaOs//
09.07.2009, 14:51
моё(со статич массивом)


Если n - нечетное, то массив заполнится не до конца

Fata1ex
09.07.2009, 14:55
\\ChaOs//, верное решение, молодец :)

2 18
в задании 18 осталось указать еще один вариант решения

fker
09.07.2009, 15:03
Если n - нечетное, то массив заполнится не до конца
тоже верно, не учел..
вопросик возник:
можно ли с помощью cout<< делать форматный вывод, типа printf("%3d",a) ?

\\ChaOs//
09.07.2009, 15:05
2 18
в задании 18 осталось указать еще один вариант решения

Если действия выполняются в функции, то можно просто возвратить значение

Пример:
int Func()
{
while(true)
{
...//Что-то
if(что-то==чему-то)
return что-то;
}
}

Fata1ex
09.07.2009, 15:09
А если нам нужно продолжить выполнение функции после выхода из циклов? Не пойдет.
вопросик возник:
можно ли с помощью cout<< делать форматный вывод, типа printf("%3d",a) ?
Для таких вопросов существует отдельная тема.

\\ChaOs//
09.07.2009, 15:14
А если нам нужно продолжить выполнение функции после выхода из циклов? Не пойдет.

Ну тогда можно сгенерировать исключение.

Fata1ex
09.07.2009, 15:22
дадада

Fata1ex
11.07.2009, 06:43
Объясните мне, почему никто не делает задание 2? ))

jawbreaker
25.08.2009, 20:24
Задание 2.

Мы создаем класс без конструкторов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор без аргументов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор копии. Что сгенерирует компилятор дополнительно?

Если вы написали

class Empty {};


то, знайте, что на самом деле вы создали примерно вот такой класс:

class Empty {
public:
// Конструктор без параметров
Empty();
// Копирующий конструктор
Empty(const Empty &);
// Деструктор
~Empty();
// Оператор присвоения
Empty& operator=(const Empty &);
// Оператор получения адреса
Empty * operator&();
// Оператор получения адреса константного объекта
const Empty * operator&() const;
};
ну и дальше понятно

pantur
27.08.2009, 13:59
Отличный раздел, только вот неплохо было бы не использовать WinAPI. Или, как минимум, делать задания и с POSIX-функциями.

Хм, почему задание 6 такое лёгкое сделали, там же gcc ругается при -Wall, даже думать не надо?

P.S.: да, предлагаю задачку (на чистом C!) - как за любое кол-во проходов определить, что мы находимся в кольцевом списке? Список односвязный. Если честно, я и сам хреново представляю, как это сделать, задачу предложил мой гуру :)

P.P.S.: пожалуйста, добавьте ещё заданий, а то я, как человек корыстный и решивший получить репутацию и похвалиться своими знаниями, был неприятно удивлён тем, что все задания на сях уже решены...

desTiny
11.06.2010, 16:06
Вот ещё попалось. Найти ошибку в коде, который должен прочитать число из файла как 4 байта по смещению 0x123:

FILE *f;
fopen_s(&f, szFileName, "r+");
if (f){
int offset = 0x123;
fseek(f, offset, SEEK_SET);
int num;
fread(&num, 4, 1, f);
printf("%d\n", num);
fclose(f);
}


P.S.: да, предлагаю задачку (на чистом C!) - как за любое кол-во проходов определить, что мы находимся в кольцевом списке? Список односвязный. Если честно, я и сам хреново представляю, как это сделать, задачу предложил мой гуру
Известная задачка - запускаем 2 указатаеля, один будет просматривать все записи подряд, второй - через одну. Если они когда-то совпадут, то зациклились, если пройдём до конца и не совпадут, то не зациклились. Работает за O(размер списка) времени и O(1) памяти

Irdis
12.06.2010, 02:37
Интересную задачу недавно встретил.
с++
Напечатать кол-во * при типе.
т.е.
int*** <=> 3
char***** <=> 5
Чем оптимальней тем лучше =)