PDA

Показать полную графическую версию : Как выяснить размер числового массива?


mrcnn
14-12-2008, 13:10
Тип int

Ограничения:
1. Не используя глобальных переменных.
2. Вернуть из функции размер нельзя, т.к возвращается указатель на массив

Память под массив выделена динамически внутри функции.
Как выяснить размер массива за пределами функции?

И еще один вопрос: как грамотно добавить еще один элемент в конец массива, сохранив все предыдущие. Я копирую, возможно ли это сделать эффективнее?

int* sum(int* n1,int sz1,int* n2,int sz2)
{
int* result;
int cnt_of_result;
int sz_of_result = max(sz1,sz2);
int tmp,vu,i,mn,cmp;

result = new int[sz_of_result];
cnt_of_result = 0;
vu = 0;
mn=min(sz1,sz2);
cmp=compare(n1,sz1,n2,sz2);

for (i=0;i < sz_of_result;i++)
{
if (i < mn)
tmp = n1[i]+n2[i]+vu;
else
{
if (cmp==1)
tmp = n1[i]+vu;
else if (cmp==2)
tmp = n2[i]+vu;
}
if(tmp>=1000)
{
tmp-=1000;
vu = 1;
}
else
vu = 0;
result[cnt_of_result]=tmp;
cnt_of_result++;
}

if (vu != 0)
{

int* cp;
cp = new int[sz_of_result+1];
for (i=0;i<sz_of_result;i++)
cp[i]=result[i];
cp[cnt_of_result]=vu;
print(cp,sz_of_result+1);
return(cp);
}

print(result,sz_of_result);
return (result);
}

Busla
14-12-2008, 15:14
точно так же как и внутри функции: int sz_of_result = max(sz1,sz2); :-)
Это называется "ошибка проектирования" - похоже, нужно переписывать не отдельную функцию, а всю программу.

mrcnn
14-12-2008, 15:37
max(sz1,sz2) это не функция, а макрос, кстати.

Вспомнил, как находить размер.
arr_sz=sizeof(x)/sizeof(x[0]);
Хотя похоже с динамическими массивами это не работает.
Вопрос по прежнему остался.
Как определить размер динамического массива и не вылететь за его пределы?

Размер массива будет известен только после обработки данных функцией, до этого узнать его нельзя. Изначально даже самой функции вообще неизвестно, сколько элементов будет в массиве, и в целях экономии ресурсов, чтобы не копировать постоянно один массив в другой с увеличением размера, я устанавливаю минимально возможный (имею право, так как по условию задачи числа положительные). Если были бы отрицательные, то только копирование одного массива в другой. Так же как внутри функции устанавливается размер, вне этой функции использовать нельзя. Запускать два раза обработку, чтобы узнать размер и получить указатель нельзя. Нет никаких ошибок в проектировании.

Busla
14-12-2008, 17:40
mrcnn, если ошибок в проектировании нет, то и вопросов возникать возникать не должно о представлении данных внутри программы ;)

А вы даже не знаете, где в вашей программе размер массива ;)

mrcnn
14-12-2008, 18:59
Busla, Умный, да?

- Взвод идет грузить люминий!
- Не люминий, а алюминий, товарищ прапорщик! .
- Взвод идет грузить люминий! А самый умный идет грузить чугуний!

Пофиг. Буду передавать через глобальную переменную. Мне не жалко.
Класс я организовывать не буду и не хочу.

Alan85
14-12-2008, 20:28
Предлагаю использовать нулевую ячейку массива для хранения длины . Как string в старом паскале

Busla
14-12-2008, 20:30
Класс я организовывать не буду и не хочу. » не обязательно переходить на объектную парадигму: можно возвращать не массив, а структуру с массивом, его размером, и коэффициентом заполнения. А вообще, в C++ разумнее не изобретать велосипед с динамическими массивами, а использовать готовые контейнеры стандартной библиотеки, в частности векторы.

mrcnn
15-12-2008, 09:13
Я недостаточно знаю структуры и классы, поэтому будут постоянно ошибки. У меня больше времени уйдет на разбор языка и на борьбу с ошибками, чем на написание программы и на разработку алгоритма. А программу сдать надо завтра и времени переписывать готовое нет..

Я мог бы вообще не писать эту программу, а найти и скачать готовый класс, но я не хочу. И Я БУДУ всегда изобретать новый велосипед и разбираться с деталями, лежащим в основе велосипеда. Без всяких vector, list и т.д STL. Нужно изобретать велосипеды, чтобы не сидеть в говне. Чтобы не покупать велосипеды в магазине за 20 тысяч рублей. Чтобы экономить. Чтобы он был более функциональным, удобным и красивым. И понятным для меня лично. Нужно изобретать велосипеды.

pva
15-12-2008, 10:14
Я недостаточно знаю структуры и классы, поэтому будут постоянно ошибки. У меня больше времени уйдет на разбор языка и на борьбу с ошибками, чем на написание программы и на разработку алгоритма. А программу сдать надо завтра и времени переписывать готовое нет.. »
А зря! месяц помучаешься, потом за уши не оттянешь!
Ну если очень не хочется, есть ещё способ:

int* calculate(int* arg1, int size1, int* rag2, int size2, int* return_size=0)
{
...
if (return_size) *return_size = size3;
return ...
}

Devils0411
19-12-2008, 09:51
Извините за оффтоп. Время поджимает. Есть задача.
Задается размер массива в ручную (например 7), нужно найти к-ый минимум (например нужно найти 3 минимум) и вывестина экран изначальный массив и этот минимум. Как мне обьяснил препод (и если я его правильно понял), то выглядить это должно примерно так:
Программа запрашивает у пользователя в вести размер массива (ввод размера массива в ручную например 7)
Далее программа запрашивает, указать какой минимум он хочет найти: (например 3)
После этого программа просит ввести массив в ручную (6 2 7 1 8 5 9)
И в конце программа должна вывести на экран сам массив и к-ый минимум.
Как мне обьяснил препод, программа должна найти первый минимум по отношению ко всему массиву в данном случае это 1, затем второй минимум - 2, потом 3 минимум - 5.
Как я понял, то это должно выглядить так: программа находит первый минимум - 1, потом найти следующий минимум и сравнивать его с массивом, но не учитывать первый минимум.

P.S. В С++ я не селен, понимаю, но реализовать не могу. Помогите пожайлуста. В понедельник сдавать!
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
main()
{
int n, i, k, m;
cout<<"Vvedite kolichestvo chisel v massive"<<endl;
cin>>n;
int A[10];
cout<<"Vvedite, kakoj po schetu minimum nado najti"<<endl;
cin>>m;
int min, c;
for (i=0; i<n; i++)
{
cout << "Vvod massiva: ";
cin >> A[i];
if (A[i]<min) min=A[i];
}
cout<<endl;
c=1;
min = A[0];
for (i=0; i<n; i++)
{
if (A[i]>min) { min = A[i]; c++;};
if (c==m)
{
cout<<"Iskomoe znachenie "<< min;
break;
};
};
if (c<m) cout<<"Trebuemoe znachenie otsutstvuet";
getch();
}
Вот код программы, которую мне помогли написать. То что она не правильная - известно. Может наведет на мысль.

pva
19-12-2008, 23:14
скажу честно, код не смотрел. Но подскажу идею, куда копать (С++). Используй частичную сортировку. Код приведён скорее для демонстрации различных фичей стандартной библиотеки, чем шаблона partial_sort. Рабочий, проверял.

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std;
//------------------------------------

int main()
{
// расположив строчку и вектор здесь, мы позволяем программе реже
// обращаться в менеджеру памяти, потому что эти контейнеры постепенно
// захватывают память по мере надобности и держат её на всякий случай.
// освободить её можно либо уничтожив контейнер, либо выполнив хитрую операцию:
// word_end.swap(string());
// values.swap(vector<int>());
string word_end;
unsigned sort_limit = 0;
vector<int> values;

for (bool working=true; working;)
{
cout << "\nEnter values separated with spaces and \"end\" at the end:\n";

// ввод данных
copy(istream_iterator<int,char>(cin), istream_iterator<int,char>(), back_inserter(values));

// слово end - не целое число, поэтому поток будет помечен как ios::failbit
if (!cin.eof() && !values.empty())
{
// снимаем эту пометку, проверяем что ввели хотя бы один элемент
cin.clear(ios::goodbit);

// убедились что именно слово end на конце, сняли слово из потока
if ((cin >> word_end) && word_end=="end")
{
// ввод и проверка границ для sort_limit
// помним, что в си нумерация идёт с нуля, и что -1 = 0xffffffff для unsigned int
while ((cout << "Enter sort limit: ") &&
(cin >> sort_limit) &&
(values.size() <= (sort_limit - 1)))
{
cout << "an unsigned integer value between 1 and " << values.size() << " expected\n";
}

// если удалось прочитать sort_limit и пройти цикл проверки диапазона
if (cin.good())
{
// делаем частичную сортировку
vector<int>::iterator middle(values.begin() + sort_limit);
partial_sort(values.begin(), middle, values.end());

// вывод результата
cout << sort_limit << "-th value is: " << *(middle - 1) << "\n";

// для отладки - можно закомментировать,
// а можно и посмотреть, как работает partial_sort
cout << "debug: ";
copy(values.begin(), values.end(), ostream_iterator<int,char>(cout," "));
cout << "\n";
}
else
{
// не ввели sort_limit
cout << "input aborted\n";
}
}
else
{
// пустой список или слово не end (например exit)
cout << "program aborted\n";
working = false;
}

values.clear();
}
else
{
// нет слова end в потоке - поток кончился.
cout << "unexpected end of input; program aborted\n";
working = false;
}
}

return 0;
}
//------------------------------------




© OSzone.net 2001-2012