generate unique numbers to 2-Dimensional array using linear search - c++

The program compiles and I can enter a number, but it doesn't generate or it display the array. When I take out the while condition with the linear search in the randomFillUnique function, it generates and displays the array, but not unique numbers. I needed a 2D array with no duplicate numbers.
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
int** gen2Array(int n);
void randomFillUnique(int** arr, int n);
bool lSearch(int** arr, int n, int target);
void display(int** arr, int n);
int main()
{
int number;
cout << "Enter a number: ";
cin >> number;
randomFillUnique(gen2Array(number), number);
system("pause");
return 0;
}
int** gen2Array(int n)
{
int** arr2D = new int*[n];
for (int index = 0; index < n; index++)
arr2D[index] = new int[n];
return arr2D;
}
void randomFillUnique(int** arr, int n)
{
static default_random_engine e;
uniform_int_distribution<int> u(1, n*n);
e.seed(static_cast<int>(time(NULL)));
bool result = false;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
arr[row][col] = u(e); //generate random number
result = lSearch(arr, n, arr[row][col]);
while (result == true)
{
arr[row][col] = u(e); //generate random number
result = lSearch(arr, n, arr[row][col]);
}
}
}
display(arr, n);
delete[] arr;
}
bool lSearch(int** arr, int n, int target)
{
bool found = false;
for (int row = 0; row < n; row++)
for (int col = 0; col < n; col++)
{
if (arr[row][col] == target)
{
found = true;
return found;
}
}
return found;
}
void display(int** arr, int n)
{
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
cout << arr[row][col];
cout << endl;
}
}

Because you are setting the entry in the array to u(e) before you lsearch, lsearch always returns true and your while loops forever. The below, adapted from your code, should fix that (I am assuming the rest of the code behaves as one would expect). As user4581301 points out, there may be better approaches, but I am going with yours enough to get it working, I hope.
void randomFillUnique(int** arr, int n)
{
static default_random_engine e;
uniform_int_distribution<int> u(1, n*n);
e.seed(static_cast<int>(time(NULL)));
int nextEntry;
bool result = false;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
result = true;
while (result == true)
{
nextEntry = u(e); //generate random number
result = lSearch(arr, n, nextEntry);
if (result != true)
{arr[row][col]=nextEntry;}
}
}
}
display(arr, n);
delete[] arr;
}

An alternative approach would be to create a container of all the unique integers which will go into the array, using iota:
std::vector<int> invalues(n*n, 0);
std::iota(invalues.begin(), invalues.end(), 1);
Then shuffle that container:
std::shuffle(invalues.begin(), invalues.end(),
std::mt19937{std::random_device{}()});
Then feed the values one by one into the matrix.
You could also use a vector<vector<int>> instead of built-in arrays:
using matrix = std::vector<std::vector<int>>;
// initialising a vector<vector<int>> to be a certain size is a bit clumsy
matrix m(size_y, std::vector<int>(size_x, 0));
Then feeding the input values into the matrix:
for (auto &row : m) {
for (auto &elem : row) {
elem = invalues.back();
invalues.pop_back();
}
}
Then displaying the matrix:
for (const auto &row : m) {
for (const auto &elem : row) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
Here's a full example in an online compiler.

OK. Here's the easier way to do this I commented on. If std::vector is disallowed, a simple 1D vector will suffice, but a sane software engineer would think really, really hard before selecting it over a vector.
I made a few other changes to fix a couple other bugs.
#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <algorithm> // std::shuffle and std::iota
#include <ctime>
using namespace std;
int** gen2Array(int n);
void randomFillUnique(int** arr, int n);
bool lSearch(int** arr, int n, int target);
void display(int** arr, int n);
//Added to properly delete the 2dArray
void del2Array(int ** arr, int n);
int main()
{
int number = 10;
randomFillUnique(gen2Array(number), number);
system("pause");
return 0;
}
int** gen2Array(int n)
{
int** arr2D = new int*[n];
for (int index = 0; index < n; index++)
arr2D[index] = new int[n];
return arr2D;
}
//Added to properly delete the 2dArray
void del2Array(int ** arr,
int n)
{
for (int index = 0; index < n; index++)
delete arr[index];
delete arr;
}
void randomFillUnique(int** arr, int n)
{
//do the seeding here
static default_random_engine e(static_cast<int>(time(NULL)));
// otherwise
// e.seed(static_cast<int>(time(NULL)));
// runs every time reseeding the RNG to potentially the give the same results
// if run more than once in a second. Plus the seeding is expensive.
std::vector<int> v(n*n); // make and size vector
std::iota (v.begin(), v.end(), 0); // init vector with 1 through n*n
std::shuffle(v.begin(), v.end(), e);
size_t index = 0;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
arr[row][col] = v[index++]; //generate random number
}
}
display(arr, n);
del2Array (arr, n); // frankly I don't think you want his here
// why fill an array only to delete it?
// more logical to display and delete back in main.
}
void display(int** arr, int n)
{
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
cout << arr[row][col] << "\t"; //added a tab to make the printing easier to read
cout << endl;
}
}
Documentation on std::vector
Documentation on std::shuffle
Documentation on std::iota. Which uses exactly this technique to demonstrate iota. Funny, huh?

Related

what's wrong with this "maximum-minimum element in an array" Logic?

I am new to coding and I am unable to see what is wrong with this Logic.
I am unable to get the desired output for this program.
The Question is to find the minimum and maximum elements of an array.
The idea is to create two functions for minimum and maximum respectively and have a linear search to identify the maximum as well as a minimum number.
#include <iostream>
#include<climits>
using namespace std;
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
if (a[i] > a[i + 1])
{
maxNum = max(maxNum, a[i]);
}
else
{
maxNum = max(maxNum, a[i+1]);
}
// maxNum = max(maxNum, temp);
}
// return maxNum;
cout<<maxNum<<endl;
}
void minElement(int c[], int d)
{
// int temp;
int minNum = INT_MAX;
for (int i = 0; i < d; i++)
{
if (c[i] > c[i + 1])
{
minNum = min(minNum,c[i+1]);
}
else
{
minNum = min(minNum,c[i]);
}
// minNum = min(minNum, temp);
}
// return minNum;
cout<<minNum<<endl;
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
minElement(arr,n);
maxElement(arr,n);
return 0;
}
You are already comparing each element to the current max / min. It is not clear why in addition you compare to adjacent elements. Trying to access a[i+1] in the last iteration goes out of bounds of the array and causes undefined behavior. Just remove that part:
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
maxNum = max(maxNum, a[i]);
}
cout<<maxNum<<endl;
}
Similar for the other method.
Note that
int n;
cin >> n;
int arr[n];
is not standard C++. Variable length arrays are supported by some compilers as an extension, but you don't need them. You should be using std::vector, and if you want to use c-arrays for practice, dynamically allocate the array:
int n;
cin >> n;
int* arr = new int[n];
Also consider to take a look at std::minmax_element, which is the standard algorithm to be used when you want to find the min and max element of a container.
Last but not least you should seperate computation from output on the screen. Considering all this, your code could look like this:
#include <iostream>
#include <algorithm>
std::pair<int,int> minmaxElement(const std::vector<int>& v) {
auto iterators = std::minmax_element(v.begin(),v.end());
return {*iterators.first,*iterators.second};
}
int main()
{
int n;
std::cin >> n;
std::vector<int> input(n);
for (int i = 0; i < n; i++)
{
std::cin >> input[i];
}
auto minmax = minmaxElement(input);
std::cout << minmax.first << " " << minmax.second;
}
The method merely wraps the standard algorithm. It isnt really needed, but I tried to keep some of your codes structure. std::minmax_element returns a std::pair of iterators that need to be dereferenced to get the elements. The method assumes that input has at least one element, otherwise dereferencing the iterators is invalid.

I am trying to write a program find maximum element of each column in a matrix but getting errors as cannot convert 'int (*)[m]' to 'int (*)[100]'

#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
//Function to calculate largest column
void largestInColumn(int mat[][MAX], int rows, int cols)
{
for (int i = 0; i < cols; i++) {
// initialize the maximum element with 0
int maxm = mat[0][i];
// Run the inner loop for rows
for (int j = 1; j < rows; j++) {
// check if any element is greater than the maximum element of the column and replace it
if (mat[j][i] > maxm)
maxm = mat[j][i];
}
cout << maxm << endl;
}
}
// Driver code
int main()
{
int n , m ;
cin>>n>>m;
int mat[n][m];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>mat[i][j];
}
}
largestInColumn(mat, n, m);
return 0;
}
I will answer the question using valid C++ statements. There are no VLAs in C++. I will use a std::vector instead.
There is also no need to store any value of the matrix for this task. You can make the decision already during reading of the values.
#include <iostream>
#include <vector>
#include <limits>
int main() {
// Read number of rows and columns
if (size_t numberOfRows{}, numberOfColumns{}; std::cin >> numberOfRows >> numberOfColumns) {
// Here we will store the max values per column, so, the result
std::vector<int> maxColumnValue(numberOfColumns, std::numeric_limits<int>::lowest());
// Read all rows and columns
for (size_t row{}; row < numberOfRows; ++row)
for (size_t col{}; col < numberOfColumns; ++col)
// If the current value of the column is greater than the current max value, then use new value instead
if (int value{ std::numeric_limits<int>::lowest() }; std::cin >> value)
if (value > maxColumnValue[col]) maxColumnValue[col] = value;
// Show result to the user
for (const int m : maxColumnValue) std::cout << m << '\n';
}
return 0;
}
The cause of the error is due to you trying to pass a variable-length-array to a function that requires a standard 2D array.
First, variable-length-arrays (VLA's) are not part of standard C++. Arrays in C++ require that the sizes of the array are known at compile-time, not runtime. So pretend they don't exist, because technically, they do not exist in standard C++.
Thus you have two choices:
Declare a non-variable-size 2D array and use that, or
Use a container that is built to have dynamic size, such as std::vector.
Since you did not specify how large n could be, then solution 2 is safer.
Given that, here is your code using std::vector:
#include <vector>
#include <iostream>
using Int1D = std::vector<int>;
using Int2D = std::vector<Int1D>;
//Function to calculate largest column
void largestInColumn(Int2D& mat, int rows, int cols)
{
for (int i = 0; i < cols; i++)
{
int maxm = mat[0][i];
for (int j = 1; j < rows; j++)
{
if (mat[j][i] > maxm)
maxm = mat[j][i];
}
std::cout << maxm << std::endl;
}
}
int main()
{
int n , m ;
std::cin >> n >> m;
Int2D mat(n, Int1D(m));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
std::cin >> mat[i][j];
}
}
largestInColumn(mat, n, m);
}
Using the input:
3 3
1 2 3
1 4 9
76 34 21
The output is:
76
34
21

Removing odd numbers from an array

I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}
// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}
Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo

Function returning the index of largest value, skipping previously returned values

I need to make a function in c++ that returns the index of the largest value. Whenever it is called it should skip the index it returned previously and return the index storing the next largest value.
for eg if : -
int a[8] = {2,6,4,12,5,7,12,8}
the function should return 3 then 6 then 7, 5,1,4,2,0
Edit :-
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
Trying to implement Fractional Knapsack algorithm. If I run the code on input
3 50
60 20
100 50
120 30
it should give the answer 180 but it returns 200 instead because my 'return_max_index' function is returning the same index again (2) but I somehow want it to skip the index it returned previously (2) and return the index that has the next highest 'valuebyweight' i.e 0.
Try this code.I made some minor changes.
#include <iostream>
#include <vector>
using std::vector;
int return_max_index(vector<int> valuebyweight, int n)
{
int max_index = 0;
for(int i=0; i<n; i++)
{
if(valuebyweight[i] >= valuebyweight[max_index])
{
max_index = i;
}
}
//if all the values in valuebyweight are 0
if(valuebyweight[max_index]==0)
{
return -1;
}
else
return max_index;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values,int n) {
double value = 0.0;
vector<int> valuebyweight(n);
for(int i=0; i<n; i++)
{
valuebyweight[i] = values[i] / weights[i];
}
while(capacity!=0)
{
int max_index = return_max_index(valuebyweight, n);
if(max_index==-1)
{
break;
}
if(weights[max_index] <= capacity)
{
capacity -= weights[max_index];
value += values[max_index];
// assign valuebyweight[max_index] to 0 as it already participated in optimal solution and need no longer to participate.
valuebyweight[max_index]=0;
}
else
{
value += (valuebyweight[max_index] * capacity);
capacity = 0;
}
}
return value;
}
int main() {
int n;
int capacity;
std::cin >> n >> capacity;
vector<int> values(n);
vector<int> weights(n);
for (int i = 0; i < n; i++) {
std::cin >> values[i] >> weights[i];
}
double optimal_value = get_optimal_value(capacity, weights, values,n);
std::cout.precision(10);
std::cout << optimal_value << std::endl;
return 0;
}
One way to do this is to just keep the list of found indices in a static local. But then, how do you know you haven't already seen this one before? So better to make it a class. Then you can also do some optimization: sort the array once, then just pop the next highest index from the result whenever it's called:
struct mysort{
const std::vector<int>& _tosort;
mysort(const std::vector<int> tosort) : _tosort(tosort) {}
bool operator()(int a, int b){ return _tosort[a] < _tosort[b]; }
}
class IndexFinder{
private:
std::vector<int> sorted_indices;
int invoked;
public:
IndexFinder(const std::vector<int>& tosort) :
sorted_indices(tosort.size()) {
invoked = 0;
for(size_t i=0; i<tosort.size(); ++i)
sorted_indices[i] = i;
std::stable_sort(sorted_indices.begin(), sorted_indices.end(),
mysort(tosort));
}
int IndexFinder::operator()(){
return sorted_indices[invoked++];
}
};
You should put in protections to IndexFinder::operator()() to handle what happens if the user calls it more times than there are indices in the vector. As a bonus you should be pretty easily able to change it into a template class to sort things other than ints.
This is not pretty (it modifies the array), but gives an idea:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int index_of_largest(int array[], size_t len) {
int r = INT_MIN;
int d = 0;
for (int i = 0; i < len; i++) {
if (array[i] > r) {
d = i;
r = array[i];
}
}
if (r != INT_MIN) {
array[d] = INT_MIN;
}
return d;
}
int main(){
int a[8] = {2, 6, 4, 12, 5, 7, 12, 8};
int len = (int)(sizeof(a) / sizeof(a[0]));
for (int i = 0; i < len; i++) {
printf("%d\n", index_of_largest(a, len));
}
}
OUTPUT
3
6
7
5
1
4
2
0
This is a little different than the previous answer #bloer gave, but shows somewhat of a shorter method (it still uses a class) by using C++ 11 (std::iota and usage if lambda in std::sort).
#include <algorithm>
#include <iostream>
#include <vector>
class MaxIndex
{
private:
std::vector<int> index;
public:
MaxIndex(const std::vector<int>& tosort) : index(tosort.size())
{
// initialize the indices
std::iota(index.begin(), index.end(), 0);
// sort the indices based on passed-in vector
std::sort(index.begin(), index.end(), [&](int n1, int n2)
{ return tosort[n1] > tosort[n2];});
}
// return the nth highest index
int getNthMaxIndex(int n) const { return index[n]; }
};
using namespace std;
int main()
{
std::vector<int> a = {2,6,4,12,5,7,12,8};
MaxIndex mi(a);
for (size_t i = 0; i < a.size(); ++i)
cout << mi.getNthMaxIndex(i) << endl;
}
Live Example
Second, is there a reason to consistently use n if you're going to use std::vector? A std::vector knows its own size, so passing (and using) extraneous variables denoting the number of elements in a vector is inviting a bug to be introduced somewhere. Just use the std::vector::size() function if you want to get the number of elements, or just pass the vector by itself.
In addition, you should be passing things like std::vector by either reference or const reference, depending on whether the passed-in vector will be changed or not. Passing std::vector by value (as you're doing now) incurs an (unnecessary) copy.

Find all possible arrays of size n constructed with all possible combinations of elements from another array in all possible orders?

For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.