Memset with assignment - c++

I have a problem : "Multiple test (t test), each test prints all strings with length N and contains exactly H numbers 1."
Here is my code:
#include <iostream>
#include <memory.h>
using namespace std;
typedef long long LL;
LL t,N,H;
LL arr[1000];
bool used[1000];
LL num = 0;
void show(){
LL number = 0;
for (LL u = 0; u<1000; u++)
{
if (arr[u]==2)
{
number++;
}
}
if (number==H)
{
for (LL v = 0; v<1000; v++)
{
if (arr[v])
{
cout << arr[v] - 1;
}
}
cout << "\n";
}
}
void backtrack (LL pos){
if (pos==N+1)
{
num = 0;
show();
return;
}
if (!used[pos])
{
for (LL j = 1; j<=2; j++)
{
if (j==2)
{
if (num==H)
{
break;
}
else
{
num++;
}
}
arr[pos] = j;
used[pos] = true;
backtrack(pos+1);
used[pos] = false;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin >> t;
for (LL i = 0; i<t; i++)
{
cin >> N >> H;
//memset(arr, sizeof(arr), 0);
for (LL cv = 0; cv<1000; cv++)
{
arr[cv] = 0;
}
backtrack(1);
if (i<t-1)
{
cout << "\n";
}
}
return 0;
}
I had trouble with using "memset(arr, sizeof(arr), 0);" - it returned wrong answer. But with the same test, when I used for-loop to assign all elements in array "arr" equal to 0, it returned correct answer.
My test is:
2
4 2
3 1
I am asking to know the difference between memset and for-loop (using for assignment). Thanks.

memset takes three arguments.The first is the pointer to the block of memory to fill (your arr), the second is the value to set, and the third the number of bytes to fill. Here's the documentation for memset, if you want to go deeper.
In your code I read
memset(arr, sizeof(arr), 0)
That reads as "fill 0 bytes with the value of sizeof". You've only given the wrong arguments, it sould be:
memset(arr, 0, sizeof(arr))

memset's second argument should be value and third is size. Use this:
memset(arr, 0, sizeof(arr) );
See this for details.

Related

Breaking out of loop from function after printing the last prime number of a given range

I'm writing a code to find the last prime number of a given range. Suppose the range is 1 to 50. Then the last prime no. I want to print must be 47. My idea was to maybe reverse the order of prime numbers in the range and then try printing only the first value. Again kinda like if my order was 1 to 50 then I would start printing from 47, 43 and so on and only print 47. But I'm stuck and not getting ideas on how I could do this. here's my code
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
You can just use exit() in the place you want to end the program, and it works fine in your case. But by far the best approach is returning a value to test for continuation, it is the most readable.
#include<iostream>
#include <stdlib.h>
using namespace std;
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
exit(0);
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
Same code using bool return type:
#include<iostream>
using namespace std;
bool prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
return true;
}
return false;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
if(prime_bef(i))
break;
}
return 0;
}
Here is a simple and efficient way to check if the number is prime. I am checking if the number is prime and when it is true I am printing the number and breaking the loop so that only 1 number is printed. You can always remove the break statement and print all prime numbers in range.
#include<iostream>
using namespace std;
bool isPrime(int n){
if(n==2)return true;
if(n%2==0 || n==1)return false;
for(int i=3; i*i<=n; ++i){
if(n%i==0){
return false;
}
}
return true;
}
int main (){
int l, u;
cin>>l>>u;
for (int i = u; i >= l; i--){
if(isPrime(i)){
cout<<i<<"\n";
break;
}
}
return 0;
}
I'll give you a hint... while you are iteratively checking for the prime nature of the number, also check whether the last prime number calculated in the loop is greater than the max term of the range and break the loop when the condition becomes false.
Here a C++17 approach :
#include <cmath>
#include <iostream>
#include <vector>
// type to use for storing primes
using prime_t = unsigned long;
// there is a way to determine an upper bound to the number of primes smaller then a maximum number.
// See : https://primes.utm.edu/howmany.html
// this can be used to estimate the size of the output buffer (vector)
prime_t pi_n(const prime_t max)
{
prime_t pi_n{ max };
if (max > 10)
{
auto ln_n = std::log(static_cast<double>(max));
auto value = static_cast<double>(max) / (ln_n - 1.0);
pi_n = static_cast<prime_t>(value + 0.5);
}
return pi_n;
}
// Calculate prime numbers smaller then max
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
auto calculate_primes(const prime_t max)
{
std::vector<bool> is_primes(max, true);
// 0, 1 are not primes
is_primes[0] = false;
is_primes[1] = false;
// sieve
for (prime_t n = prime_t{ 2 }; n < prime_t{ max }; ++n)
{
if (is_primes[n])
{
auto n2 = n * n;
for (prime_t m = n2; m < max; m += n)
{
is_primes[m] = false;
}
}
}
// avoid unnecessary resizes of vector by pre-allocating enough entries to hold result
prime_t n{ 0 };
std::vector<prime_t> primes;
primes.reserve(pi_n(max));
// add all prime numbers found by the sieve
for (const auto is_prime : is_primes)
{
if (is_prime) primes.push_back(n);
n++;
}
return primes;
}
int main()
{
const prime_t max{ 50 };
auto primes = calculate_primes(max);
// max prime is last one in container
auto max_prime = primes.back();
std::cout << "maximum prime number smaller then " << max << ", is " << max_prime << std::endl;
}

Unable to find the error in the code I wrote for a question on loops in C++. Could anyone point it out?

a beginner at coding here.
I was practising loops(c++) when I stumbled upon this problem:-
Write a program in C++ to find the perfect numbers between 1 and 500. (6,28 and 496)
Perfect number: It is a positive integer that is equal to the sum of its proper divisors. The smallest perfect number is 6, which is the sum of 1, 2, and 3.
I wrote the following code:-
#include <iostream>
using namespace std;
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
}
return 0;
}
The code is supposed to print that 6, 28 and 496 are perfect numbers.
But instead, it's not printing anything. Haven't been able to find the error yet after checking for 30+ minutes.
Could anyone point out the error?
You forget to re-initialize some variables in your loop.
for seems more appropriate than while here.
Create sub function also help to "identify" scope.
#include <iostream>
bool isPerfectNumber(int n)
{
int sum = 0;
for (int div = 1; div != n; ++div) {
if (n % div == 0) {
sum += div;
}
}
return sum == n && n > 0;
}
int main()
{
for (int i = 2; i != 501; ++i) {
if (isPerfectNumber(i)) {
std::cout << n << " is a perfect number." << std::endl;
}
}
return 0;
}
#include<iostream>
using namespace std;
bool perfect_num(int x);
int main() {
int m, n, x;
cout << "input the range m, n: " << "\n";
cin >> m >> n;
for (x = m; x <= n; ++x) {
if (perfect_num(x)) {
cout << x << " ";
}
}
return 0;
}
bool perfect_num(int x) {
bool flag = false;
//initialize
int sum = 0, i;
//loop 1 to x
for (i = 1; i < x; ++i) {
//judge whether is the factor
if (x % i == 0) {
sum += i;
}
}
//update flag
flag = (sum == x);
return flag;
}
#include<iostream>
using namespace std;
//judge function
bool isPerfectNum(int num){
int tmp = 0;
for (int i = 1; i < num; ++i) {
if (num % i == 0) {
tmp += i;
}
}
return tmp == num;
}
int main(){
cout << "Perfect Number contains: ";
for (int i = 1; i <= 500; ++i){
if (isPerfectNum(i)) {
cout << i << " ";
}
}
cout << "\n";
return 0;
}
at the end of your first loop, you should bring back div and sum to their default value.
int main() {
int n=2; //test numbers from 2 to 500.
int div=1; //divisor for n.
int sum=0; //sum of divisors which divide n.
while (n<=500) {
while (div<n){ //if div divides n, then it will added to sum and incremented, else only incremented.
if (n%div==0){
sum=sum+div;
div++;
} else{
div++;
}
}
if (sum==n){
cout<<n<<" is a perfect number."<<endl;
n++;
} else{
n++;
}
div = 1; // you should bring them back here.
sum = 0;
}
return 0;
}

Why am I not able to push a pair after a limit in the vector?

The problem is to find if a given sequence of numbers can form a valid permutation or not. The problem statement is trivial for the real problem. So, I am pushing a pair of integers into the vector. The first part being the number itself and second being 0 or 1.
The code works fine till a sequence 1041 long (specific after debugging a lot). Just to debug I added a print statement after pushing each pair inside the vector. For a length of 1042, the code shows pushed 1040 and then pushed 1 (which is weird) and then just hangs on there.
I am attaching the code as well as the input and terminal output.
You can just check the main function
Code
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std;
bool comparator_function(pair<int, int> a, pair<int, int> b) {
return (a.first < b.first);
}
//index_added -> the index at which the latest element was added
void set_r_array(int* r_array_ref, int* per_array_ref, int size, int* count, int index_added) {
for(int i = 1;i <= size; i++) {
count[i] = 0;
}
int temp = index_added;
while(index_added <= size) {
if(index_added == size) {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = size;
break;
}
else {
r_array_ref[temp] = -1;
break;
}
}
else {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = index_added;
break;
}
else {
index_added++;
}
}
}
for(int i = 1;i <= size; i++) {
if(r_array_ref[i] != -1) {
count[r_array_ref[i]]++;
}
}
}
bool check_max(int* count, int next_element, int size) {
int max_count = -1, index = 0;
for(int i = 1;i <= size; i++) {
int temp_val = count[i];
if(max_count <= temp_val) {
max_count = temp_val;
index = i;
}
}
int num = 0;
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
num++;
}
}
//one max
if(num == 1) {
if(next_element == index) {
return true;
}
return false;
}
else {
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
if(next_element == i) {
return true;
}
}
}
return false;
}
}
int main() {
int testCases;
cin >> testCases;
cin.ignore();
while(testCases-- > 0) {
int n, result_flag = 0;
cin >> n;
cin.ignore();
vector<pair<int, int>> per;
int temp;
for(int i = 0;i < n; i++) {
cin >> temp;
pair<int, int> temp_pair = make_pair(temp, i+1);
per.push_back(temp_pair);
//debug statement
cout << "pushed " << temp << endl;
}
auto start = std::chrono::high_resolution_clock::now();
cout << "start" << endl;
sort(per.begin(), per.end(), comparator_function);
int permutation_array[n+1], r_array[n+1], count[n+1];
for(int i = 0;i <= n; i++) {
permutation_array[i] = 0;
r_array[i] = i;
count[i] = 1;
}
cout << "end" << endl;
permutation_array[per[0].second] = per[0].first;
set_r_array(r_array, permutation_array, n, count, per[0].second);
//insertion of numbers
for(int i = 1;i < n; i++) {
//check if the next element inserted has the largest count rn or not
int next_element = per[i].second;
if(!check_max(count, next_element, n)) {
cout << "No" << endl;
result_flag = -1;
break;
}
permutation_array[per[i].second] = per[i].first;
set_r_array(r_array, permutation_array, n, count, per[i].second);
}
if(result_flag == 0) {
cout << "Yes" << endl;
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
cout << "Time: " << duration.count() << " microseconds" << endl;
}
}
Input 1
1
5
2 3 4 5 1
Output 1
pushed 2
pushed 3
pushed 4
pushed 5
pushed 1
start
end
Yes
Input 2
1
1042
1 2 3 4 ... so on till 1042
Output 2
pushed 1
pushed 2
.
.
.
pushed 1040
pushed 1
and then hangs, from here on
The complexity of the code is O(n^2). So, I don't think it has to do anything with that. Since the input can be at max 10^4 order. Moreover, according to the print debugging, I think the issue is with the input.
You have issue with input as you reach console line limit.
Put your input into a file should solve that issue.
Then you should be able to debug your algorithm which seems more complicated than needed.

C++ Recursion to detect duplicates in row and column of grid

I'm coding a recursive algorithm to take a user input N and make a N x N grid where the same number does not appear twice on either a row or a column. Almost everything's working, and duplicates don't appear in columns, but I'm having trouble getting rows working.
My code for checking duplicates in rows is the function noRowDuplicates. Duplicates are still appearing, and occasionally it'll throw a segmentation fault, but I'm not sure why.
Thanks in advance for the help!
// Author: Eric Benjamin
// This problem was solved using recursion. fill() is the recursive function.
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
void fillOptions();
void fill(int arrayPosition);
int inputNum;
int gridSize;
int *grid;
int allOptionsSize = 0;
int *allOptions;
int main() {
cout << "Please enter a number!" << endl;
cin >> inputNum;
gridSize = inputNum * inputNum;
grid = new int[gridSize];
allOptions = new int[inputNum];
for (int i = 0; i < inputNum; i++) {
allOptions[i] = i + 1;
allOptionsSize++;
}
srand((unsigned)time(0));
fill(0);
delete[] grid;
delete[] allOptions;
return 0;
}
bool noColumnDuplicates(int arrPosition, int valueToCheck) {
for (int i = 1; i < inputNum; i++) {
if (arrPosition - (inputNum * i) >= 0) {
if (grid[arrPosition - (inputNum * i)] == valueToCheck) {
return false;
}
}
}
return true;
}
bool noRowDuplicates(int arrPosition, int valueToCheck) {
int rowPosition = arrPosition % inputNum; // 0 to num - 1
if (rowPosition > 0) {
for (int p = 1; p < rowPosition; p++) {
if (grid[arrPosition - p] == valueToCheck) {
return false;
}
}
}
return true;
}
void fill(int arrayPosition) {
if (arrayPosition < gridSize) {
int randomPosition = rand() % allOptionsSize;
grid[arrayPosition] = allOptions[randomPosition];
if (noColumnDuplicates(arrayPosition, grid[arrayPosition])) {
if (noRowDuplicates(arrayPosition, grid[arrayPosition])) {
if (arrayPosition % inputNum == 0) {
cout << endl;
}
cout << grid[arrayPosition] << " ";
fill(arrayPosition + 1);
} else {
fill (arrayPosition);
}
} else {
fill(arrayPosition);
}
}
}
noRowDuplicates never tests the first element of a row, which makes sense when you are trying to fill the first element of a row, but not any other time.

My code stops at a certain condition

In this code I input a test case number t and then input t numbers (n). Then my code prints the nth prime number. In the 1st line of the function, prime(), if I write if(a > 43000) return; Then the code works perfectly. But if I write if(a >= 165000) return; in the same place, codeblocks says the program has stopped working. But I can't understand why.
#include <iostream>
#include <cmath>
using namespace std;
int p[15000];
void prime(int a, int i)
{
if(a >= 165000) return;
else {
int q = 0;
int s=sqrt(a), d=3;
while(d<=s){
if(a % d == 0) {
q = 1;
}
d += 2;
}
if(q == 0) {
p[i] = a;
i++;
a += 2;
prime(a, i);
}
else {
a += 2;
prime(a, i);
}
}
}
int main()
{
p[0]=2;
prime(3, 1);
int k, T;
cin >> T;
for(int i = 1; i <= T; i++){
cin >> k;
cout << p[k - 1] << endl;
}
return 0;
}
First, I'll point out that your array p has only 15000 elements and that the 15001-th prime number is 163,847. This means that if you do a check for a >= 165000 before quiting you'll end up trying to fill indices of your array that are outside the bounds of your array.
Second, everyone is quite right that you should be careful when doing recursion. With each run of prime() you're allocating space for 5 new integer variables a, i, q, s, and d. This means you're allocating memory for tens of thousands of integers when (from the looks of your method) all you really need is 5.
Since it looks like these values are independent of all other iterations, you can employ a couple tricks. First, for q, s, and d by declaring them as globals they will only be allocated once. Secondly, by changing prime(int a, int i) to prime(int &a, int &i) you wont be allocating memory for a and i with each loop. This changes your code to look like the following:
#include <iostream>
#include <cmath>
using namespace std;
const int max_size = 15000 ;
int p[max_size];
int q ;
int s ;
int d ;
void prime(int &a, int &i)
{
if (i>=max_size) return ;
q = 0;
s=sqrt(a) ;
d=3;
while(d<=s){
if(a % d == 0) {
q = 1;
}
d += 2;
}
if(q == 0) {
p[i] = a;
i++;
a += 2;
prime(a, i);
}
else {
a += 2;
prime(a, i);
}
}
int main()
{
p[0]=2;
int a(3), i(1) ;
prime(a, i);
int k, T;
cin >> T;
for(int i = 1; i <= T; i++){
cin >> k;
// You should do a check of whether k is larger than
// the size of your array, otherwise the check on p[k-1]
// will cause a seg fault.
if (k>max_size) {
std::cout << "That value is too large, try a number <= " << max_size << "." << std::endl;
} else {
cout << p[k - 1] << endl;
}
}
return 0;
}
A couple of other changes:
instead of filling the array until you reach a specific prime number, I've changed your check so that it will fill the array until it hits the maximum number of entries.
I've also included a check as to whether the user has passed an index number outside the range of the "p" array. Otherwise it will produce a segmentation fault.
Now compiling this and running gives:
$ g++ prime_calc.cpp -o prime_calc
$ ./prime_calc
3
1500
12553
15000
163841
15001
That value is too large, try a number <= 15000.