I have this function that should take a matrix, compare the diagonal elements of the matrix and find the smallest one.
Here it should compare y[0][1] and y[1][0].
#include <iostream>
int Min(int, int [][2]);
using namespace std;
int main() {
int min, y[2][2];
y[0][0]=5;
y[0][1]=4;
y[1][0]=-9;
y[1][1]=0;
min = Min(2, y);
cout<<min;
return 0;
}
int Min(int k, int x[][2]){
int min=x[0][0];
for(int i=0; i<k;i++){
if(x[i][i]<min){
min=x[i][i];
}
}
return min;
}
It always returns 0. Why?
Here it should compare y[0][1] and y[1][0].
Your function goes through the diagonal of the matrix, it hence checks y[0][0] and y[1][1]. They are 5 and 0. The result is zero, which is to be expected.
Here it should compare y[0][1] and y[1][0].
But that's not what you say here:
int min=x[0][0];
or here:
if(x[i][i]<min){
min=x[i][i];
}
Since i cannot be both 0 and 1 at the same time, this accesses x[0][0] and x[1][1].
And for those elements, 0 is the correct minimum.
As a side note, your Min function can only work with matrices of size 2, so the k parameter is unnecessary. Multi-dimensional arrays are annoying like that.
To iterate over all items instead of just [0][0] and [1][1] you need to do:
for(int i=0; i<k; i++)
{
for(int j=0; j<k; j++)
{
if(x[i][j]<min)
{
min=x[i][j];
}
}
}
int Min(int k,const int x[][2])
{
int min=x[0][0];
for(int i=0; i<k;i++)
{
for(int j=0;j<k;j++)
{
if(x[i][j]<min)
{
min=x[i][j];
}
}
}
Earlier it was always showing zero because it had a mess with the column index. Outer for loop iterates k-1 times with first iteration at i=0, and second at i=1 and during both iterations it assigns the same index to both row and column(i.e., x [0][0] and x[1][1]). Perhaps it must assign the index x[0][0], x[0][1], x[1][0], x[1][1]. Earlier, it had only two iterations(the outer for loop) but now it takes four iterations assigning the appropriate index to both column and rows the efficient number of times.
Related
I am learning DSA and while practising my LeetCode questions I came across a question-( https://leetcode.com/problems/find-pivot-index/).
Whenever I use vector prefix(size), I am greeted with errors, but when I do not add the size, the program runs fine.
Below is the code with the size:
class Solution {
public:
int pivotIndex(vector<int>& nums) {
//prefix[] stores the prefix sum of nums[]
vector<int> prefix(nums.size());
int sum2=0;
int l=nums.size();
//Prefix sum of nums in prefix:
for(int i=0;i<l;i++){
sum2=sum2+nums[i];
prefix.push_back(sum2);
}
//Total stores the total sum of the vector given
int total=prefix[l-1];
for(int i=0; i<l;i++)
{
if((prefix[i]-nums[i])==(total-prefix[i]))
{
return i;
}
}
return -1;
}
};
I would really appreciate if someone could explain this to me.
Thanks!
You create prefix to be the same size as nums and then you push_back the same number of elments. prefix will therefore be twice the size of nums after the first loop. You never access the elements you've push_backed in the second loop so the algorithm is broken.
I suggest that you simplify your algorithm. Keep a running sum for the left and the right side. Add to the left and remove from the right as you loop.
Example:
#include <numeric>
#include <vector>
int pivotIndex(const std::vector<int>& nums) {
int lsum = 0;
int rsum = std::accumulate(nums.begin(), nums.end(), 0);
for(int idx = 0; idx < nums.size(); ++idx) {
rsum -= nums[idx]; // remove from the right
if(lsum == rsum) return idx;
lsum += nums[idx]; // add to the left
}
return -1;
}
If you use vector constructor with the integer parameter, you get vector with nums.size() elements initialized by default value. You should use indexing to set the elements:
...
for(int i = 0; i < l; ++i){
sum2 = sum2 + nums[i];
prefix[i] = sum2;
}
...
If you want to use push_back method, you should create a zero size vector. Use the constructor without parameters. You can use reserve method to allocate memory before adding new elements to the vector.
I need to solve a c++ problem but something doesn't work and i don't know why.
N numbers are given, divided in k sequences. I need to find out which sequences are equal, knowing that k divides n.
is the problem with some values as an example:
Here is the problem with some values as an example. (it's in romanian)
I tried something like this:
#include <bits/stdc++.h>
using namespace std;
bool compare(int a[], int b[], int n)
{
for(int i=1;i<=n;i++)
if(a[i]!=b[i])
return false;
return true;
}
int main()
{
int n, k;
int i, j, secv;
cin>>n>>k;
int flag=1, v[n];
for(i=1;i<=n;i++)
cin>>v[i];
secv=n/k;
for(i=1;i<k && flag==1;i++)
for(j=i+1; j<=k && flag==1; j++)
if(compare(v+i*secv, v+j*secv, secv)==true)
{
cout<<i<<" "<<j;
flag=0;
}
if(flag==1) cout<<"NU";
return 0;
}
If your array is of size k and you are iterating the first element at index 1 then there are two problems:
Your array will only be able to save k-1 elements because in memory an array's first element is at index 0.
Some of the default array functions like begin and size will include 0 index so it might produce unexpected results.
How an array is saved in memeory
An array name is just a placeholder to the continuous memory reference. So if you's starting your array with 1 then you're skipping through the first index.
The best practice is to start an array with index 0.
I need to find the lowest value in an array that isn't in the main diagonal, I have written some code but it seems to pick either the second or the last value only (depending on which one is the lowest).
here is my code:
#include<iostream>
using namespace std;
int main()
{
int arr[4][2];
int Min,i,j;
cout<<"Type 8 numbers";
for (i=0;i<4;i++)
{
for (j=0;j<2;j++)
{
cin>>arr[i][j];
Min=arr[0][1];
if(i!=j and Min > arr[i][j])
{
Min=arr[i][j];
}
}
}
cout<<"The values of the array are: \n";
for (i=0;i<4;i++)
{
cout<<"\n";
for (j=0;j<2;j++)
{
cout<<arr[i][j]<<"\t";
}
}
cout<<"The lowest value is: "<<Min;
}
If I type 1-8 the returned value is 2, if I type 8-1 the returned Value is 1, in both of these cases the code is working as I intended, but if I type something like 8,6,4,1,2,3,4,5, the lowest value is returned as 5, I'm very new to coding and would appreciate any help.
The line
Min=arr[0][1];
is bad because
It reads uninitialized arr[0][1] when i = 0, j = 0.
It writes arr[0][1] to Min unconditionally, even if current Min is smaller than that.
Instead of this:
Min=arr[0][1];
if(i!=j and Min > arr[i][j])
{
Min=arr[i][j];
}
This will work, for example:
if(i!=j and ((i==0 and j==1) or Min > arr[i][j]))
{
Min=arr[i][j];
}
Your Min=arr[0][1] line is inside both loops, which means each time when you are trying to compare Min and the current element arr[i][j], you just threw away whatever smallest value stored in Min and replaced it with arr[0][1].
Hence the code as you have written returns either the last number or arr[0][1], whichever is smaller.
You should really only initialise this Min once before your loops begin. i.e.
Min = arr[0][1]
for(i = 0; i < 4;i++)
{
for(j = 0; j < 2; j++)
{
// Compare Min and arr[i][j] and reassign the smaller one to Min if i != j
}
}
l changed my code but still cant figure out why it wont sort array...bubble sort only moves all elements one place to the right in my program instead of sorting array...l tired bsort and ssort and both do same thing shift elements for 1 position
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bsort(int n,int a[])
{
int i,j,k;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1;j++)
{
if(a[j]>a[j+1]);
{
k=a[j+1];
a[j+1]=a[j];
a[j]=k;
}
}
}
}
int main()
{
int i,j,k,m,n;
srand(time(0));
printf("Unesi broj clanova niza:");
scanf("%d",&n);
int a[n];
printf("Niz za sortiranje je:\n");
for(int i=0;i<n;i++) //Generisanje niza
{
a[i]=rand()%(81);
}
for(int i=0;i<n;i++)
{
printf("%3d",a[i]);
}
bsort(n,a);
printf("\n\nSortirani niz je:\n");
for(i=0;i<n;i++)
{
printf("%3d",a[i]);
}
}
There are several problems with your bubble sort implementation.
First, this line:
if (a[j] > a[j + 1]); {
is incorrect. The semi-colon terminates the conditional. As a result, the following block executes on every iteration of the inner loop and you end up unconditionally swapping a[j] and a[j+1] for every value of j. This means you're performing a nonsensical rearrangement of the array.
Second, you're not dealing correctly with edge cases in the inner loop. When j == 19, you access a[j+1], which is a[20], which is beyond the end of the array. You thus import garbage data into your array.
Lastly, even after correcting the above, your implementation is needlessly inefficient, in that your inner loop goes through the entire array on each iteration of the outer loop, which it doesn't have to. Hint: Try to think about how the initialization or termination condition of the inner loop could depend on i.
Update (after the OP's rewrite): You only addressed the second issue.
int main() {
int a[20];
srand(time(0));
// array values initialization
for (int i = 0; i < 19; i++) {
a[i] = rand() % (81);
}
// array sorting
bsort(a);
// array printing
for (int i = 0; i < 19; i++) {
printf("%3d", a[i]);
}
}
I have 2 arrays called xVal, and yVal.
I'm using these arrays as coords. What I want to do is to make sure that the array doesn't contain 2 identical sets of coords.
Lets say my arrays looks like this:
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
Here I want to find the match between xVal[0] yVal[0] and xVal[1] yVal[1] as 2 identical sets of coords called 1,1.
I have tried some different things with a forLoop, but I cant make it work as intended.
You can write an explicit loop using an O(n^2) approach (see answer from x77aBs) or you can trade in some memory for performance. For example using std::set
bool unique(std::vector<int>& x, std::vector<int>& y)
{
std::set< std::pair<int, int> > seen;
for (int i=0,n=x.size(); i<n; i++)
{
if (seen.insert(std::make_pair(x[i], y[i])).second == false)
return false;
}
return true;
}
You can do it with two for loops:
int MAX=4; //number of elements in array
for (int i=0; i<MAX; i++)
{
for (int j=i+1; j<MAX; j++)
{
if (xVal[i]==xVal[j] && yVal[i]==yVal[j])
{
//DUPLICATE ELEMENT at xVal[j], yVal[j]. Here you implement what
//you want (maybe just set them to -1, or delete them and move everything
//one position back)
}
}
}
Small explanation: first variable i get value 0. Than you loop j over all possible numbers. That way you compare xVal[0] and yVal[0] with all other values. j starts at i+1 because you don't need to compare values before i (they have already been compared).
Edit - you should consider writing small class that will represent a point, or at least structure, and using std::vector instead of arrays (it's easier to delete an element in the middle). That should make your life easier :)
int identicalValueNum = 0;
int identicalIndices[4]; // 4 is the max. possible number of identical values
for (int i = 0; i < 4; i++)
{
if (xVal[i] == yVal[i])
{
identicalIndices[identicalValueNum++] = i;
}
}
for (int i = 0; i < identicalValueNum; i++)
{
printf(
"The %ith value in both arrays is the same and is: %i.\n",
identicalIndices[i], xVal[i]);
}
For
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
the output of printf would be:
The 0th value in both arrays is the same and is: 1.
The 1th value in both arrays is the same and is: 1.
The 3th value in both arrays is the same and is: 4.