C++ : Longest Arithmetic Subarray - c++

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?

Related

Make floor pattern

How do i make this?
image of my homework
note: Batasan means limitaion and Contoh means example
So, my professor wants me to do make output the same size horizontal and vertically in pattern shown in the image
I dont know what to do, but the best i can make is this:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
const char * array1[4];
const char * array2[4];
array1[0] = "O", array1[1] = ">", array1[2] = "X", array1[3] = "<";
array2[0] = "v", array2[1] = "/", array2[2] = "^", array2[3] = "\\";
cin>>n;
for(int i = 1; i <= n; i++){
if (i%2 != 0){
for(int j = 0; j <=n; j++){
cout << array1[j];
}
cout<<"\n";
} else if (i%2 != 0) {
for(int j = 0; j <=n; j++){
cout << array2[j];
}
cout<<"\n";
}
return 0;
}
}
I dont know if array is necessary or not.
If you guys have any suggestion about my program feel free to give me some.
This is my first time asking in this web and im sorry if my post and english are terrible
Thanks in advance:)
We are here to help.
I will first show you the problems in your code and then make a proposal on how to make it better.
So, let us first check your code:
#include<bits/stdc++.h> is a non C++ compliant compiler extension. It should never be used. On my machine, it does not compile.
using namespace std; should not be used. It is better to always use full qualified names. This will avoid name clashes from different scopes or namespaces
Variables should have meaningful names. One character variables are in most cases not that good
All variables should be initialized during definition
C-Style arrays should not be used in C++. Always use a specialized STL container like std::vector or std::array
In C++ we use std::string for strings and not char[] or char *
Array indices in C/C++ start with 0. If you use <= in the end condition of a for loop, you will access an element one past the end. This is a severe out of bound error. You do that in you for loop with the 'j'
There is anyway a severe out of bound bug here. You access array[j] and j might be 4 or bigger. That is a bug and must be corrected. You can simply do a modulo devision % by 4. Then you do never exceed the 4. it will then always be 0,1,2,3,0,1,2,3,0,1,2,3 . . .
You should write as much as possible comments
If we correct all this findings, then we could come up with:
#include <array>
#include <iostream>
constexpr size_t NumberOfLinePatterns = 2;
constexpr size_t NumberOfElementsPerLinePattern = 4;
using Pattern = std::array<std::array<char, NumberOfElementsPerLinePattern>, NumberOfLinePatterns>;
// If you do not yet know the std::array. Then uncomment the following and
// remove on opening and closing curly brace in the initialization below
// using Pattern = char[NumberOfLinePatterns][NumberOfElementsPerLinePattern];
Pattern pattern{{
{'O','>','X','<'},
{'v','/','^','\\'}
}};
int main() {
// Get number of rows and columns to print
unsigned int numberOfElements{}; std::cin >> numberOfElements;
// Now, for all rows and columns
for (unsigned int row{}; row < numberOfElements; ++row) {
for (unsigned int column{}; column < numberOfElements; ++column) {
// Print the selected character
std::cout << pattern[row % NumberOfLinePatterns][column % NumberOfElementsPerLinePattern];
}
std::cout << '\n';
}
return 0;
}

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.

getting no result in terminal window

I have just started coding in C++ and I am using codeblocks. My build log is giving me 0 errors and 0 warning but I do not know why when I run it, it is giving me no result in the terminal.
Terminal Window Result:
Process returned -1073741571 (0xC00000FD) execution time : 1.252 s
Press any key to continue.
my code:
#include <iostream>
#include<math.h>
using namespace std;
int main() {
int n;
cin>>n;
int a[n];
for(int i = 0; i <n ; i++){
cin>>a[i];
}
const int N = pow(10, 6);
int idx[N];
for(int i = 0; i< N; i++){
idx[i] = -1;
}
int minidx = INT_MAX;
for(int i = 0; i<n; i++){
if(idx[a[i]] != -1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]] = i;
}
}
if (minidx == INT_MAX){
cout<<"-1"<<endl;
}
else{
cout<<minidx+1<<endl;
}
return 0;
}
Please help me in finding my mistake in the code.
This:
int n;
std::cin >> n;
int a [n];
for (int i = 0; i < n ; i++) {
std::cin >> a [i];
}
is bad practice. Don't use VLAs whose size you don't know at compile time. Instead, if I guess correctly that this is some Competitive Programming problem, you'll probably know what the max size will be as stated in the problem. So, do it this way instead:
int n;
std::cin >> n;
constexpr int max_size = 1000000;
int a [max_size];
for (int i = 0; i < n; i++) {
std::cin >> a [i];
}
However, even doing it this way will crash your program anyway. This is simply because of stack overflow when you declare an array that size inside a function. For slightly smaller sizes however, that would be okay. Just don't use VLAs the way you're using them.
One solution is to use a standard container like std::vector as the allocation takes place on the heap. Note that using std::array will crash too as the allocation is not on the heap.
Another solution is to make your array a global. This way you can increase to sizes well over 1e6. Not really recommended though.
In your code above, irrespective of what the size n for array a is (even if it's a fairly small size to fit on the stack), your code will definitely crash when you declare the array idx [1000000]. Reason is the same, stack overflow.
Also, please post indented code and use good indentation practices.

Stack Overflow Error From Recursive Function

#include<iostream>
#include<string>
#include<sstream>
#include<conio.h>
#include<vector>
#define MAX 100
using namespace std;
int size;
int getlargest(int arr[ ]){
static int max = -1000;
static int i = 0;
if(i < size){
if(arr[i] >= max){
max = arr[i];
i++;
}
getlargest(arr);
}
return max;
}
int main(){
int res;
cout << "enter the size please: ";
cin >> size;
int arr[MAX];
for(int i=0;i<size;i++){
cin >> arr[i];
}
res = getlargest(arr);
cout << res;
getch();
return 0;
}
I am not experienced with the concept of recursive functions. This code was written to find the maximum element of an array. However, I am getting a stack overflow error. Could anyone correct it? Also, I don't know exactly where to insert recursion.
You have several problems, all of them small.
First, you make no progression through the array: you always call with the same argument, that being the entire array. The strategy of recursion is to do something simple, and then reduce the problem to something smaller when you call again.
In this case, you have the concept right: check one element against the largest of the rest of the list. You do recur to find the maximum, but you don't reduce the list. You also don't actually work well with the list max. For instance, note that (on each call) you're returning the max to the previous level ... but you don't save it at all.
Try this instead:
take the first element off the list;
find the max of the remainder;
return the larger of those two.
The code might look like this:
if(arr.size() == 1) {
return arr[0]
else {
max = getlargest(++arr);
if (arr[0] >= max)
max = arr[0]
}
return max;
Note the little C trick here: ++arr increments arr, as an array reference, to the next element. You may have seen this already as a character pointer and string variable.
Well, it seems you're trying to do something that is easier to do with a loop than recursion. You can implement getlargest() like this:
int getlargest(int arr[]) {
int max = arr[0]; // This is safer than initializing max with 0. What if arr[0] is the largest element and all elements are below 0?
for (int i = 0; i < size; ++i)
if (arr[i] > max)
max = arr[i];
return max;
}
I am not experienced with the concept of recursive functions.
Assuming you want to learn how to use recursion, you should take a look at factorial. It's a no-brainer to find the factorial of an integer i using a recursive function.

Why do I get random numbers after the input?

I'm trying to take in some input and find the number of a certain character in a string. I keep getting a weird answer when I try to take in the actual string. Why is this happening?
I'm using cout to find why I'm getting such weird numbers and it appears to be a problem with the input.
Note - This is my attempted solution to Codeforces Problem 462 B. I'm attempting to just find the number of a certain letter in the input. My friend is attempting a bubble sort method.
Input:
6 4
YJSNPI
Expected Output:
YJSNPI
4
Actual Output:
YJSNPI
1699623981
Code:
#include <iostream>
#include <string>
#include <vector>
#include <istream>
using namespace std;
int main()
{
int n, k, counting;
cin >> n >>k;
char trash;
cin.get(trash);
vector<string> cards;
string theline, name;
cin >> theline;
cout << theline << "\n";
for (int i = 0; i < n; i++){
name = theline[i];
cards.push_back(name);
}
for (int i = 0; i < n; i++){
if (cards[i] == cards[k-1]){
counting++;
}
}
int tmp = 0;
if (cards.size() != k){
tmp = k - counting;
}
counting *= k;
counting += tmp;
cout << counting;
return 0;
}
Local variables are not automatically initialized to 0. If you try to use the value of a local variable before assigning it, you get undefined behavior. You're incrementing counting without ever initializing it. Change to:
int n, k, counting = 0;
The issue is that the variable "counting" is never initialized - handy link
Basically, "counting" has some garbage value from memory after you declare it with
int counting;
Then, the first operation performed is
counting++;
And the garbage value is saved.
THE FIX:
Change
int counting;
to
int counting = 0;
NOTE: n and k are not helpful variable names. It would make understanding the code a lot easier if they had real names, but oh well.
ADDITIONALLY:
As chris mentioned above, make the compiler work for you. See comment below for good compiler flags. Don't ignore warnings!
Can't really understand what you are doing here. But I can see where you are going wrong.
int n, k, counting;
counting is uninitialized try
int n, k, counting = 0;
I get answer of (1*4 + 4 - 1) = 7 not the 4 you are expecting.
This code will always result in counting = 1, given that k is within range.
for (int i = 0; i < n; i++){
if (cards[i] == cards[k-1]){
counting++;
}
}
https://ideone.com/7Hk3ix