Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Как выяснить размер числового массива? (http://forum.oszone.net/showthread.php?t=125971)

mrcnn 14-12-2008 13:10 980663

Как выяснить размер числового массива?
 
Тип 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 980735

точно так же как и внутри функции:
Код:

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

mrcnn 14-12-2008 15:37 980752

max(sz1,sz2) это не функция, а макрос, кстати.

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

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

Busla 14-12-2008 17:40 980832

mrcnn, если ошибок в проектировании нет, то и вопросов возникать возникать не должно о представлении данных внутри программы ;)

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

mrcnn 14-12-2008 18:59 980880

Busla, Умный, да?

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


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

Alan85 14-12-2008 20:28 980920

Предлагаю использовать нулевую ячейку массива для хранения длины . Как string в старом паскале

Busla 14-12-2008 20:30 980923

Цитата:

Цитата mrcnn
Класс я организовывать не буду и не хочу. »

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

mrcnn 15-12-2008 09:13 981230

Я недостаточно знаю структуры и классы, поэтому будут постоянно ошибки. У меня больше времени уйдет на разбор языка и на борьбу с ошибками, чем на написание программы и на разработку алгоритма. А программу сдать надо завтра и времени переписывать готовое нет..

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

pva 15-12-2008 10:14 981287

Цитата:

Цитата mrcnn
Я недостаточно знаю структуры и классы, поэтому будут постоянно ошибки. У меня больше времени уйдет на разбор языка и на борьбу с ошибками, чем на написание программы и на разработку алгоритма. А программу сдать надо завтра и времени переписывать готовое нет.. »

А зря! месяц помучаешься, потом за уши не оттянешь!
Ну если очень не хочется, есть ещё способ:
Код:

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 984711

Извините за оффтоп. Время поджимает. Есть задача.
Задается размер массива в ручную (например 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 985337

скажу честно, код не смотрел. Но подскажу идею, куда копать (С++). Используй частичную сортировку. Код приведён скорее для демонстрации различных фичей стандартной библиотеки, чем шаблона 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;
}
//------------------------------------



Время: 21:58.

Время: 21:58.
© OSzone.net 2001-