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.
Related
#include <iostream>
long factorial(long n)
{
int x = 1;
for(int i = 2; i <= n; i++) x = x * i;
return x;
}
long nCr(long n, long r)
{
return factorial(n) / (factorial(r) * factorial(n - r));
}
int main()
{
int row;
std::cout << "Enter the number of rows: ";
std::cin >> row;
for (int n = 1; n <= row; n++)
{
for (int s = 1; s <= row - n; s++) std::cout << " "; //space
for (int r = 0; r != n; r++) std::cout << nCr(n-1, r) << " "; //numbers
std::cout << std::endl;
}
}
The code works perfectly fine when constructing a 13-row Pascal's Triangle(albeit a bit ugly), but for some reason it starts becoming inaccurate/wrong at the 14th row and prints this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 4 24 88 221 399 532 532 399 221 88 24 4 1
The purpose of Pascals Triangle is to avoid the calculation of big factorials. See, how many multiplactions you need to make. And by calculating the combinations, n choose k, you quickly come to situations, where build in datatypes overflow.
To tackle such problems, Pascals Triangle is the ideal solution. You can survive, by just summing up values. Row by row.
There are really many solutions for that. I show an example using 2 std::vectors. One holds the current row (the upper row) and the other the next row. For the next row, we can just add the values from the upper row. That is really simple.
Please see:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iomanip>
using ull = unsigned long long;
constexpr size_t NumberOfRows = 50U;
int main() {
std::vector<ull> current{ 1 };
std::vector<ull> next{};
current.reserve(NumberOfRows+2);next.reserve(NumberOfRows+3);
for (size_t i{}; i < NumberOfRows; ++i) {
// Next row has one element more
next.resize(current.size() + 1);
// Each row starts and ends with a 1
next.front() = 1; next.back() = 1;
// For the next row, sum up the upper to values from the current row
for (unsigned k{ 1 }; k < next.size() - 1; ++k)
next[k] = current[k - 1] + current[k];
// Debug Output
std::cout << std::setw(NumberOfRows - i + 2) << "";
std::copy(current.begin(), current.end(), std::ostream_iterator<ull>(std::cout, " "));
std::cout << '\n';
// Prepare next loop run. Assign the calculated row to current
current = std::move(next);
}
return 0;
}
When you calculate factorial(n) you are overflowing LONG_MAX. By doing an unsigned long you get more positive integers but this will only push the maximum rows a few more. If you know that your doing factorial division you can remove a lot of the large numbers by changing the logic.
ie: 13! /11! = (13 * 12 * 11 * 10 * 9....) / (11 * 10 * 9...)
can be simplified to (13* 12) which will remove the overflow
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This is my solution to the problem Codeforces-D2A-129 Cookies. The program outputs a wrong answer at testcase 11, which is:
82
43 44 96 33 23 42 33 66 53 87 8 90 43 91 40 88 51 18 48 62 59 10 22 20 54 6 13 63 2 56 31 52 98 42 54 32 26 77 9 24 33 91 16 30 39 34 78 82 73 90 12 15 67 76 30 18 44 86 84 98 65 54 100 79 28 34 40 56 11 43 72 35 86 59 89 40 30 33 7 19 44 15
My program:
#include <cstdio>
#include <algorithm> // for count() and sort()
#include <vector>
using namespace std;
// function prototype
void erase_duplicates(vector<int> &, int, int);
int main()
{
int num; // number of bags of cookies
int total = 0; // total number of cookies
int ways = 0; // number of ways Olga can take a bag of cookies
int duplicates = 0; // number of duplicates of an element
scanf("%i", &num); // getting number of bags of cookies
vector<int> cookies(num); // number of cookies in the ith bag
// getting number of cookies in each bag
for(int i = 0; i < num; i++)
scanf("%i", &cookies[i]);
for(int j = 0; j < num; j++) // calculating total number of cookies
total += cookies[j];
// sorting the input
sort(cookies.begin(), cookies.end());
for(int k = 0; k < cookies.size(); k++)
{
if((total - cookies[k]) % 2 == 0)
{
// adding number of duplicates of the current element to the number of ways
duplicates = count(cookies.begin(), cookies.end(), cookies[k]);
ways += duplicates;
// erasing the duplicates of that element
erase_duplicates(cookies, cookies[k], k);
}
}
//printing the possible number of ways
printf("%i", ways);
return 0;
}
// This function erases the duplicates of the element passed as the second argument.
// Parameters are: vector of integers, element, index of the element.
void erase_duplicates(vector<int> &cookies, int value, int k){
for(int i = k; i < cookies.size(); i++){
if(cookies[i] == value) // if it is a duplicate, remove it.
cookies.erase(cookies.begin() + i);
}
}
What's wrong with my code?
There is actually no need of sorting.
The problem can be solved as -
First sum all the array elements and find the number of even and odd elements.
Next if sum of array elements is odd then the bags having odd number of cookies can be stolen so answer would be the number of odd elements and if the sum is even then the answer is number of bags with even number of cookies.
Logic - Difference of two odd number is even
Difference of two even numbers is even
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
vector<int> num;
cin>>n;
num.resize(n);
int even=0,odd=0,sum=0;
for(int i=0;i<n;i++)
{
cin>>num[i];
sum+=num[i];
if(num[i]%2)
odd++;
else even++;
}
if(sum%2)
cout<<odd<<endl;
else cout<<even<<endl;
return 0;
}
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.
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.
This program is supposed to give to the last 100 digits of any size factorial. However, there's something weird going on with the counter2++ in main(). counter2 is incremented +1 for each time the loop runs in the main() function (which is 99 times). However this is what is displayed:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
71
86
90
123
164
196
207
254
300
362
432
471
551
620
630
708
761
772
857
896
985
1036
1100
1116
1207
1209
1280
1356
1417
1452
1512
Counter2 ends up being 1512 instead of 100, but if I remove either mult(i) or carry() from main() then it displays 100. Why does counter2 end up being 1512 and not 100?
#include <iostream>
using namespace std;
int numbers[100];
int counter2 = 0;
void init(){
//sets elements 1-99 of numbers[] to 0, increments counter2 by 1, sets numbers[0] = 1
for (int i = 1; i < 100; i++){
numbers[i] = 0;
}
numbers[0] = 1;
counter2++;
}
void mult(int x){
//multiplies each element by 1 through n to calculate for !n
//this is used to represent a very large number without using a BigInt library
//the nth element is a placeholder for the n+1 position of the number
//e.g 2nd element represents 100-900 of the number, 4th represents 1000-9000, etc
//carry() is used to take care of overflow, so that it's only 1 digit per element
for (int i = 0; i < 100; i++){
numbers[i] *= x;
}
}
void carry(){
//in order to make previous function work, this adds any overflow to the next
//element. e.g: 8 * 4 = 32, 3 is added to numbers[i+1], sets numbers[i] to 2
int counter = 0;
for (int i = 0; i < 100; i++){
if (numbers[i] >= 10){
counter = numbers[i] / 10;
numbers[i+1] += counter;
numbers[i] = numbers[i] % (counter * 10);
}
}
}
int main()
{
init();
for (int i = 2; i < 101; i++){
//calculates the last 100 digits of !100, but counter2 ends up being 1512
mult(i);
carry();
counter2++;
cout << counter2 << endl;
}
}
You are writing past the end of the numbers array in carry():
numbers[i+1] += counter;
Here, i can be 99, in which case numbers[i+1] is out of bounds.
Technically, this is undefined behaviour. What happens in practice is that you overwrite the count2 variable, which happens to sit in memory right after the array.
One nasty thing about memory bugs is that they can go symptomless for a long time, and then surface in the worst possible circumstances. valgrind is a great tool for detecting problems of this type.
In this line
numbers[i+1] += counter;
you are writing out of bounds of array numbers[100];when i == 99 thus changing the value of int counter2 = 0; which (in your case, but not necessarily) sits right next to numbers in memory.