Modifing Arrays without using <algorithm> functions in C++? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So first, we start with an array of 50. The range of the values within the array can be 1-100, not repeating. Then we display the highest value of that random array. Then we display the lowest value in the array. Then comes the sorting, which would be easy using the standard library functions in the <algorithm> header, but since it's not allowed, we need to find another way around it. Then sort from high to low.
So, to display this easily... First we start with an array[50] with random numbers between 1-100
72 29 11 41 31 27 21 46 43 40 17 45 30 32 25 15 19 88 22 24 51 34 99 23 26 37 1 4 2 9 33 44 12 39 38 3 47 48 5 42 49 18 54 55 87 16 28 20 50 9
Now we display the highest number
99
Then the lowest
1
The we sort them
1 2 3 4 5 9 9 11 12 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 54 55 72 87 88 99
Then reverse sort them
99 88 87 72 55 54 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 12 11 9 9 5 4 3 2 1
So.. how would I go about doing this without algorithms?

The usual way to do this is by using loops.
For example, to traverse an array, printing every element, we could use a loop like:
for (int i=0; i<50; i++) {
std::cout << array[i] << std::endl;
}
All of the problems you mention, except sorting, can be done using a simple loop like the one above. You'll have to do your own bookkeeping in order to solve the problems, but it shouldn't be too difficult.
As for sorting, that's a more challenging problem. You might start with the wikipedia article to see how that is handled. You probably want to try implementing selection sort.

You can use bitset sort since the range of values of the array is limited to 1-100, and there is no repetition you can have a bitset array of 100 ints where each index specifies can be a 0 (that number isn't in the array) or a 1 (the number is in the array). For example the array [1, 5, 3] can be represented by the bitset array [1, 0, 1, 0, 1].
pseudo code:
MAX_SIZE = 100
bitset = new int[MAX_SIZE]
smallest = biggest = -1
for each value in array {
smallest = value if value < smallest
biggest = value if value > biggest
bitset[value-1] = 1
}
sorted = (i for i in 0..bitset.length - 1 if bitset[i] == 1)
reverse_sorted = (sorted[i] for i in sorted.length-1..0)

Not very professional but works
int array[50], used[50], sortedArray[50], buildSort = 1, genNum, max = 0, min = 101;
bool x;
srand(time(0));
//Array Generator
for(int i = 0; i < 50; i++){
do{
genNum = (1+rand()%100);
x = false;
for(int j =0; j < 50; j++){
if(genNum == used[j]){
x = true;
}
}
}while(x == true);
used[i] = genNum;
array[i] = genNum;
}
cout << "Numbers: ";
for(int d = 0; d < 50; d++){
cout << array[d] << " ";
}
cout << endl << endl;
//Max and Min finder
for(int m = 0; m < 50; m++){
if(array[m] > max){
max = array[m];
}
if(array[m] < min){
min = array[m];
}
}
cout << "Max is: " << max << endl;
cout << "Min is: " << min << endl << endl;
//Sorting
sortedArray[0] = min;
for(int v = min+1; v <= max; v++){
for(int r = 0; r < 50; r++){
if(array[r] == v){
sortedArray[buildSort] = array[r];
buildSort++;
}
}
}
cout << "Sorted: ";
for(int k = 0; k < 50; k++){
cout << sortedArray[k] << " ";
}
cout << endl << endl;
cout << "Reverse sorting: ";
for(int l = 49; l >=0; l--){
cout << sortedArray[l] << " ";
}

Well, I have not checked this code and I'm sure it has some errors in it, but hopefully this will at least give you some ideas and a good base to go off of:
/******************
*
* Your array should have 51 spots.
* The last element should be 0.
*
******************/
uint8_t findMax(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t highest = 0;
for(; *arrayToSearch; arrayToSearch++){
highest = (*arrayToSearch > highest) ? *arrayToSearch : highest;
}
return highest;
}
uint8_t findMin(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t lowest = 101;
for(; *arrayToSearch; arrayToSearch++){
lowest = (*arrayToSearch < lowest) ? *arrayToSearch : lowest;
}
return lowest;
}
void sortAscending(uint8_t *arrayToSearch){
// sort from low to high
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll the sorted values to the array to search */
int i;
for(i=0; i < count; i++){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/*
* We can actually write sortDescending the same way and just modify
* the last loop to put them in reverse order
*/
void sortDescending(uint8_t *arrayToSearch){
// sort from low to high and then order as high to low
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll copy the values to the arrayToSearch in reverse order */
int i;
for(i=(count-1); i >= 0; i--){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/* calling these */
int main(){
uint8_t yourArray[51];
// ... your code to populate this array
yourArray[50] = 0; // set the last spot to 0.
uint8_t highest = findMax(yourArray);
uint8_t lowest = findMin(yourArray);
// now make yourArray sorted by lowest to highest
sortAscending(yourArray);
// ... Whatever you need to do with it in ascending order.
// now make it sorted by highest to lowest
sortDescending(yourArray);
// ... Whatever you need to do with it in descending order.
return 0;
}
I'm a C-programmer so this is a rather C-style answer.
Some additional information that might be helpful can be found at:
http://www.sanfoundry.com/c-program-sort-array-ascending-order/
http://www.programmingsimplified.com/c/source-code/c-program-bubble-sort
http://en.wikipedia.org/wiki/Sorting_algorithm
The Wikipedia page (last link) might seem a little overwhelming, but there is a lot of great content on it.
I hope this will be of some help to you. Again, I'm not sure if the code I included will work properly. It's merely meant to convey the general idea.

Related

How to do a specific double "for" loop to do a calcul

I would like to be able to do a loop that be able to make a count like this :
00 01 02 03 04
10 11 12 13 14
20 12 22 23 24
30 31 32 33 34
40 41 42 43 44
The way they are wrote is not important, I just want to be able do a count from 0 to 4 on the right number, then it do a + to the left number, and again 0 to 4
And here is what I've done
for (i; i <= TAILLE - 1; i++) {
for (int i2=0; i2 <= TAILLE - 1; i2++) {
//tableau[x][y] = false;
cout << x << y << endl;
y = i2;
}
x = i;
}
TAILLE = 5
x=0
y=0
i=0
i2=0
x is the left number
y the right number
This should do the trick:
for (int i = 0; i < TAILLE; i++) {
for (int j=0; j <TAILLE; j++) {
cout << i << j << ' ';
}
cout << endl;
}
some notes on this code:
1.- Instead of i<=TAILLE -1 use i<TAILLE it is shorter and easier to read. Also it is more computationally efficient since you avoid the subtraction, this is very subtle, but it's good to note this kind of detail, since in large datasets this could mean saving thousands or millions of calculations.
2.- Use i, j, k instead of i, i2, i3, this is not mandatory, but is kind of the standard and makes it easier to read as well.
3.- The variables x and y are not necessary, you can use directly i and j

Where is this array value coming from?

So I'm practicing coding before classes begin again and I wanted to create a random array of 10 integers and wanted to find which two numbers, when added together, equal greater than 100.
When I run the code below
int arr[9];
for(int i = 0; i<=9; i++){
arr[i]=(rand()%100)+1;
cout<<arr[i]<<endl;
}
cout<<endl;
for(int k = 0; k<=9; k++){
for (int j = k+1; j<=9; j++){
if((arr[k]+arr[j])>100){
cout<<arr[k]<<" + "<<arr[j]<<" "<<"over 100"<<endl;
}
else{
cout<<arr[k]<<" + "<<arr[j]<<" "<<"under 100"<<endl;
}
}
}
return 0;
I notice that the value of arr[9] is equal to one number but the program has another number for it.
For example: the array that's created is
[42
68
35
1
70
25
79
59
63
65]
but my output shows a 9 as arr[9]
42 + 68 over 100
42 + 35 under 100
42 + 1 under 100
42 + 70 over 100
42 + 25 under 100
42 + 79 over 100
42 + 59 over 100
42 + 63 over 100
42 + 9 under 100
(I'll just include the first loop to not make this any longer)
Where did my 65 go??
Where did the 9 come from??
Did I write something wrong??
Thanks
I notice that the value of arr[9] is equal to one number but the program has another number for it.
Counting in computers starts from 0 and ends at one number less than the total size. For int arr[9]
the ninth index is arr[8]
the 1st index is arr[0]
the 2nd index is arr[1]
When you do arr[9], you are crossing the boundary (accessing an element that's not in the range) which leads to undefined behaviour.
As a result, your loop should stop at i < 9:
for(int i = 0; i < 9; i++) // i < 9 now vs i <=9
The same changes need o be made to the loops below the first one.

srand() is outputting the wrong values

So I'm making a selection sort program where I have to input two values: one for the numbers to use in the array, and the seed to use for the random number generator. I'm just a little confused on how to adjust the number used, since the maximum number of elements we can put in is 15. The array currently has 8. Each element should be a number between 20 and 40.
#include <iostream>
using namespace std;
int selectionSort(int[], int);
int selectionSort(int numbers[], int numbersSize) {
int i = 0;
int j = 0;
int indexSmallest = 0;
int temp = 0; // Temporary variable for swap
for (i = 0; i < numbersSize - 1; ++i) {
// Find index of smallest remaining element
indexSmallest = i;
for (j = i + 1; j < numbersSize; ++j) {
if (numbers[j] < numbers[indexSmallest]) {
indexSmallest = j;
}
}
// Swap numbers[i] and numbers[indexSmallest]
temp = numbers[i];
numbers[i] = numbers[indexSmallest];
numbers[indexSmallest] = temp;
}
return indexSmallest;
}
int main() {
int numbers[] = {10, 2, 78, 4, 45, 32, 7, 11, 0, 0, 0, 0, 0, 0, 0};
const int NUMBERS_SIZE = 15;
int i = 0;
int nums = 0;
int seed = 0;
cin >> nums;
cin >> seed;
srand(seed);
for (int i = 0; i < nums; i++) {
numbers[i] = (rand() % 20) + 20;
}
cout << "UNSORTED: ";
for (i = 0; i < nums; ++i) {
cout << numbers[i] << " ";
}
cout << endl;
selectionSort(numbers, nums);
cout << "SORTED: ";
for (i = 0; i < nums; ++i) {
cout << numbers[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
The only problem is that the random numbers being generated are the wrong numbers. For example, when I input "10 100" (10 for the numbers being used in the array and 100 for the seed), it outputs
UNSORTED: 25 36 35 24 24 34 38 22 29 29
SORTED: 22 24 24 25 29 29 34 35 36 38
when it should be outputting
UNSORTED: 28 28 34 37 36 27 33 36 36 39
SORTED: 27 28 28 33 34 36 36 36 37 39
I'm not really sure how to fix this.
There is a lot to say about this code:
The initial values put into the array numbers[] will of course be overwritten.
NUMBERS_SIZE is not used.
If you want to be able to specify the array length as input parameter, you should use a std::vector<>, or create the array dynamically, or at least check that the given number of values doesn't exceed the array size.
rand() is a random number generator, srand() sets some kind of seed for these random numbers. It is guaranteed that with the same seed you will always get the same sequence of random numbers.But, why/how do you expect to know the numbers that will be generated?
Indention.
Don't do using namespace std;
The answer to your question would be: Don't use random numbers.
You may try rand function
/* initialize random seed: */
srand (time(NULL));
/* generate random number betwee 1 and 10: */
iSecret = rand() % 10 + 1;
you need also to include 3 libraries
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */

Array of Pointers getting garbage value in c++

I'm trying to create an array of pointers to a 2D (5 X 12) array in C++.
The ptr array has 5 elements. Each element should hold the address of the 1st element of the respective row of the 2D array. So 1st element should point to 1st element of 1st row, 2nd element should point to 1st element of 2nd row, and so on.
The 5th element of my array of pointers seems to point to a garbage value.
Code and output shown below. Can anyone please let me know why?
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main( )
{
int rainMatrix[5][12] = {{0}}; //declare and initialize rain matrix
int *matrix_ptr[5] = {NULL};//declare and initialize array of pointers
int **matrix_ptr_ptr = matrix_ptr;
for (int i = 0; i < 5; ++i)
matrix_ptr[i] = &rainMatrix[i][0];
rainGen(matrix_ptr_ptr, 5, 12); //generate a random matrix
//display the matrix
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 12; ++j) {
cout << setw(2) << rainMatrix[i][j] << " ";
}
cout << endl;
}
for (int i = 0; i < 5; ++i)
cout << setw(2) << *matrix_ptr[i] << " " << rainMatrix[i][0] << endl;
return 0;
}
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
**pptr = rv;
*pptr += 1;
}
pptr++;
}
}
OUTPUT
11 1
88 11
28 88
25 28
1477892712 25
You're manipulating the wrong pointer in the innermost loop. Consider the pointer arithmetic carefully:
pptr essentially points to matrix_ptr[0];
on the first iteration, the double indirection means **pptr will set what you want, but then
*pptr += 1 will modify the contents of matrix_ptr[0], which means it no longer points to the beginning of the matrix.
Subsequent passes through the loop compound the situation drastically.
Modifying pptr won't help because it actually points to the wrong thing: it points to matrix_ptr, so incrementing it merely once moves its address from that of matrix_ptr[0], which points to rainMatrix[0][0], to that of matrix_ptr[1], which points to rainMatrix[1][0]. That is the wrong address for the next entry of the matrix, which is rainMatrix[0][1]. In essence, you've moved to the next row, instead of to the next column.
Try this for the innermost loop instead:
for (int i = 0; i < row; ++i)
{
auto qptr = *pptr;
for (int j = 0; j < col; ++j)
{
rv = rand() % 100;
*qptr = rv;
qptr += 1;
}
pptr++;
}
}
In this case, qptr is given the address of the first entry in the matrix. *qptr = rv sets the value. qptr += 1 increments the position of qptr while leaving *pptr alone - and, by extension, it leaves matrix_ptr[0] alone.
John Perry correctly identified the problem, but you have several option to deal with it. You are incorrectly incrementing *pptr += 1 Beyond using auto, you can simply index the pointer with the offset of j, e.g.
*(*pptr + j) = rv;
or
(*pptr)[j] = rv;
Either will work. Putting it together in your rainGen function, you could do:
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
// *(*pptr + j) = rv; /* or */
(*pptr)[j] = rv;
}
pptr++;
}
}
(note: seed and srand(seed) should be moved to main() if there is the potential that rainGen could be called more than once -- srand should only be called once)
Example Use/Output
Both will produce the desired output:
$ ./bin/raingen
72 71 65 94 0 13 49 17 36 49 67 51
87 68 45 15 91 72 16 80 77 35 9 81
11 88 73 59 24 22 37 48 45 54 94 45
19 44 62 56 45 81 59 32 49 4 99 92
28 16 24 5 3 34 38 14 22 12 26 98
72 72
87 87
11 11
19 19
28 28
You are modifying the pointers in the pointer-array matrix_ptr within your rainGen function, so that all of them point past the end and further accesses go to "random" memory locations, which is undefined behavior. Tools like valgrind can find such errors.

how to check a matrix for duplicate numbers C++

I'm trying to generate a 5x20 matrix filled with random numbers. How can I make sure none of the random numbers are duplicates? This is the code I have for filling the matrix with random numbers.
srand(time(0));
int matrix[5][20];
int i = 0;
int j = 0;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 20; j++)
{
matrix[i][j] = 1 + (rand() % 100);
cout << matrix[i][j] <<"_";
}
cout << endl;
}
the code works but there are sometimes duplicates. If this were an array I could make use of a simple for loop and compare all of the elements in the array. but I have no idea how to do so with a matrix. I have searched everywhere but cant seem to find a solution.
It's not quite fit your question title but I think you should take a look.
for (i = 0; i < 5; i++)
{
for (j = 0; j < 20; j++)
{
matrix[i][j] = 1 + (rand() % 100);
cout << matrix[i][j] <<"_";
}
cout << endl;
}
I don't know the 5x20 and 100 (in rand() % 100) is compulsory or just an example you want to give. So I suggest for all case I can consider:
Let call the number of matrix elements is a, the number of set (contains all possible generated number) is b. In your is example, a is 5x20=100 and b is 100 (from 1 to 100).
a > b: no valid matrix without duplicates since Dirichlet principle
a == b: take a look at http://en.cppreference.com/w/cpp/algorithm/random_shuffle. Just create an 1-dimension array containing consecutive number from 0 to b-1 (or from min and max of your range) and permute them. Then use it to fill in the matrix.
a < b: similar to case a==b, but you just take a part of the permutation.
Of course, when a =< b then you can use rand() but you have to check duplicate and retry rand(), which is quite complicated. You can create a mark array (which cost memory) or iterate through your matrix again (which cost time).
as a heads up, you shouldn't use rand() unless you've got explicit reasons to (such as a professor's requirements).
The following approach uses a GetIndex function to simulate an int[5][20] with an int[100]. See if you can figure out how to use the code I wrote to create an int[5][20].
Your code fills the matrix with random numbers between 1 and 100 (1 + (rand() % 100)) inclusively, but you do no work to ensure you don't get duplicates! So you won't be able to guarantee that you don't get duplicates (in fact, it's very unusual for you to get no duplicates).
If you first initialize all your values to 1,...,100 and then later shuffle them, you know you have no duplicates.
#include <iostream>
#include <iomanip>
#include <random>
#include <algorithm>
constexpr size_t kDefaultMatrixHeight = 20;
constexpr size_t kDefaultMatrixWidth = 5;
constexpr size_t GetIndex(size_t i, size_t j) {
return i * kDefaultMatrixWidth + j;
}
int main() {
int matrix[kDefaultMatrixWidth * kDefaultMatrixHeight];
for (size_t i = 0 ; i < kDefaultMatrixHeight * kDefaultMatrixWidth ; i++) {
matrix[i] = i + 1;
}
std::mt19937 rng(std::random_device{}());
std::shuffle(std::begin(matrix), std::end(matrix), rng);
for (size_t i = 0 ; i < kDefaultMatrixHeight ; i++) {
for (size_t j = 0; j < kDefaultMatrixWidth ; j++) {
std::cout << std::setw(4) << matrix[GetIndex(i,j)];
}
std::cout << '\n';
}
}
And for example output:
Test#Test:/tmp/example$ g++ example.cpp && ./a.out
93 28 70 14 39
83 3 80 95 58
42 69 71 16 49
75 63 41 82 46
26 50 81 33 97
65 10 77 68 12
8 19 30 86 37
57 24 78 31 88
2 90 4 13 56
36 15 35 32 85
29 76 99 45 18
54 11 44 62 98
9 96 79 34 27
40 21 52 22 55
72 1 47 92 59
94 7 64 91 53
74 5 61 100 89
48 23 66 67 51
38 6 87 17 20
60 25 84 43 73
not exactly answer your question but for your purpose you can try something like this:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
srand(time(0));
int matrix[5][20];
int *pmatrix = &matrix[0][0];
int i = 0;
for (i = 0; i < 100; i++)
{
pmatrix[i] = i+1;
}
std::random_shuffle(pmatrix, pmatrix+100);
for (i = 0; i < 100; i++)
{
std::cout<<pmatrix[i]<<",";
}
}
cpp.sh/5bnyt
Update fixed memory out of bounds problem.