Помогите с задачей

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
centnew
Сообщения: 4
Зарегистрирован: 22 июл 2009, 19:48

Нужно написать программу, которая будет возводить в степень больше 20ой и числа большего max_int, проблема состоит в том что, входящее число может быть разное и я не могу заранее создать массив подходящий для результата, знаю что это как-то делается в куче, но как не знаю подскажите пожалуйста!!!
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Код: Выделить всё

int size = rand() % 500;

// Allocating new array in the heap
int* p = new int [size];

// Here we work with p as with ordinal array
for (int i = 0; i < size; ++i)
{
   p[i] = i;
}

// Don't forget to free the memory
delete [] p;
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Ну и толку в этом коде ?
for (int i = 0; i < size; ++i)
{
p[i] = i;
}
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Это был ответ на вопрос:
&quot писал(а):я не могу заранее создать массив подходящий для результата, знаю что это как-то делается в куче, но как не знаю подскажите пожалуйста
Пример демонстрирует как работать c кучей.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
centnew
Сообщения: 4
Зарегистрирован: 22 июл 2009, 19:48

Бальшое спасибо, буду переделовать, но ещё маленькая просьба немогли бы ктонибудь протестить эту прогу? :)

Код: Выделить всё

/* Задача: Составить программу для вычисления степеней чисел вида  an, если  a > MaxInt,  n > 10. */

#include <iostream>
#include <conio.h>

#define int_max 10000
void perevorot(int mas[], int x)
{
	int tmp,i,j;
	j=x;
	for(i=0;i<j;i++){
		j--;
		tmp=mas[j];
		mas[j]=mas[i];
		mas[i]=tmp;
	}
}
int addsum(int outmas[],int x,int mas[], int z)
{
	perevorot(mas,z);
	perevorot(outmas,x);
	int overbit=0,i=0,j;
	j=z;
	j--;
	while(i<j){
		outmas[i]+=mas[i];
		outmas[i]+=overbit;
		if (outmas[i]>9) {
			outmas[i]-=10;
			overbit=1;
		} else overbit=0;
        i++;
	}
	outmas[i]+=mas[i];
	outmas[i]+=overbit;
	if (outmas[i]>9){
		outmas[i]-=10;
		i++;
		outmas[i]+=1;
	}
	i++;
	perevorot(outmas,i);
	perevorot(mas,z);
	return i;
}

int umnoj(int outmas[],int x,int tmas1[], int z1, int tmas2[], int z2)
{   
	int i,q=0;
	for(i=0;i<int_max;i++) outmas[i]=0;
	int mas1[int_max],mas2[int_max];
	for(i=0;i<int_max;i++) mas1[i]=mas2[i]=0;
	for(i=0;i<int_max;i++) {
		mas1[i]=tmas1[i];
		mas2[i]=tmas2[i];
	}
	perevorot(mas1,z1);
	perevorot(mas2,z2);
	int j=0,st=0,razryad=0,nommas=0;
	int tmp[int_max];
	for(i=0;i<int_max;i++) tmp[i]=0;
	for(razryad=0;razryad<z2;razryad++){
			nommas=razryad;
		for(j=0;j<z1;j++){
						//перебор
			tmp[nommas]+=(mas1[j]*mas2[razryad])%10;
			nommas++;
			tmp[nommas]+=(mas1[j]*mas2[razryad])/10;

		}
		if ((mas1[j]*mas2[razryad])>9||z1==1) nommas++;
		perevorot(tmp,nommas);
		q=addsum(outmas,q,tmp,nommas);
		for(st=0;st<int_max;st++)
			tmp[st]=0;
	}
	return q;
}
int stepen(int outmas[],int n,int inmas[], int x,int st)
{	
	int i,j;
	if(st==0) {
		for(i=0;i<int_max;i++) outmas[i]=0;
		outmas[0]=1;
		return 1;
	}else if(st==1){
		for(i=0;i<int_max;i++) outmas[i]=inmas[i];
		return x;
	}
	int a[int_max];
	n=umnoj(outmas,n,inmas,x,inmas,x);
	for(i=3;i<=st;i++){
		for(j=0;j<int_max;j++) a[j]=outmas[j];
		n=umnoj(outmas,n,a,n,inmas,x);
	}
	return n;
}
int vvodchisla(int mas[])
{
	using namespace std;
	char c=0;
	int i,top=0;
	for(i=0;i<int_max;i++) mas[i]=0;
	while (c!=13){
		c=getch();
		if(c<='9'&&c>='0') {
			if(top==int_max){
				cout << "bolshe nelza!" << endl;
				continue;
			}
			cout << c;
			mas[top]=c-'0';
			top++;
		}
		if(c=='\b'){
			cout << '\b' << ' ' << '\b';
			top--;
		}
	}
	return top;
}
void main()
{
	using namespace std;
	int indigit[int_max];
	int outdigit[int_max];
	int i,n=0,top=0,st;
	cout << "vvedite chislo \n";
	top=vvodchisla(indigit);
	cout << "\nv kakuye stepen vozvodim?\n";
	cin >> st;
	cout << "\n+++++++++++\n";
	n=stepen(outdigit,n,indigit,top,st);
	for(i=0;i<n;i++)
		cout << outdigit[i];
	getch();
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Очень необычная просьба. Первый раз такую просьбу вижу на форуме программистов :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
centnew
Сообщения: 4
Зарегистрирован: 22 июл 2009, 19:48

Вопрос меняется!!!
Нужне не создание динамического массива, а управление размером динамического массива, Romeo а можно пример с управлением размера массива?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В С++ нет стандартного механизма для переаллокации (изменения размера) памяти, которая была выделена ранее. Поэтому для переаллокации использует комбинированный подход - выделение нового участка нужного размера, копирование, удаление старого. Например так:

Код: Выделить всё

int size = rand() % 500;
int* p = new int [size];

// Here we work with p
...

// Let's image situation that we need to reallocate memory
// Function GetNewSize is our one and it returns new needed memory size

int new_size = GetNewSize();
int min_size = size < new_size ? size : new_size;

// Allocate new memory segment
int* new_p = new int [new_size];
// Initialize it with zeros
memset(new_p, 0, new_size * sizeof(int));
// Copy old data to new memory segment
// If new segment is less then old - tail data will be ignored
memcpy(new_p, p, min_size);

// Deleting old memory segment
delete [] p;
// Now p points to the new segment of new required size
p = new_p;

// Here we work with p
// ...

// Dont forget to free new memory segment
delete [] p;

Помимо стандартных стредств С++, у нас есть некоторые другие возможности для реаллокации памяти:

1. Как ни странно, язык С, прародителе С++, имеется функцию для реаллокации памяти. Один из вариантов - использовать malloc и free вместо new и delete. В этом случае тебе будет доступна С функция realloc. Однако будь осторожен - старые С функции для работы с динамической памятью не вызывают конструкторы и деструкторы объектов. Если ты не работаешь с объектами классов, то это, к счастью, тебя не касается.

2. Можно использовать функции Windows для работы с динамической памятью, но для этого, конечно же, понадобится Windows компилятор. Если этот вариант тебе подходит, то используй LocalAlloc, LocalReAlloc, LocalFree.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Vasilisk
Сообщения: 116
Зарегистрирован: 13 фев 2004, 18:43

Если вся работа с большим числом происходит в пределах одной процедуры (одного стекового фрейма), то есть такая функция alloca (или _alloca - она на всех платформах есть, только везде по-разному называется). Эта функция выделяет память в стеке. Т.е. "делает автоматическую переменную" указанного размера. после выхода из процедуры стек, разумеется, очищается самопроизвольно.

Эффективность функции - одна-две команды процессора, это куда лучше malloc

Впрочем, того же самого можно добиться просто объявив массив с переменной, а не константой, под скобками: int sz = что-то там; char arr[sz];
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

&quot писал(а):просто объявив массив с переменной, а не константой, под скобками
Если мне не изменяет память, то текущая версия стандарта С++ не позволяет этого делать - в скобках допускается только rvalue.

Да, некоторые нестандартные компиляторы делают отступление и разрешают это, да и проблем с ассемблерной реализацией подобного подхода тоже нет (sub esp, [var]; mov [p], esp), тем не менее стандарт строг в этом отношении. Почему так - это уже другой вопрос. Ответ на него я не знаю.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить