How do I drop the lowest value? - c++

I'm pretty new to C++, and I need help figuring out the code for dropping the lowest value of a randomly generated set of numbers. Here is my code so far:
//Create array and populate the array with scores between 55 and 10
// Drop lowest Score
#include <iostream>
#include <cstdlib>//for generating a random number
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;
//function prototype
int *random (int);
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
//random function, generates random numbers between 55 and 100 ??
int *random(int num)
{ int *arr; //array to hold numbers
//return null if zero or negative
if (num <= 0)
return NULL;
//allocate array
arr = new int[num];
//seed random number generator
srand(time (0));
//populate array
for (int count = 0; count < num; count++)
arr[count] = (rand()%(45) +55);
//return pointer
//
return arr;
}
For this piece of code, how would I sort or find the lowest score to drop it after the function returns the random numbers?
int main()
{ int *numbers; //point to numbers
//get an array of 20 values
numbers = random(20);
//display numbers
for (int count = 0; count < 20; count++)
cout << numbers[count] << endl;
cout << endl;
system("pause");
return 0;
}
Your suggestions are appreciated!

In general, to find the lowest value in an array, you can follow this psuedo-algorithm:
min = array[0] // first element in array
for (all_values_in_array)
{
if (current_element < min)
min = current_element
}
However, you can't "drop" a value out of a static array. You could look into using a dynamic container (eg. vector), or swapping the lowest value with the last value, and pretending the size of the array is 1 less. Another low level option would be to create your own dynamic array on the heap, however, this is probably more complicated than you are looking for.
Using an vector would be much easier. To drop the lowest element, you just have to sort in reverse order, then remove the last element. Personally, I would recommend using a vector.

The obvious approach to find the smallest element is to use std::min_element(). You probably want to use std::vector<T> to hold your elements but this isn't absolutely necessary. You can remove the smallest value from an array like this:
if (count) {
int* it = std::min_element(array, array + count);
std::copy(it + 1, array + count--, it);
}
Assuming you, reasonable used std::vector<int> instead, the code would look something like this:
if (!array.empty()) {
array.erase(std::min_element(array.begin(), array.end()));
}

First find the index of the lowest number:
int lowest_index=0, i;
for (i=0; i<20; i++)
if (arr[i]<arr[lowest_index])
lowest_index=i;
Now that we know the index, move the numbers coming after that index to overwrite the index we found. The number of numbers to move will be 19 minus the found index. Ie, if index 2 (the third number, since the first is at index 0) is lowest, then 17 numbers comes after that index, so that's how many we need to move.
memcpy(&arr[lowest_index],&arr[lowest_index+1],sizeof(int)*(19-lowest_index))
Good luck!

Sort the array ascending.
The lowest value will be at the beginning of the array.
Or sort the array descending and remove the last element.

Further to what others have said, you may also choose to use something like, perhaps a std::list. It's got sorting built-in, also offering the ability to define your own compare function for two elements. (Though for ints, this is not necessary)
First, I typically typedef the vector or list with the type of the elements it will contain. Next, for lists I typedef an iterator - though both of these are merely a convenience, neither is necessary.
Once you've got a list that will holds ints, just add them to it. Habit and no need to do otherwise means I'll use .push_back to add each new element. Once done, I'll sort the list, grab the element with the lowest value (also the lowest 'index' - the first item), then finally, I'll remove that item.
Some code to muse over:
#include <cstdio>
#include <cstdlib>
#include <list>
using namespace std;
typedef list<int> listInt;
typedef listInt::iterator listIntIter;
bool sortAsc(int first, int second)
{
return first < second;
}
bool sortDesc(int first, int second)
{
return first > second;
}
int main (void)
{
listInt mList;
listIntIter mIter;
int i, curVal, lowestScore;
for (i=1; i<=20; i++)
{
curVal = rand()%45 + 55;
mList.push_back(curVal);
printf("%2d. %d\n", i, curVal);
}
printf("\n");
mList.sort();
// mList.sort(sortAsc); // in this example, this has the same effect as the above line.
// mList.sort(sortDesc);
i = 0;
for (mIter=mList.begin(); mIter!=mList.end(); mIter++)
printf("%2d. %d\n", ++i, *mIter);
printf("\n");
lowestScore = mList.front();
mList.pop_front();
printf("Lowest score: %d\n", lowestScore);
return 0;
}
Oh, and the choice to use printf rather than cout was deliberate too. For a couple of reasons.
Personal preference - I find it easier to type printf("%d\n", someVar);
than cout << someVar << endl;
Size - built with gcc under windows, the release-mode exe of this example is 21kb.
Using cout, it leaps to 459kb - for the same functionality! A 20x size increase for no gain? No thanks!!
Here's an std::list reference: http://www.cplusplus.com/reference/stl/list/

In my opinion the most optimal solution to your problem would be to use a linked list to store the numbers, this way you can use an algorithm with complexity O(N) = N to find the smallest element in the list, it is a similar finding method given by user1599559 or Mikael Lindqvist, you only need stored together with the minimum value the pointer to the Item(ItemX) in the linked list that store it, then to eliminate Item X just tell Item X - 1 points to Item X + 1 and free memory allocated by Item X

Related

Issues with checking an array moving both forwards and backwards simultaneously and issue printing values stored in a pointer array

Preface: Currently reteaching myself C++ so please excuse some of my ignorance.
The challenge I was given was to write a program to search through a static array with a function and return the indices of the number you were searching for. This only required 1 function and minimal effort so I decided to make it more "complicated" to practice more of the things I have learned thus far. I succeeded for the most part, but I'm having issues with my if statements within my for loop. I want them to check 2 separate spots within the array passed to it, but it is checking the same indices for both of them. I also cannot seem to get the indices as an output. I can get the correct number of memory locations, but not the correct values. My code is somewhat cluttered and I understand there are more efficient ways to do this. I would love to be shown these ways as well, but I would also like to understand where my error is and how to fix it. Also, I know 5 won't always be present within the array since I'm using a pseudo random number generator.
Thank you in advance.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// This is supposed to walk throught the array both backwards and forwards checking for the value entered and
// incrementing the count so you know the size of the array you need to create in the next function.
int test(int A[], int size, int number) {
int count = 0;
for (int i = 0; i <= size; i++, size--)
{
if (A[i] == number)
count++;
// Does not walk backwards through the array. Why?
if (A[size] == number)
count++;
}
cout << "Count is: " << count << endl;
return (count);
}
// This is a linear search that creates a pointer array from the previous "count" variable in function test.
// It should store the indices of the value you are searching for in this newly created array.
int * search(int A[], int size, int number, int arr_size){
int *p = new int[arr_size];
int count =0;
for(int i = 0; i < size; i++){
if(A[i]==number) {
p[count] = i;
}
count++;
}
return p;
}
int main(){
// Initializing the array to zero just to be safe
int arr[99]={0},x;
srand(time(0));
// Populating the array with random numbers in between 1-100
for (int i = 0; i < 100; i++)
arr[i]= (rand()%100 + 1);
// Was using this to check if the variable was actually in the array.
// for(int x : arr)
// cout << x << " ";
// Selecting the number you wish to search for.
// cout << "Enter the number you wish to search for between 1 and 100: ";
// cin >> x;
// Just using 5 as a test case.
x = 5;
// This returns the number of instances it finds the number you're looking for
int count = test(arr, (sizeof(arr)/4), x);
// If your count returns 0 that means the number wasn't found so no need to continue.
if(count == 0){
cout << "Your number was not found " << endl;
return 0;
}
// This should return the address array created in the function "search"
int *index = search(arr, (sizeof(arr)/4), x, count);
// This should increment through the array which address you assigned to index.
for(int i=0; i < count; i++) {
// I can get the correct number of addresses based on count, just not the indices themselves.
cout << &index[i] << " " << endl;
}
return 0;
}
I deeply appreciate your help and patience as well as I want to thank you again for your help.

Why is my randomly generated array outputting only zeroes?

I am writing a code that is supposed to act as a lottery. The lottery numbers available are 1-50, and there are 10 of them. The user is supposed to input one number and the program returns if the user's number matches one of the 10 random lottery numbers. I have gotten all of these parts down, but there is one problem; all 10 of the lottery numbers must be unique. I have gotten 10 unique numbers 1-50, but they weren't very random. The code I have written up to this point seems correct to me, except I know there is something missing (along with the fact that I can clean my code up a lot, but I'm focusing on the objective right now). Right now if I run the program it will return ten zeroes. I need each element in the lottery array to be a unique number from 1-50, and produce different sets of numbers each time i run the program. Any help would be appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using std::cout; using std::cin; using std::endl;
void printOut(int[]);
void draw(int[]);
bool check();
int fillFunc[10];
int main()
{
const int arraySize = 10;
int win[arraySize] = {};
srand((unsigned)time(NULL));
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
}
void draw(int fillFunc[])
{
int i;
for (i = 0; i < 10; i++)
{
if (check() == true)
continue;
fillFunc[i] = 1 + rand() % 50;
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
bool check()
{
for (int i = 0; i < 10; ++i)
{
if (fillFunc[i] == i)
return true;
}
return false;
}
(also don't ask me why the array has the name "win", this is what my prof wants me to call it)
Because check() always return true. At the start, the array is filled with zeroes so check returns true as win[0]==0 and that remains true forever as nothing changes that value. So in draw you always branch to continue and never modify anything.
To solve the problem one way could be to shuffle the sequence of 1-50 and extract the first 10 values of the shuffled array. You can use the very simple Fisher-Yates algorithm.
To answer your question that you updated in the comments you need to consider a shuffling algorithm.
I will give you an idea of how to do this that is O(n) so you don't have to "loop" thru your current list of numbers and keep checking to see if the new number was already picked...
your lottery max number is 50 so make an array of size 50 that is as follows:
lotteryNumber[0]=1
lotteryNumber[1]=2
...
lotteryNumber[49]=50
to pick a number to put into your "selected" numbers array...
indexToLotteryNumbers = rand() % 50 - numbersPickedSoFar;
randomLotteryNumber[i++] = lotteryNumber[ indexToLotteryNumbers ];
// this is the key "trick"
swap(&lotteryNumber[ indexToLotteryNumbers ], &lotteryNumber[49-numbersPickedSoFar]);
numbersPickedSoFar++;
Theory
The random numbers are the indexes and not the actual values
By swapping the number you picked with the outer element you don't care if your random number generator picks the same index because it will be different the next time.
look at a small example...say you have 1 2 3 4
rand() generates "2"
so your first # is 2 (assume 1-based indexing here) now you swap the (4th) element for the (2nd) element now you have 1 4 3 |2
(here |2 means you can't pick that number again because it's outside the
random # generator range) but you reduce the random # generation from
1-4 to 1 thru 3
rand() generates "1" so your number is "1" and you swap that with the "outer" unpicked number 3 4 |1 2
rand() generates
"2" again! your lottery number is 4 this time... and so on.
I hope this makes sense.
This is what I would do, given your constraints. Rather than check if a number is unique while you are filling the array, just pass the array into the function that chooses the number so it can return a unique value.
I also removed the redundant global array. It could be a source of bugs if you forgot to pass the local array you were working with to any of the functions.
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int getUniqueNumber(int fillFunc[])
{
while(true)
{
//pick number
int val = 1 + rand() % 50;
//assume it's unique
bool unique = true;
for (int i = 0; i < 10; ++i)
{
//if another number matches, it isn't unique, choose again
if (fillFunc[i] == val)
{
unique = false;
break;
}
}
//if it is unique, return it.
if (unique)
{
return val;
}
}
//never reached, but avoids an all control paths must return a value warning.
return -1;
}
void draw(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
fillFunc[i] = getUniqueNumber(fillFunc);
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
int main()
{
srand((unsigned)time(NULL));
const int arraySize = 10;
int win[arraySize] = {};
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
return 0;
}
There are other, perhaps better, ways to select unique numbers in a range, but I went for simple to implement and explain. You can read about some other methods in these questions:
Unique random numbers in an integer array in the C programming language
Unique (non-repeating) random numbers in O(1)?
You only assign a value to fillFunc[i] when i is 10, which is an out of bounds access. Move the assignment to inside the loop.
You have other problems too. If you do continue, you just leave an entry in the array unset.
You should try adding a lot of output statements to your program so you can more easily understand what it's doing. If you prefer, use a debugger to step through it.

How to fill an array with random values from a range? (Duplicates are OK.)

I am new to C++, I have a problem of array manipulation. I have an array of X with length 100, I need to fill the value of X with integer value of 1 to 10 (1,2,3,4,5,6,7,8,9,10) randomly.
I know that there will be duplicate, maybe like 1 printed ten times, etc, but that's really what I want.
Here is what I have:
an array of X:
int X[100];
Here is my code snippet:
int* X = NULL;
int* val = NULL;
int length1= 100;
int length2= 10;
X = new int[length1];
val = new int[length2];
int i;
int j;
for (i = 0; i < isi; i++) {
val[i] = i;
for (j = 0; j < length1; j++) {
if (j > i) {
X[j] = val[i];
} else {
X[j] = val[0];
}
cout << "X[" << j << "] = " << X[j] << "\n";
Sleep(1);
}
}
Code above makes the array X from index 0 to 99 has value of 0, then index 0 to 99 has value of 1 and so the other index until the index 0 to 99 has value of 9.
This is not what I want, what I want is to make it (if it is not random) index 0 to 9 has value of 0, then 10 to 19 has value of 1 ... until index 90 to 99 has value of 9. Hope my explanation clear.
I have come to a question in stackoverflow: How would you make an array of 10000 with only values of 1-1000 inclusive?
But still can't resolve my problem my self.
Can someone please give me solution to this.
Thank you in advance
#include <stdlib.h>
int main(int argc, char **argv) {
int r[100];
for (int i = 0; i < 100; ++i) {
r[i] = rand() % 10 + 1;
}
}
For some output, you can #include <iostream> and then std::cout << "r[" << i << "] = " << r[i] << "\n" inside the loop after each assignment.
If you want to seed the random number generator for a different sequence each time, then #include <time.h> and then srand(time(NULL)) before your first call to rand.
You can also use generate function:
#include <iostream>
#include <algorithm>
#include <random>
using namespace std;
int main()
{
int arr[100];
random_device rd;
default_random_engine dre(rd());
uniform_int_distribution<int> uid(0,9);
generate(arr, arr + sizeof(arr) / sizeof(int), [&] () { return uid(dre); });
for (int a : arr)
cout << a << " ";
}
Here are two ways to solve this problem - since this is a learning experience, only pseudo code (and relevant links) are provided. Each "task" can be looked up and solved separately. Note that neither method uses a secondary array.
If the amount of each number in the final result does not need to be the same (eg. 2 might appear 17 times) then consider the following loop-and-assign-random approach. A standard C for-each loop is sufficient.
# for every index pick a random value in [0, 10) and assign it
for i in 0 to last array index:
array[i] = random in range 0, 10
If the amount of numbers need to be the same, then consider filling the array and then shuffling it. The modulus operator is very handy here. (This assumes the array length is a multiple of the group size.)
# fill up array as 0,1,2,3,4,5,6,7,8,9,0,1,2.. (will be 10 groups)
for i in 0 to last array index:
array[i] = i % 10
# and randomly rearrange order
shuffle array
For the shuffle see Fisher-Yates, which even shows a C implementation - there are "more C++" ways, but this is a good technique to learn and practice with loops. (One cool property about Fisher-Yates is that as soon an item is swapped into the current index it is at the final swap location - thus the shuffle loop can be modified to shuffle and immediately perform an action such as displaying the value.)
In both cases a random function should be used; else the numbers will not be .. random.
To loop over the items of a collection the most natural C++ loop is the range based for loop.
In order to assign something to each item, the formal item name should be a reference, thus:
for( auto& item : X )
{
// E.g. assign to item here.
}
This serves up each item of the array, in order, to the code marked by a comment.
There are two different random generators in C++, the old C library one, which is just a pair of functions, and the more general and modern but also not-so-easy-to-grok C++11 thingy. I suggest you google it and try out things. Ask new more specific question if/when stuck.
I think others have pointed it out but you have to first write the pre-compiler directive #include <ctime> and then use the srand function. Most would say don't use that but since you and I are at the basics our teachers, respectively, start us off with that. And it might work with your compiler as well.
Here is a link to learn more about it. I would have commented but I can't.
http://www.cplusplus.com/reference/cstdlib/srand/

Get the maximum number from an integer array in C++

I have another task for my school and it is:
Write a program which will output the largest from three inputed numbers
So far I have done this:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int* numbers = new int[3];
for(int i = 0; i < 3; i++) {
cout << "Input number no. " << (i + 1);
cin >> numbers[i];
cout << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Is there a helper function/method in C++ which will find a largest number in my numbers array?
There's an algorithm that finds the maximal element in a container (std::max_element), but that's inappropriate. Your situation can be solved with constant memory consumption, so you don't need to store all numbers. At any given point, you just need to remember the current maximum.
Imagine you had to process one gazillion numbers. Then storing them all would not be desirable.
Of course, internally the max_element algorithm does the same as I just suggested, but it assumes that you already have the container anyway. If you don't, then just update the maximum on the fly. The boost.accumulators library has something to do that, but I'm sure you can write this yourself — it should only take one or two lines.
In the following code snippet, max will contain the highest number from the list:
int i;
int max=numbers[0];
for(i=1;i<3;i++)
{
if(numbers[i]>max) max=numbers[i];
}
Note: Your array looks too small - it has a size of two and I'm pretty sure you want a size of three.
You don't need an array here. Just look at the numbers as they come in:
int largest = std::numeric_limits<int>::min();
for (int i = 0; i < 3; ++i) {
int value;
std::cin >> value;
if (largest < value)
largest = value;
}

Find the biggest 3 numbers in a vector

I'm trying to make a function to get the 3 biggest numbers in a vector. For example:
Numbers: 1 6 2 5 3 7 4
Result: 5 6 7
I figured I could sort them DESC, get the 3 numbers at the beggining, and after that resort them ASC, but that would be a waste of memory allocation and execution time. I know there is a simpler solution, but I can't figure it out. And another problem is, what if I have only two numbers...
BTW: I use as compiler BorlandC++ 3.1 (I know, very old, but that's what I'll use at the exam..)
Thanks guys.
LE: If anyone wants to know more about what I'm trying to accomplish, you can check the code:
#include<fstream.h>
#include<conio.h>
int v[1000], n;
ifstream f("bac.in");
void citire();
void afisare_a();
int ultima_cifra(int nr);
void sortare(int asc);
void main() {
clrscr();
citire();
sortare(2);
afisare_a();
getch();
}
void citire() {
f>>n;
for(int i = 0; i < n; i++)
f>>v[i];
f.close();
}
void afisare_a() {
for(int i = 0;i < n; i++)
if(ultima_cifra(v[i]) == 5)
cout<<v[i]<<" ";
}
int ultima_cifra(int nr) {
return nr - 10 * ( nr / 10 );
}
void sortare(int asc) {
int aux, s;
if(asc == 1)
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] > v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = aux;
s = 1;
}
} while( s == 1);
else
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] < v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = v[i];
s = 1;
}
} while(s == 1);
}
Citire = Read
Afisare = Display
Ultima Cifra = Last digit of number
Sortare = Bubble Sort
If you were using a modern compiler, you could use std::nth_element to find the top three. As is, you'll have to scan through the array keeping track of the three largest elements seen so far at any given time, and when you get to the end, those will be your answer.
For three elements that's a trivial thing to manage. If you had to do the N largest (or smallest) elements when N might be considerably larger, then you'd almost certainly want to use Hoare's select algorithm, just like std::nth_element does.
You could do this without needing to sort at all, it's doable in O(n) time with linear search and 3 variables keeping your 3 largest numbers (or indexes of your largest numbers if this vector won't change).
Why not just step through it once and keep track of the 3 highest digits encountered?
EDIT: The range for the input is important in how you want to keep track of the 3 highest digits.
Use std::partial_sort to descending sort the first c elements that you care about. It will run in linear time for a given number of desired elements (n log c) time.
If you can't use std::nth_element write your own selection function.
You can read about them here: http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements
Sort them normally and then iterate from the back using rbegin(), for as many as you wish to extract (no further than rend() of course).
sort will happen in place whether ASC or DESC by the way, so memory is not an issue since your container element is an int, thus has no encapsulated memory of its own to manage.
Yes sorting is good. A especially for long or variable length lists.
Why are you sorting it twice, though? The second sort might actually be very inefficient (depends on the algorithm in use). A reverse would be quicker, but why even do that? If you want them in ascending order at the end, then sort them into ascending order first ( and fetch the numbers from the end)
I think you have the choice between scanning the vector for the three largest elements or sorting it (either using sort in a vector or by copying it into an implicitly sorted container like a set).
If you can control the array filling maybe you could add the numbers ordered and then choose the first 3 (ie), otherwise you can use a binary tree to perform the search or just use a linear search as birryree says...
Thank #nevets1219 for pointing out that the code below only deals with positive numbers.
I haven't tested this code enough, but it's a start:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> nums;
nums.push_back(1);
nums.push_back(6);
nums.push_back(2);
nums.push_back(5);
nums.push_back(3);
nums.push_back(7);
nums.push_back(4);
int first = 0;
int second = 0;
int third = 0;
for (int i = 0; i < nums.size(); i++)
{
if (nums.at(i) > first)
{
third = second;
second = first;
first = nums.at(i);
}
else if (nums.at(i) > second)
{
third = second;
second = nums.at(i);
}
else if (nums.at(i) > third)
{
third = nums.at(i);
}
std::cout << "1st: " << first << " 2nd: " << second << " 3rd: " << third << std::endl;
}
return 0;
}
The following solution finds the three largest numbers in O(n) and preserves their relative order:
std::vector<int>::iterator p = std::max_element(vec.begin(), vec.end());
int x = *p;
*p = std::numeric_limits<int>::min();
std::vector<int>::iterator q = std::max_element(vec.begin(), vec.end());
int y = *q;
*q = std::numeric_limits<int>::min();
int z = *std::max_element(vec.begin(), vec.end());
*q = y; // restore original value
*p = x; // restore original value
A general solution for the top N elements of a vector:
Create an array or vector topElements of length N for your top N elements.
Initialise each element of topElements to the value of your first element in your vector.
Select the next element in the vector, or finish if no elements are left.
If the selected element is greater than topElements[0], replace topElements[0] with the value of the element. Otherwise, go to 3.
Starting with i = 0, swap topElements[i] with topElements[i + 1] if topElements[i] is greater than topElements[i + 1].
While i is less than N, increment i and go to 5.
Go to 3.
This should result in topElements containing your top N elements in reverse order of value - that is, the largest value is in topElements[N - 1].