I have a struct to assign values to it. But my programm crashs it. Hopefully you can help me.
struct HashEntry{
std::string key; //the key of the entry
bool used; //the value of the entry
int value; //marks if the entry was used before
};
HashEntry *initHashList(int N){
HashEntry* hashList = new HashEntry[N];
for (int i = 0; i <= N; i++){
hashList[i].key = " ";
hashList[i].value = -1;
hashList[i].used = false;
}
for(int i = 0; i <N; i++){
cout<<hashList[i].value<<endl;
}
return hashList;
}
You iterate through one element too many on creation:
for (int i = 0; i <= N; i++){
Shoule be
for (int i = 0; i < N; i++){
It's because with arrays being 0-based, you can't access the element N of an array of the size N, only N-1, but in return also element 0.
Also, to make the code clearer and less error prone, you could use std::array instead of a pure C style array, or even an std::vector to be able to loop through them range based. You might also rething your use of new which should be avoided in most cases. If you don't really need that, I'd change the function to
std::vector<HashEntry> initHashList(int N) {
std::vector<HashEntry> hashList(N, { "", false, -1, }); //Creating vector of N elements
for (const HashEntry& entry : hashList) { //Iterating through the elements
std::cout << entry.value << std::endl;
}
return hashList;
}
I hope this makes it clearer how you can approach such a problem.
This way of creating the vector and looping through it avoids the potential access errors and is easier to read, imo. For more information, search for std::vector, its constructors, and range-based loops.
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'm trying to find a way to iterating while comparing the element with the next element to find what is the biggest element in the array. But, the output i want keep repeating as much as the loop run.
int main(){
int array[4];
for ( int i = 0; i < 4; i++){
cin >> array[i];
}
for (int i:array){
for (int j = 1; j < 4; j++){
if (i < array[j]){
break;
}
if (i > array[j] ){
cout << i;
}
}
}
}
You can use the following program to find the biggest element in the array. Note that there is no need to use two for loops as you did in your code snippet.
#include <iostream>
int main()
{
int array[4] = {1,10, 13, 2};
int arraySize = sizeof(array)/sizeof(int);//note that you can also use std::size() with C++17
int startingValue = array[0];
for(int i = 1; i < arraySize; ++i)//start from 1 instead of 0 since we already have array[0]
{
if(array[i] > startingValue)
{
startingValue = array[i];
}
}
//print out the biggest value
std::cout<<"the biggest element in the array is: "<<startingValue<<std::endl;
return 0;
}
Your program is reapeating output because you have the cout inside the if which is satisfied multiple times(depending upon how big the array is and what elements it contains). For example, if you try your example on the array int array[] = {23,2,13,6,52,9,3,78}; then the output of your program will be 2323231313652525293787878 . So the output is reapeating more than 2 times. You can instead use the version i gave that uses only 1 for loop and prints the correct biggest element only once.
Note that you can also use std::size with C++17 while sizeof(array)/sizeof(int) works with all C++ versions.
I have written the following which gets the index value for the maximum number.
int TravellingSalesMan::getMaximum(double *arr){
double temp = arr[0];
int iterator = 0;
for(int i = 0; i < 30; i++){
if(arr[i] > temp){
iterator = i;
}
}
return iterator;
}
But the output keeps stepping into the conditional statement and keeps printing out 29. I am not sure why this is happening
I also tried using max_element() but with no luck
EDIT
The above function is invoked as following
static unsigned int chromosome = 30;
double value[chromosome]
for(int i = 0; i < chromosomes; i++){
value[i] = estimateFitness(currPopultaion[i]);
}
int best = 0;
best = getMaximum(value);
cout<<best<<endl; // this just prints out 29
Okay, so I didn't plan on writing the answer, but I just saw too many logical mistakes in the code for me to write in the comments section!
First of all, your use of the variable name iterator is very
wrong. It's not used for iteration over the list. Why create confusion. Best to use something like max_index or something like that.
Why start from i=0? Your temp value is arr[0], so there is no use. of checking with first element again. Start from i=1!
temp is pointless in that function. The maximum index should initially be 0, and set to i if ever there is some arr[i] that is greater than arr[max_index].
Passing the length separately to the function is better coding as it makes the code more clearer.
The content in arr is not modified, and as such better safe than sorry: make the pointer const.
Re-writing the code, it should be:
int TravellingSalesMan::getMaximum(const double *arr,int len)
{
int max_index = 0;
for(int i = 1; i < len; i++)
{
if(arr[i] > arr[max_index])
max_index = i;
}
return max_index;
}
Worth noting, but unchanged in the code above, len, i, and the function result should all be an unsigned integer type. There is no reason, to allow signed integer indexing, so make it a warning-condition from the caller if they do so by hard-specifying unsigned or just size_t as the indexing variable types.
You should be assigning a new value to temp when you find a new maximum.
int TravellingSalesMan::getMaximum(double *arr){
double temp = arr[0];
int iterator = 0;
for(int i = 0; i < 30; i++){
if(arr[i] > temp){
iterator = i;
temp = arr[i]; // this was missing
}
}
return iterator;
}
Without this you are finding the largest index of a value greater than the value at index zero.
A much better solution is to simply use std::max_element instead. Pointers can be used as iterators in most (if not all) algorithms requiring iterators.
#include <algorithm>
static unsigned int chromosomes = 30;
double value[chromosomes];
for (int i=0; i<chromosomes; ++i) {
value[I] = estimate_fitness(current_population[i]);
}
double *max_elm = std::max_element(&value[0], &value[chromosomes]);
int best = int(max_elm - &value[0]);
std::cout << best << std::endl;
I have an array A:
A = [10 11 3 15 8 7]
index = 0 1 2 3 4 5
I want to sort this array.After sorting I want the information of old index.For this I can create a structure like this.
struct VnI{
int value;
int index;
};
sorting the array of structure with respect to value solve my problem.But I want to know that is it possible to solve this using sort or any other function in C++11.
I have tried this way:
struct VnI{
int V;
int I;
};
bool comparator(VnI x,VnI y){
if(x.V < y.V)
return true;
return false;
}
int maximumGap(const vector<int> &A) {
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
sort(B.begin(),B.end(),comparator);
for(int i = 0;i < B.size();i++){
cout<<B[i].I<<" "<<B[i].V<<endl;
}
}
But I got runtime error.
Please help.
This code is wrong:
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
When you write B[i], it assumes that B is at least of size i+1. Since the maximum value of i (which you used an index to B) is A.size()-1. The assumption in your code is that B is at least of size A.size(). This assumption is wrong — the fact is that B is of size 0.
Unfortunately operator[] of std::vector doesn't check for out of range index. If you use at(), the code will throw std::out_of_range exception:
vector<VnI> B;
for(int i = 0;i < A.size();i++){
B.at(i).I = i;
B.at(i).V = A[i];
}
Now this would throw std::out_of_range exception.
Anyway, one simple fix could be this:
vector<VnI> B (A.size()); //initialize B with the size of A.
for(int i = 0;i < A.size();i++){
B[i].I = i;
B[i].V = A[i];
}
However, I'd suggest this solution:
vector<VnI> B;
B.reserve(A.size());
for(int i = 0;i < A.size(); i++){
B.emplace_back(i, A[i]);
}
I'd also suggest you read more about std::vector, especially the following functions:
size()
capacity()
resize()
reserve()
push_back()
operator[]
at()
emplace_back()
and all the constructors.
Also, learn to naming your variables properly and be consistent with it.
Hope that helps.
do you pefer to use vector and pair?
each pair has "first" and "second", put "first"=value to sort,"second"=original index, create a pair for each element and put them into vector to sort:
int N[]={10,11,3,15,8,7};
std::vector<std::pair<int,int> > v;
//create pair for each element
for(int i=0;i<sizeof(N)/sizeof(int);i++){
//first is value of array,second is original index
v.push_back(std::make_pair(N[i],i));
}
//sort the vector of pair
sort(v.begin(),v.end());
//get original index from second of pair
for(std::pair<int,int>& p : v){
std::cout << p.first << ":" << p.second << std::endl;
}
output
3:2
7:5
8:4
10:0
11:1
15:3
Normally what is done is the opposite... i.e. given an array x of elements compute an array of integers ix so that x[ix[i]] appears to be sorted under a certain criteria.
This allows representing the container with different orderings without actually having to move/copy the elements.
With C++11 this can easily be done using lambdas:
// Build the index vector ix
std::vector<int> ix(x.size());
for (int i=0,n=x.size(); i<n; i++) ix[i] = i;
// Sort ix according to the corresponding values in x
// (without touching x)
std::sort(ix.begin(), ix.end(),
[&x](int a, int b) { return x[a] < x[b]; });
This ix index array is what you are asking for (i.e. the "old" position of an element: ix[i] is where the i-th element of the sorted list was in the original array) and there is no need to modify the input array.
You are trying to sort a list of custom objects, answerd here:
SO Link
Once you list the list of VnI objects you can then access there old index's through the I member that I presume is the index.
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.