SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:25:17 - c++

I am solving the problem-->
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.
and the error I get is Line 16: Char 17: runtime error: index 3 out of bounds for type 'int [n - 1]' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:25:17
The line 16 is indice[i][j] = abs(i-j);
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int n = nums.size();
int indice[n-1][n-1];
int total[n-1][n-1];
for(int i = 0;i<n;i++)
{
for(int j=0;j<n;j++)
{
indice[i][j]= abs(i-j);
total[i][j] = abs(nums[i]-nums[j]);
}
}
for(int i = 0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(indice[i][j]<=k && total[i][j]<=t)
{
return true;
}
}
}
return false;
}
};
for the test case [1,2,3,1] 3 0
The code works fine on my device and other compiler but not on leetcode's compiler.
Please help

This would fix your bug, however there is a problem with your algorithm, does not pass all the test cases:
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int n = nums.size();
int indice[n][n];
int total[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
indice[i][j] = abs(i - j);
total[i][j] = abs(nums[i] - nums[j]);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (indice[i][j] <= k && total[i][j] <= t) {
return true;
}
}
}
return false;
}
};
This solution would pass using std::lower_bound:
// The following block might trivially improve the exec time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
return 0;
}();
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
#include <set>
#include <algorithm>
using ValueType = std::int_fast64_t;
static const struct Solution {
static const bool containsNearbyAlmostDuplicate(
const std::vector<int>& nums,
const int k,
const int t
) {
std::set<ValueType> window;
ValueType len = std::size(nums);
for (auto index = 0; index < len; ++index) {
if (index > k && index - k - 1 < len ) {
window.erase(nums[index - k - 1]);
}
const auto it = window.lower_bound((ValueType)nums[index] - t);
if (it != std::cend(window) && *it - nums[index] <= t) {
return true;
}
window.insert(nums[index]);
}
return false;
}
};

Related

Can't convert memory address to value

thanks for visiting my question! Currently, when I run this code (an implementation of the Set data structure in c++), the memory address of each element in the set is printed instead of the values in the set. To help with debugging, here's my code:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#define PB push_back
typedef std::vector<int> vint;
class SetBase
{
public:
SetBase() {}
~SetBase() {}
void insert(int x)
{
if (!this->isInSet(x))
{
this->set.PB(x);
}
}
int size()
{
return this->set.size();
}
bool empty()
{
return this->size() == 0;
}
int operator[](int index)
{
if (index >= 0 && index < this->size())
{
return this->set[index];
}
else
{
return -1;
}
}
bool find(int target)
{
sort(this->set.begin(), this->set.end());
int low = 0, high = this->size();
while (low <= high)
{
long long mid = low + (high - low) / 2;
long long guess = this->set[mid];
if (guess == target)
return true;
else if (guess < target)
low = mid + 1;
else
high = mid - 1;
}
return false;
}
int count(int target)
{
int counter = 0;
for (int i = 0; i < this->set.size(); i++)
{
if (this->set[i] == target)
counter++;
}
return counter;
}
bool operator=(SetBase &other)
{
if (other.size() != this->size())
return false;
for (int i = 0; i < other.size(); i++)
{
if (other[i] != this->set[i])
return false;
}
return true;
}
private:
vint set;
bool isInSet(int target)
{
for (int i = 0; i < this->size(); i++)
{
if (set[i] == target)
{
return true;
}
}
return false;
}
};
class Set : public SetBase
{
public:
void set_union(Set *set1, Set *set2, Set &back_insertor)
{
for (int i = 0; i < set1->size(); i++)
{
if (this->isInSet(back_insertor, i))
{
back_insertor.insert(i);
}
}
}
void set_difference(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 - set2
}
void set_intersection(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 U set2
for (int i = 0; i < set1.size(); i++)
{
for (int j = 0; j < set2.size(); j++)
{
if (set1[i] == set2[j])
{
back_insertor.insert(set1[i]);
}
}
}
}
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << &in[i] << "\n";
}
}
private:
bool isInSet(SetBase set1, int target)
{
for (int i = 0; i < set1.size(); i++)
{
if (target == set1[i])
{
return true;
}
}
return false;
}
};
int main()
{
Set *set_1 = new Set();
Set *set_2 = new Set();
Set *back = new Set();
for (int i = 1; i <= 10; i++)
set_1->insert(i);
for (int i = 1; i <= 10; i++)
set_2->insert(i);
set_2->insert(11);
set_1->set_union(set_1, set_2, *back);
set_1->printSet(set_1);
delete set_1;
delete set_2;
delete back;
}
When running the set_1->printSet(set_1); line, here's what I get:
0x7fb498c05a20
0x7fb498c05a38
0x7fb498c05a50
0x7fb498c05a68
0x7fb498c05a80
0x7fb498c05a98
0x7fb498c05ab0
0x7fb498c05ac8
0x7fb498c05ae0
0x7fb498c05af8
Even though this works, I would like to print out the values (integer) instead. Any help would be appreciated! Thanks! :)
Inside printSet(), you use &in[i] to print each element.
The & operator returns the address of the object you are referencing. So, instead of getting the value, you are getting its address. You should remove it, eg:
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << (*in)[i] << "\n";
}
}

map iterator: invalid type argument of unary '*' (have 'int')

I get this compilation error:
error: invalid type argument of unary '*' (have 'int')
_M_insert_unique_(end(), *__first);
I've tried using (*cols_it).first and (*cols_it).second and every other permutation I can think of, but I can't make it compile. What should I be writing?
Here's some of the code:
#include <map>
#include <vector>
using std::map;
using std::vector;
void setZeroes(vector<vector<int> > &A) {
map<int,int> rows;
map<int,int> cols;
for (unsigned int x = 0; x < A[0].size(); x++) {
for (unsigned int y = 0; y < A.size(); y++) {
if (A[x][y] == 0) {
rows.insert(y,y); // error reported here
cols.insert(x,x);
}
}
}
map<int,int>::iterator rows_it = rows.begin();
map<int,int>::iterator cols_it = cols.begin();
while (rows_it != rows.end()) {
for (unsigned int i = 0; i < A[0].size(); i++) {
int val = rows_it->second;
A[val][i] = 0;
}
rows_it++;
}
while (cols_it != cols.end()) {
for (unsigned int i = 0; i < A.size(); i++) {
int val = cols_it->second;
A[i][val] = 0;
}
cols_it++;
}
}
rows.insert(y,y); and cols.insert(x,x); won't work, std::map::insert expects std::pair<> as its argument.
You could:
rows.insert(std::make_pair(y,y));
cols.insert(std::make_pair(x,x));
or use list initialization (since C++11):
rows.insert({y,y});
cols.insert({x,x});
or use std::map::emplace (since C++11) instead:
rows.emplace(y,y);
cols.emplace(x,x);
The simple fix, since you are using std::map, is to replace the general container insert:
rows.insert(y,y);
cols.insert(x,x);
with the more convenient indexer of std::map:
rows[y] = y;
cols[x] = x;
Some of your loop counters look a bit odd, particularly the use of A[0] as a substitute of a particular row of A. That can be tidied up, and you could use std::set more easily than std::map:
#include <set>
#include <vector>
void setZeroes(std::vector<std::vector<int> > &A) {
std::set<unsigned int> rows, cols;
for (unsigned int x = 0; x < A.size(); x++) {
for (unsigned int y = 0; y < A[x].size(); y++) {
if (A[x][y] == 0) {
rows.insert(y);
cols.insert(x);
}
}
}
for (auto r: rows) {
for (unsigned int i = 0; i < A[r].size(); i++) {
A[r][i] = 0;
}
}
for (auto c: cols) {
for (unsigned int i = 0; i < A.size(); i++) {
A[i][c] = 0; // DANGER: should check c < A[i].size()
}
}
}

Dynamic Nested Loops (C++)

Hello I am looking for a way to write this C++ Code in a general way, so that if a want 20 columns I will not have to write 20 for loops:
for(int i=1; i<6; i++) {
for(int j=i; j<6; j++) {
for(int k=j; k<6; k++) {
for(int m=k; m<6; m++) {
std::cout << i << j << k << m << std::endl;
}
}
}
}
It is important that my numbers follow a >= Order.
I am very grateful for any help.
This recursive function should work:
#include <iostream>
bool inc( int *indexes, int limit, int n )
{
if( ++indexes[n] < limit )
return true;
if( n == 0 ) return false;
if( inc( indexes, limit, n-1 ) ) {
indexes[n] = indexes[n-1];
return true;
}
return false;
}
int main()
{
const size_t N=3;
int indexes[N];
for( size_t i = 0; i < N; ++i ) indexes[i] = 1;
do {
for( size_t i = 0; i < N; ++i ) std::cout << indexes[i] << ' ';
std::cout << std::endl;
} while( inc( indexes, 6, N-1 ) );
return 0;
}
live example
The design here is simple. We take a std::vector each containing a dimension count and a std::vector containing a current index at each dimension.
advance advances the current bundle of dimension indexes by amt (default 1).
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
return;
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which gives us an advance function for generic n dimensional coordinates.
Next, a filter that tests the restriction you want:
bool vector_ascending( std::vector<size_t> const& v ) {
for (size_t i = 1; (i < v.size()); ++i) {
if (v[i-1] < v[i]) {
return false;
}
}
return true;
}
then a for loop that uses the above:
void print_a_lot( std::vector<size_t> counts ) {
for( std::vector<size_t> v(counts.size()); v < counts; advance(v,counts)) {
// check validity
if (!vector_ascending(v))
continue;
for (size_t x : v)
std::cout << (x+1);
std::cout << std::endl;
}
}
live example.
No recursion needed.
The downside to the above is that it generates 6^20 elements, and then filters. We don't want to make that many elements.
void advance( std::vector<size_t>& indexes, std::vector<size_t> const& counts, size_t amt=1 ) {
if (indexes.size() < counts.size())
indexes.resize(counts.size());
for (size_t i = 0; i < counts.size(); ++i ) {
indexes[i]+=amt;
if (indexes[i] < counts[i])
{
size_t min = indexes[i];
// enforce <= ordering:
for (size_t j = i+i; j < counts.size(); ++j) {
if (indexes[j]<min)
indexes[j]=min;
else
break; // other elements already follow <= transitively
}
assert(vector_ascending(indexes));
return;
}
assert(counts[i]!=0);
amt = indexes[i]/counts[i];
indexes[i] = indexes[i]%counts[i];
}
// past the end, don't advance:
indexes = counts;
}
which should do it without the vector_ascending check in the previous version. (I left the assert in to do testing).
This function works for me, but do not call it with 20 if you want it to finish.
#include <list>
#include <iostream>
std::list<std::list<int>> fun (std::list<std::list<int>> inputlist, int counter)
{
if(counter == 0)
{
return inputlist;
}
else
{
std::list<std::list<int>> outputlist;
for(std::list<int> oldlist : inputlist)
{
for(int i = 1; i<6; i++)
{
std::list<int> newlist = oldlist;
newlist.push_back(i);
outputlist.push_back(newlist);
}
}
return fun(outputlist, counter - 1);
}
}
int main()
{
std::list<int> somelist;
std::list<std::list<int>> listlist;
listlist.push_back(somelist);
std::list<std::list<int>> manynumbers = fun (listlist,5);
for (std::list<int> somenumbers : manynumbers)
{
for(int k : somenumbers)
{
std::cout<<k;
}
std::cout<<std::endl;
}
return 0;
}
Same with Processing (java) here :
void loopFunction(int targetLevel, int actualLevel, int min, int max, String prefix){
/*
targetLevel is the wanted level (20 in your case)
actualLevel starts from 1
min starts from 1
max is the max number displayed (6 in your case)
prefix starts from blank
see usage bellow (in setup function)
*/
for(int m=min; m<max; m++) {
if(targetLevel==actualLevel)
{
println(prefix+ " " + m);
}
else
{
loopFunction(targetLevel, actualLevel+1,m,max,prefix+ " " + m);
}
}
}
void setup(){
loopFunction(10,1,1,6,"");
}
Well, I am not the fastest in writing answer... when I started there was no other answer. Anyhow, here is my version:
#include <iostream>
#include <vector>
using namespace std;
class Multiindex {
public:
typedef std::vector<int> Index;
Multiindex(int dims,int size) :
dims(dims),size(size),index(Index(dims,0)){}
void next(){
int j=dims-1;
while (nextAt(j) && j >= 0){j--;}
}
Index index;
bool hasNext(){return !(index[0]==size-1);}
private:
bool nextAt(int j){
index[j] = index[j]+1;
bool overflow = (index[j]==size);
if (!overflow && j < dims-1){std::fill(index.begin() + j + 1,index.end(),index[j]);}
return overflow;
}
int dims;
int size;
};
int main() {
Multiindex m(4,6);
while (m.hasNext()){
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
m.next();
}
cout << m.index[0] << m.index[1] << m.index[2] << m.index[3] << endl;
return 0;
}

Querying for a value that's bigger than X, while having another condition

I have list of pair [x;y] where x is unique and y can be duplicate(integers).
Here lies a problem:
Given a pair [x;y], find new pair [k;m], such that:
k > x
m >= y
k - x is minimized.
Now, I've solved this problem with this logic; I sort pairs by x, and then start naive O(n^2) algorithm on it. It seems to work fine, except it's too slow.
Can I do better?
The actual problem im trying to solve, is here: http://www.spoj.com/problems/VBOSS/
and my current code:
#include <stdio.h>
#include <utility>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
struct employee
{
int id;
int salary;
int height;
int parent_index;
int sub_ordinates;
int cur;
bool important;
bool operator < (const employee& e) const
{
if(height == e.height)
return salary > e.salary;
return (height > e.height);
}
};
// problem states explictly that no two employees
// have same salary.
struct salary_predicate
{
inline bool operator() (const employee& struct1, const employee& struct2)
{
return (struct1.salary > struct2.salary);
}
};
const int MAX_EMPLOYEES = 30000;
const int MAX_QUERIES = 200;
employee employees[MAX_EMPLOYEES];
int queries[MAX_QUERIES];
int main()
{
int test_cases;
scanf("%d", &test_cases);
while(test_cases--)
{
int employeeCount, queryCount;
scanf("%d %d", &employeeCount, &queryCount);
int i = 0;
int j = 0;
while(i < employeeCount)
{
employees[i].parent_index = -1;
employees[i].sub_ordinates = 0;
employees[i].cur = i;
employees[i].important = false;
scanf("%d %d %d", &employees[i].id, &employees[i].salary, &employees[i].height);
i++;
}
map<int, int> mapper;
while(j < queryCount)
{
scanf("%d", &queries[j]);
mapper.insert(pair<int, int>(queries[j], -1));
j++;
}
// now step1; sort employees structure
// based on SALARY!!
sort(employees, employees + employeeCount, salary_predicate());
for(int k = 0; k < employeeCount; k++)
{
employees[k].cur = k;
if(mapper.find(employees[k].id) != mapper.end())
{
mapper[employees[k].id] = k;
employees[k].important = true;
}
}
int found = 0;
for(int l = employeeCount - 1; l >= 0; l--)
{
int gef = l - 1;
// check out information about previous worker,
// he might give us some valuable information!
// with his help, we know if we can skip some shit :)
if(l + 1 < employeeCount && employees[l + 1].parent_index != -1)
{
// if previous employee is smaller than our current employee
// then we can skip some people, becase we know that answer cant be
// smalle than that :)
if(employees[l + 1].height <= employees[l].height)
gef = employees[l + 1].parent_index - 1;
}
// find boss!
for(int b = gef; b >= 0; b--)
{
if(employees[b].height >= employees[l].height)
{
employees[l].parent_index = b;
employees[b].sub_ordinates += employees[l].sub_ordinates + 1;
break;
}
}
// this bit makes sure if we have processed all necessay things,
// then we can basically stop our work.
if(employees[l].important) found++;
if(found == mapper.size()) break;
}
// time to print it out.
for(int b = 0; b < queryCount; b++)
{
int id = queries[b];
int index = mapper[id];
int parent_index = employees[index].parent_index;
int parent = parent_index < 0 ? 0 : employees[parent_index].id;
printf("%d %d\r\n", parent, employees[index].sub_ordinates);
}
}
return 0;
}
salary=x, and height=y.
I would start by eliminating all records where m<y or k<=x. Then find the item with the smallest k value out of what's left. Both of these should be linear, so your overall complexity should also be linear.
struct p {
int k, m;
};
p find_item(p xy, std::vector<p> &values) {
auto end = std::partition(values.begin(), values.end(),
[xy](p const &v) { return xy.k < v.k || xy.m >= v.m; });
return *std::min_element(values.begin(), end,
[](p const &a, p const &b) { return a.k < b.k; });
}

Iterating over subsets of any size

I can iterate over the subsets of size 1
for( int a = 0; a < size; a++ ) {
or subsets of size 2
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
or 3
for( int a1 = 0; a1 < size; a1++ ) {
for( int a2 = a1+1; a2 < size; a2++ ) {
for( int a3 = a2+1; a3 < size; a3++ ) {
But how to do this for subsets of size n?
This does the job, based on an answer by Adam Rosenfield
void iterate(int *a, int i, int size, int n)
{
int start = 0;
if( i > 0 ) start = a[i-1]+1;
for(a[i] = start; a[i] < n; a[i]++) {
if(i == n-1) {
// a is the array of indices of size n
for( int k = 0; k < size; k++ ) {
printf("%d ",a[k]);
}
printf("\n");
}
else
iterate(a, i+1, size, n);
}
}
You can use recursion:
void iterate(int *a, int i, int size, int n)
{
for(a[i] = 0; a[i] < size; a[i]++)
{
if(i == n-1)
DoStuff(a, n); // a is the array of indices of size n
else
iterate(a, i+1, size, n);
}
}
...
// Equivalent to 4 nested for loops
int a[4];
iterate(a, 0, size, 4);
You likely could do this with some recursion.
Here is something I used for a similar problem. It does not use recursion; rather, it uses a vector of indexes.
#include <vector>
template<class T>
class MultiForVar {
std::vector<T> _begin, _end, _vars;
inline int dim(){return _vars.size();}
public:
MultiForVar(std::vector<T> begin, std::vector<T> end) : _begin(begin), _end(end), _vars(_begin)
{
assert(begin.size() == end.size() and "Starting and ending vector<T> not the same size!" );
}
MultiForVar& operator ++()
{
++_vars[dim()-1];
for(int d = dim()-1; d > 0; --d)
{
if( _vars[d] >= _end[d] )
{
_vars[d] = _begin[d];
++_vars[d-1];
}
}
return *this;
}
bool done()
{
/*for(int d = 0; d < dim(); ++d)
if( _vars[d] < _end[d] )
return false;
return true;*/
return (_vars[0] >= _end[0]);
}
T operator[](int d)
{
return _vars.at(d);
}
int numDimensions(){
return dim();
}
std::vector<T>& getRaw(){
return _vars;
}
};
If I understand what you're asking correctly, another way to do it is to use bit-wise operators:
for(int i = 0; i < 1<<size; i++) {
for(int j = 0; j < size; j++) {
if(i & 1<<j) printf("%d ", a[j]);
}
printf("\n");
}
You need something the constructs the powerset of the original set. It's been a while since I've written that, but the psuedocode looks like
Powerset(a, size)
{
if(size == 0) return emptyset
subseta = Powerset(a, size-1) // Powerset of everything except last element
subsetb = appendToAll(a[size-1], subseta) // appends the last element to every set in subseta
return union(subseta, subsetb)
}