Which solution is optimal? - c++

I have two solutions for this problem, but which is one is optimal?
A list of N numbers is given. The player has to arrange the numbers so that all the odd numbers of the list come after the even numbers. Write an algorithm to arrange the given list such that all the odd numbers of the list come after the even numbers.
Input
The first line of the input consists of an integer numbers, representing the size of the list(N).
The second line of the input consists of N space-separated integers representing the values of the list
Output
Print N space-separated integers such that all the odd numbers of the list come after the even numbers
Example
Sample Input
8
10 98 3 33 12 22 21 11
Sample Output
10 98 12 22 3 33 21 11
Solution no1-
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n];
for(int i=0; i<n; i++)
cin>>a[i];
int p1=0, p2= n-1;
while(p1 < p2){
while(a[p1]%2 == 0 and p1<p2)
p1++;
while(a[p2]%2 != 0 and p1<p2)
p2--;
if(p1 < p2){
swap(a[p1], a[p2]);
p1++;
p2--;
}
}
for(int i=0; i<n; i++)
cout<<a[i]<<" ";
return 0;
}
solution 2-
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
for(int i=0;i<n;i++){
if(arr[i]%2==0)
cout<<arr[i]<<" ";
}
for(int i=0;i<n;i++){
if(arr[i]%2!=0)
cout<<arr[i]<<" ";
}
return 0;
}

I would make a few changes, but mostly follow the second example.
First, I would put in an if-statement to ensure that n is a positive number. That's just a good check to do.
Next, I wouldn't output them quite like this. I'd build a second array instead.
int inputArray[n];
int finalArray[n];
int outputIndex = 0;
... Fill inputArray like you currently fill array
for (int i = 0; i < n; ++i) {
if (inputArray[i] % 2 == 0) {
outputArray[outputIndex++] = inputArray[i];
}
}
Do the second loop the same way. Then dump the outputArray.
Now, some other notes. These are stylistic, but will help you. Please use more whitespace in your code. Notice my code has spaces between operators. You're clearly young with young eyes, but good habits now will matter when you have to share code with old farts. Your scrunched-together code is really quite difficult to read and can readily hide errors. You wouldn't believe how many bugs are in code because some programmer was afraid of spaces.
Second, many programmers will tell you that optional braces shouldn't be treated as optional. Notice my if-statement has a pair of braces whereas yours don't. And if you look at how your code was formatted, you'll see that your indentation is wrong. You didn't indent your cout lines properly. This is a way errors hide. If you always use braces, evne when the language thinks they're optional, you'll have fewer bugs.
Lastly, most people will suggest you stop using fixed-length arrays and instead use vector, but as you're a new programmer, maybe you're not ready for that.

#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int* arr = new int[n];
int* odd = new int[n];
int* even = new int[n];
int oddIndex = 0;
int evenIndex = 0;
for(int i=0;i<n;i++){
cin>>arr[i];
}
for(int i=0;i<n;i++){
if(arr[i]%2==0)
even[evenIndex++] = arr[i];
else
odd[oddIndex++] = arr[i];
}
for(int i=0;i<evenIndex;i++){
cout<<even[i]<<" ";
}
for(int i=0;i<oddIndex;i++){
cout<<odd[i]<<" ";
}
return 0;
}

Related

C++- Filling a 2D array from user input

I'm new to programming and was finding transpose of a matrix.
However, I want the input of the matrix from the user and by writing the following code, the complier doesn't take any input values and immediately stops.
I looked into previous questions posted here about the same but found non useful.
#include<iostream>
using namespace std;
int main()
{
int rows,val;
int num[rows][rows];
cin>> rows;
for(int i=1; i<= rows; i++)
{
for(int j = 1; j <= rows; j++)
{
cin>> val;
arr[i][j]= val;
}
cout<<endl;
}
You can't use variables in array length if they aren't defined as one of the comments mentioned.
arr[i][j] inside your nested for loop isn't declared so that would also give an error, I guess you wanted to use num array which you declared.
The rest is all looking good

C++ : Longest Arithmetic Subarray

Given an input array, the output must be the length of the longest arithmetic subarray of the given array.
I am getting a different output other than the desired one. I don't understand where I went wrong, I'm still a beginner so please ignore the rookie mistakes and kindly help me out wherever I'm wrong. Thanks in advance.
Here's the code:
#include <iostream>
using namespace std;
int main () {
int n;
cin>>n;
int array[n];
for (int i=0;i<n;i++)
{
cin>>array[i];
}
int length = 2;
int cd = array[1] - array[0];
for(int i=2; i<n; i++){
if(array[i] - array[i-1] == cd){
length++;
}
else {
cd = array[i] - array[i-1];
length=2;
}
cout<<length<<" ";
}
return 0;
}
If you are looking for a subsequence then what you did would not accomplish that.
For example:
Input: nums = [9,4,7,2,10]
Output: 3
Explanation:
The longest arithmetic subsequence is [4,7,10].
You would require a nested loop structure (a for loop within the for loop you currently have) to accomplish that as you want to check a certain cd with the entire array and not just the next element.
If you require to find a subsequence/subarray given that the elements must be adjacent to one another then your program would work correctly.
Also a big error in your code is that you are printing the length inside the for loop. Unsure of whether that was for debugging purposes.
The problem here is you're resetting length after every update. You need a variable to store the maximum of every length.
#include <iostream>
using namespace std;
const int maxn = 1e6;
int arr[maxn];
int main ()
{
int n; cin>>n;
for (int i=0;i<n;i++) { cin >> arr[i]; }
int length = 2;
int maxLength = 2; //max variable
int cd = arr[1] - arr[0];
for(int i=2; i<n; i++){
if(arr[i] - arr[i-1] == cd) {length++;}
else {
cd = arr[i] - arr[i-1];
length=2;
}
//cout<<length<<" "; //remove this
maxLength = max(maxLength, length); //update maxLength
}
cout << maxLength;
}
A few more aesthetic notes:
array is a keyword in C++ used to declare std::array. Although the program may still run, it could create unnecessary confusion.
int array[n] is a VLAs (variable length array). It's not a C++ standard. It may or may not work depends on the compiler.
Why is "using namespace std;" considered bad practice?

Get array input and print the array (C++)

I am writing a code that takes an array of 10 and collects user input. I want to print out the array after the user has finished putting all the values into it. The problem is that when I printout the array it gives me a bunch of garbage values and a weird output. I am not sure why it is doing what it is doing.
This is my code:
#include <iostream>
#include<ctime>
using namespace std;
int main(){
int num;
int arr[10] = {0};
cout<<"Enter 10 numbers: "<< endl;
for(int i = 0; i < 10; i++){
cin>>arr[i];
}
for(int i = 0; i < sizeof(arr); i++){
cout<<arr[i]<< " ";
}
return 0;
}
That is because you are running the loop from 0 till sizeof(arr), here sizeof(arr) means the size of array in bytes. Which happens to be sizeof(int) times the number of elements in the array.
So if we consider sizeof(int) to be 4bytes(i.e. each int takes 4bytes in memory), and number of elements to be 10, then it would be 4*10 = 40. So the for loop would run for 40 times.
Instead do the following:
#include <iostream>
#include<ctime>
using namespace std;
int main(){
int num;
int arr[10];
cout<<"Enter 10 numbers: "<< endl;
for(int i = 0; i < (sizeof(arr)/sizeof(arr[0])); i++){
cin>>arr[i];
}
for(int i = 0; i < (sizeof(arr)/sizeof(arr[0])); i++){
cout<<arr[i]<< " ";
}
return 0;
}
As pointed out by #user4581301, it's better to make the loop stop taking input at (sizeof(arr)/sizeof(arr[0])), as the size can be changed laterwards.
I have corrected it. It will work now.
Why you are getting garbage values is very well explained in the other answers. You can use std::begin and std::end or range-based for-loop here for iterating through the array. C++ is smart enough to deduce the length of the array for you.
int main(){
int arr[10]{0};
/* Take inputs from the console and fill the array here. */
auto start = std::begin(arr);
auto end = std::end(arr);
for(; start!=end; ++start)
std::cout<<*start<<" ";
// Or using range-based for-loop
for(auto val: arr)
std::cout<<val<<" ";
}
sizeof(arr) is the total size in bytes of the array, not the number of elements. That's probably 40 rather than 10, Because the typical compiler targeting desktop PC hardware uses a 32 bit int at this time.
If your compiler's up to date and supports at least the C++17 Standard revision, use std::size to get the number of elements in the array, but a better option (supported back to C++11) is to use range-based for loops and let the compiler figure out the bounds for you. This makes changes to the count of elements in arr self-managing.
Eg:
for(auto & val:arr){
cin>>val;
}
for(auto & val:arr){
cout<<arr[i]<< " ";
}
If range-based for and std::size are not available, define and use a constant value everywhere you use 10 or sizeof(arr).
Eg:
const int ARR_SIZE = 10;
and then the definition of arr becomes
int arr[ARR_SIZE] = {0};
and the control for both for loops become
for(int i = 0; i < ARR_SIZE; i++)
This allows you to vary the size of arr with only one change required to make the code function correctly. This is also less cumbersome than repeating sizeof(arr)/sizeof(arr[0]) everywhere the number of elements in arr is needed.

use array to change every digit in a 3-digit number

#include<iostream>
using namespace std;
int main(){
int n,d1,d2,d3;
cout<<"Enter a 3-digit positive integer"<<endl;
cin>>n;
d1=n/100;
d2=n%100/10;
d3=n%10;
int a[3]{d1,d2,d3};
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
}
This code takes a 3-digit integer as input and returns a new number in which all non-zero digits in the original are replaced by the distance between the digit and 10, for example, if one of the digits is 2 so the new digit will be 10-2=8. But the problem is with the output.
I want the program to print (The new number is :(here the new digits in the same line)), instead of repeating the message and printing each digit in a separate line. How can I do that??
Thanks in advance.
This for loop,
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
Is the issue for your problem. This means that your printing The new number is : on every iteration. What we need to do is, print it once and print all the integers after it. Its very simple, just change the position of the std::cout to be before the for loop and we can put in a little optimization; we dont need to store the 10 - a[i], we can directly print it.
cout << "The new number is : ";
for (int i = 0; i < 3; ++i) {
if(a[i] != 0) {
std::cout << (10 - a[i]);
}
}
Bonus: Try not to use using namespace std; as its a bad practice. Basically what it does is, it takes the whole std namespace and dumps it into the global namespace. If its for competitive programming and time is limited, then it would be okay but for general programming, avoid it.
u can print the information out from the for loop or u can do for loop like this
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
if(i == 0)
cout<<"The new number is :";
cout <<a[i];
}
cout << endl

What is the missing step here to insert random numbers into the array (c++)?

I am trying to insert random numbers [1;100] into this array of 5 elements but so far I've been using only cin>> for inserting, when the user had to put something in. In this case I would like the random function to insert numbers, no user involved.
I show the code below because I am a beginner and the included pieces of codes are mostly what I can use and understand but on the other hand the whole code is useless because I don't know what is to connect with what. Where is rand()%100+1 to put?
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
int main()
{
srand(time(0));
int a[5];
int r=rand()%100+1;
for(int i=0; i<5; i++)
{
cout<<a[i]<<endl;
}
for(int i=0; i<5; i++)
{
cout<<a[i]<<endl;
}
return 0;
}
In your program you have 2 loops that both print out result. I suppose previously you had one loop that used cin to insert values, like this:
for(int i=0; i<5; i++)
{
cin<<a[i]<<endl;
}
So you want to change from inserting with ci to inserting random number:
for(int i=0; i<5; i++)
{
a[i] = rand()%100+1
}
In your code you are not initializing the values of the array elements using the rand() function.
Your rand function should go inside the first 'for' loop.Something like the following will do the trick.
for (int i = 0; i < 5; i++) {
a[i] = rand()%100+1;
}