Dynamic array

Pages: 12
Dec 23, 2019 at 9:23pm
closed account (23q2T05o)
Hi, so the user has to type the numbers in the array, then the program has to find the largest number in the array, then half it and here is an example:
if the array is 2 32 4 8, the largest number is 32, the new array should look like this: 2 16 16 4 8

I have done so far, please help me, I am new to programming :)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  #include <iostream>
#include <new>
using namespace std;

int main ()
{
  int i,n, numa;
  int * p;
  cout << "How many numbers would you like to type? ";
  cin >> i;
  p= new (nothrow) int[i];
  
  if(i<4 || i>1024){
      cout<<"Invalid input!";
      return 1;
  }
  
  if (p == nullptr)
    cout << "Error: memory could not be allocated";
  else
  {
    for (n=0; n<i; n++)
    {
      cout << "Enter number: ";
      cin >> p[n];
    }
    
    cout<<"A<num>, enter a number: ";
    cin>>numa;
    
    for(i = 1; i < n; ++i)
    {
       if(p[0] < p[i])
           p[0] = p[i];
    }
  }
  
  delete[] p;
  return 0;
}
Dec 23, 2019 at 9:27pm
Keep a variable called "max_value", set it to be a really low number, initially (e.g. lowest possible int, std::numeric_limits<int>::min(), see http://www.cplusplus.com/reference/limits/numeric_limits/)
Alternatively, just set the max_value to initially be the first element in the array, after line 26.

As you iterate through the array in your lines 31-36 for loop, update the "max_value" if the current array element is greater than the current max_value.

Then, iterate through the array a second time, but this time, halve the number if it equals max_value.
Last edited on Dec 23, 2019 at 9:37pm
Dec 24, 2019 at 12:36am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

using namespace std;

int main()
{
    int p[] = {52,92,2,4,78,10};
    int size = sizeof(p)/sizeof(int);
    
    size_t index_of_biggest = 0;
    for( size_t i = 1; i < size; i++) // <-- Why did I have size - 1? Because I was lucky :)
    {
        if (p[i] > p[index_of_biggest])
            index_of_biggest = i;
    }
    cout << "Biggest = " << p[index_of_biggest] << '\n';
    
    p[index_of_biggest] /= 2;
    for( size_t i = 0; i < size; i++)
    {
        cout << p[i] << '\n';
    }
    return 0;
}
Last edited on Dec 24, 2019 at 10:28am
Dec 24, 2019 at 9:08am
closed account (23q2T05o)
Hi, so if I have to find the biggest num and half it for example 3 times? I mean find the biggest num, half it, find again the new biggest num, half it and again find the new biggest num and half it, how would the code look like then?
Dec 24, 2019 at 9:24am
What are you learning here? Memory management or logic of finding a value from array?

If the latter, then let vector manage the memory (for now).
(You should learn the use of standard containers anyway.)
Remember that input can fail. (Never trust the user.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <vector>

int main ()
{
  int n = 0;
  std::cout << "How many numbers would you like to type? ";
  std::cin >> n;
  if ( n < 4 || 1024 < n ) {
      std::cout << "Invalid input!\n";
      return 1;
  }

  std::vector<int> p;
  p.reserve( n ); // preallocate memory without creating elements

  int value = 0;
  int i=0;
  while ( i < n && std::cin >> value )
  {
    // add value only if read was successful
    p.emplace_back( value );
  }
  // p has at most n values

  // show p
  for ( int v : p ) {
    std::cout << v << ' ';
  }
  std::cout << '\n';
}


This is how standard library would solve the half largest:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <algorithm>

int main ()
{
  // input
  std::vector<int> p {52, 91, 2, 7, 78, 10};

  // find largest element
  auto m = std::max_element( p.begin(), p.end() );
  // modify
  *m /= 2;

  // show p
  for ( int v : p ) {
    std::cout << v << ' ';
  }
  std::cout << '\n';
}

The key thing to notice is that the std::max_element does not return a value. It returns the position (in range) of the largest value (just like againtry's loop does).

You could merge the input loop and the find largest element loop, if you write both by hand.

@againtry:
i < size - 1? Why do you skip the last element?


Ganado's "by value" approach changes {8,2,3,8} into {4,2,3,4}.
The "find largest" returns {4,2,3,8}.
Choose the approach that does what you want.
Dec 24, 2019 at 9:28am
closed account (23q2T05o)
we havent studied #include <vector> and we cant use it for now :/ and the same for <algorithm>
Dec 24, 2019 at 10:30am
Check this out. I think it does 3, despite losing all confidence in mistakenly using size - 1 which luckily worked because the last element (10) wasn't in the race.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

using namespace std;

int main()
{
    int p[] = {52,92,2,4,78,10};
    int size = sizeof(p)/sizeof(int);
    
    size_t index_of_biggest = 0;
    
    for(int trial = 0; trial < 3; trial++) // <--
    {
        for( size_t i = 1; i < size; i++)
        {
            if (p[i] > p[index_of_biggest])
                index_of_biggest = i;
        }
        cout << "Biggest = " << p[index_of_biggest] << '\n';
        
        p[index_of_biggest] /= 2;
        for( size_t i = 0; i < size; i++)
        {
            cout << p[i] << '\n';
        }
    }// <--

    return 0;
}
Dec 24, 2019 at 1:13pm
haven't studied, can't use

Irrelevant. If you haven't seen something does not mean that you cannot look at it. Not for use, but for ideas.
The idea of max_element is to return (where) an element is rather than what is in it.
(It is trivial to access the value, if you already know the element.)


I bet you haven't had functions either (unless you count the main). Functions are handy for encapsulating and reusing something.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

void maxhalve( int* data, int N )
{
  int index_of_biggest = 0;
  for ( int i = 1; i < N; i++)
  {
     if ( data[i] > data[index_of_biggest] ) index_of_biggest = i;
  }
  std::cout << "Biggest = " << data[index_of_biggest] << '\n';
  data[index_of_biggest] /= 2;
}

int main()
{
  int p[] = {52,92,2,4,78,10};
  int size = sizeof(p) / sizeof(int);

  for (int trial = 0; trial < 3; trial++)
  {
    maxhalve( p, size );

    for ( int v : p ) std::cout << v << '\n';
  }
}

Now the main clearly repeats two operations:
1. finds and modifies the largest element of p
2. shows p

It is not compulsory to use functions (except for recursion), but it can make code easier to read.

There is one logical difference between this version and againtry's. It is not the use of functions.
Dec 26, 2019 at 12:19pm
closed account (23q2T05o)
@againtry, when the program finds the biggest num, for example: the array looks like that: 14 16 18, the biggest num is 18, so it halfs it and then the array should look like this: 14 16 9 9, so how to make it like that?
Dec 26, 2019 at 12:31pm
Of my, you have to add elements too. Missed that initially.

And three times. As in:
8 18 16
8 9 9 16
8 9 9 8 8
8 4 4 9 8 8

Is it ok to append the new elements, rather than to insert?
8 18 16
8 9 16 9
8 9 8 9 8
8 4 8 9 8 4

Either way, your array has to be larger than the input data.
1
2
3
4
5
6
7
8
9
10
11
size = 5;
capacity = size + 3; // room for 3 splits
p = new int [capacity];
// insert size values
while ( size < capacity ) {
  e = find_largest( p, size );
  p[e] /= 2;
  p[size] = p[e]; // or insert( p, size, e+1, p[e] )
  ++size;
}
delete [] p;
Last edited on Dec 26, 2019 at 12:31pm
Dec 26, 2019 at 12:31pm
then the array should look like this: 14 16 9 9


I assume this means you add an extra item to the array and make that item half the (previous) maximum.

If that's right then you can allow for the extra items in the array at the start of the program or create a new array each time and copy the values across.

I would just add the extra places at the start, in this case 3 extras (1 for each try) above those shown at my line 8, i.e. size += 3.

Then just do what you want, keeping in mind you'll have to update the index values accordingly.
Dec 26, 2019 at 12:36pm
closed account (23q2T05o)
@againtry yes, it makes an item that is the half, the array is 10 12 16, the new one should be 10 12 8 8, I hope you get it, but can you help me withe the code?
Dec 26, 2019 at 12:41pm
closed account (23q2T05o)
@keskiverto, yes you are right but idk how to add your code to mine :)
Dec 26, 2019 at 12:44pm
closed account (23q2T05o)
@againtry, also the user inputs the num, as I said in the example if its 3 and the array looks like this: 16 12 6, the biggest one in 16, the new array is 8 8 12 6, again finds the biggest num and its 12 so the new array is 8 8 6 6 6 and again the biggest num is 8 so the new array should look like this 4 4 8 6 6 6, it find 3 times the biggest num and halfs it, so this num 3 in my code is named numa. Please help mee
Dec 26, 2019 at 1:05pm
the user inputs the num

Yep, that's OK - so all you do is add 3 to the answer to your line 9 input.

And it appears you have to put the result of the halving alongside the original. I missed your repeated 16 at your original post. My bad :[

So, another way of showing the same as your description

16 12 6 -> 8 12 6 -> 8 8 12 6 after inserting 8
8 8 12 6 -> 8 8 6 6 -> 8 8 6 6 6 after inserting 6
8 8 6 6 6 -> 4 4 8 6 6 6 after inserting 4

You refer to numa at your line 29, but AFAICS your program doesn't use it.

Dec 26, 2019 at 1:10pm
closed account (23q2T05o)
@againtry the user inputs numa /that how its named in my code/ and that num is how many times your have to find the biggest num, half it and create a new array
please help me with the code
Dec 26, 2019 at 1:22pm
OK,so, numa = trial in my program. That's what I thought. The point is you haven't used it while I have, even though the extra insertions aren't in either of our's.

What I'd suggest is you have a go using either of our code -let's see what you come up with but the essence is, once you have the maximum you have to insert it in your array by moving elements around - shifting then along by making room.

Keep in touch.
Dec 26, 2019 at 1:31pm
closed account (23q2T05o)
@againtry so I just inserted your code in my code but the problem is: if the array is 4 16 8, then the array is 4 8 8 but it should be 4 8 8 8, so what should I do?
Dec 26, 2019 at 1:48pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

using namespace std;

int main()
{
    int p[] = {16,12,6,0,0,0};//{52,92,2,4,78,10,0,0,0};
    size_t size = sizeof(p)/sizeof(int);
    size_t index_of_biggest = 0;
    
    for(size_t trial = 0; trial < 3; trial++) 
    {
        for( size_t i = 0; i < size; i++)
        {
            if (p[i] > p[index_of_biggest])
                index_of_biggest = i;
        }
        p[index_of_biggest] /= 2;
        
        // SHIFT ALONG 1 SPOT
        for(size_t i = size - 2; i > index_of_biggest; i-- )
        {
            p[i+1] = p[i];
        }
        p[index_of_biggest+ 1] = p[index_of_biggest];
        
        for( size_t i = 0; i < size; i++)
        {
            cout << p[i] << ' ';
        }
        cout << '\n';
    }
    
    return 0;
}



8 8 12 6 0 0
8 8 6 6 6 0
4 4 8 6 6 6
Last edited on Dec 26, 2019 at 2:09pm
Dec 26, 2019 at 1:51pm
HINT: You have to put 'numa' extra zero's in the array
Pages: 12