Страница 1 из 1
Помогите с задачей
Добавлено: 22 июл 2009, 19:59
centnew
Нужно написать программу, которая будет возводить в степень больше 20ой и числа большего max_int, проблема состоит в том что, входящее число может быть разное и я не могу заранее создать массив подходящий для результата, знаю что это как-то делается в куче, но как не знаю подскажите пожалуйста!!!
Re: Помогите с задачей
Добавлено: 26 июл 2009, 10:03
Romeo
Код: Выделить всё
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;
Re: Помогите с задачей
Добавлено: 26 июл 2009, 16:42
Airhand
Ну и толку в этом коде ?
for (int i = 0; i < size; ++i)
{
p[i] = i;
}
Re: Помогите с задачей
Добавлено: 26 июл 2009, 18:28
Romeo
Это был ответ на вопрос:
" писал(а):я не могу заранее создать массив подходящий для результата, знаю что это как-то делается в куче, но как не знаю подскажите пожалуйста
Пример демонстрирует как работать c кучей.
Re: Помогите с задачей
Добавлено: 27 июл 2009, 15:46
centnew
Бальшое спасибо, буду переделовать, но ещё маленькая просьба немогли бы ктонибудь протестить эту прогу?
Код: Выделить всё
/* Задача: Составить программу для вычисления степеней чисел вида 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();
}
Re: Помогите с задачей
Добавлено: 27 июл 2009, 16:29
Romeo
Очень необычная просьба. Первый раз такую просьбу вижу на форуме программистов

Re: Помогите с задачей
Добавлено: 27 июл 2009, 17:29
centnew
Вопрос меняется!!!
Нужне не создание динамического массива, а управление размером динамического массива, Romeo а можно пример с управлением размера массива?
Re: Помогите с задачей
Добавлено: 28 июл 2009, 11:52
Romeo
В С++ нет стандартного механизма для переаллокации (изменения размера) памяти, которая была выделена ранее. Поэтому для переаллокации использует комбинированный подход - выделение нового участка нужного размера, копирование, удаление старого. Например так:
Код: Выделить всё
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.
Re: Помогите с задачей
Добавлено: 01 авг 2009, 00:52
Vasilisk
Если вся работа с большим числом происходит в пределах одной процедуры (одного стекового фрейма), то есть такая функция alloca (или _alloca - она на всех платформах есть, только везде по-разному называется). Эта функция выделяет память в стеке. Т.е. "делает автоматическую переменную" указанного размера. после выхода из процедуры стек, разумеется, очищается самопроизвольно.
Эффективность функции - одна-две команды процессора, это куда лучше malloc
Впрочем, того же самого можно добиться просто объявив массив с переменной, а не константой, под скобками: int sz = что-то там; char arr[sz];
Re: Помогите с задачей
Добавлено: 02 авг 2009, 21:24
Romeo
" писал(а):просто объявив массив с переменной, а не константой, под скобками
Если мне не изменяет память, то текущая версия стандарта С++ не позволяет этого делать - в скобках допускается только rvalue.
Да, некоторые нестандартные компиляторы делают отступление и разрешают это, да и проблем с ассемблерной реализацией подобного подхода тоже нет (sub esp, [var]; mov [p], esp), тем не менее стандарт строг в этом отношении. Почему так - это уже другой вопрос. Ответ на него я не знаю.