After running this code , it will generate a random array of desired rows and columns . Then a loop will divide the array by its diagonal into an upper side and lower side.In the upper side the loop will look for a max number and in the lower side the loop will look for a min number . Then in the final stage I need to change the positions of min and max . Max in place of min and vice versa.The code runs and finds the min and max.Don't know how to change their places.
Code
#include <iostream>
#include <time.h>
#include <limits.h>
using namespace std;
int main(){
int rows, columns;
int max = INT_MAX;
int min = INT_MIN;
int XindexOfMax, YindexOfMax;
int XindexOfMin, YindexOfMin;
cout << "Enter rows: ";
cin >> rows;
cout << "Enter columns: ";
cin >> columns;
int **array = new int *[rows]; //generating random array
for(int i = 0; i < rows; i++)
array[i] = new int[columns];
srand((unsigned int)time(NULL)); //generating randoms
for(int i = 0; i < rows; i++){ //loop for the main array
for(int j = 0; j < columns; j++){
array[i][j] = rand() % 10;
cout << array[i][j] << " ";
}
cout << "\n";
}
cout << "For finding Max: " << endl;
for(int i = 0; i < rows; i++){ //upper half of the diagonal
for(int j = 0; j < columns - i; j++){
cout << array[i][j] << " ";
if(array[i][j] > max){
max = array[i][j];
XindexOfMax = i; //find x and y coordinates if max
YindexOfMax = j;
}
}
cout << "\n";
}
cout << "For finding Min: " << endl;
for (int i = 0; i < rows; i++){ // lower half of the diagonal
for (int j = 0; j < columns; j++){
if (j < columns - i - 1){
cout << " ";
}
else{
cout << array[i][j] << " ";
if(array[i][j] < min){
min = array[i][j];
XindexOfMin = i; //find x and y coordinates if min
YindexOfMin = j;
}
}
}
cout << "\n";
}
cout << "Result" << endl;
//swapping positions of min and max
std::swap(array[XindexOfMax][YindexOfMax], array[XindexOfMin][YindexOfMin]);
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
cout << array[i][j] << " "; //Printing the final array
}
cout << "\n";
}
return 0;
}
In addition to the min and max values, you need to remember the indizes where you found min and max, respectively. Then you can exchange the values (either manually or by using std::swap).
BTW: you need to initialize max and min with INT_MIN and INT_MAX, respectively, and not the other way around.
So it needs to be
int max = INT_MIN;
int min = INT_MAX;
Otherwise, if you write int max = INT_MAX, then no comparison like if(array[i][j] > max) will ever evaluate to true, since there is no integral value greater than INT_MAX.
The swapping is done at the end of main() using std::swap().
I broke a couple of routines into functions. The answer would be improved by breaking out more functions so that each function performs a single task. Still, I added a class, yet tried to stay true to your original design for printing the triangle halves. Hope you can handle some classes at this point.
#include <iostream>
#include <time.h>
#include <limits.h>
#include <cmath>
using namespace std;
class Point {
public:
Point(int x, int y, int value) : x(x), y(y), value(value) {}
int X() { return x; }
int Y() { return y; }
int Value() { return value; }
void SetValue(int valueArg) { value = valueArg; }
void SetPoint(int xArg, int yArg, int valueArg) {
x = xArg;
y = yArg;
value = valueArg;
}
string to_string() {
return std::to_string(value);
}
private:
int x;
int y;
int value;
};
void PrintArray(int **array, int rows, int columns) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
cout << array[i][j] << " ";
}
cout << "\n";
}
}
int main() {
int rows, columns;
cout << "Enter rows: ";
cin >> rows;
cout << "Enter columns: ";
cin >> columns;
int **array = new int *[rows]; //generating random array
for (int i = 0; i < rows; i++)
array[i] = new int[columns];
srand((unsigned int) time(NULL));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
array[i][j] = rand() % 10; //generating randoms
}
}
PrintArray(array, rows, columns);
Point maxPoint = Point(0, 0, INT_MIN); // initialize max
Point minPoint = Point(0, 0, INT_MAX);;
cout << "For finding Max: " << endl;
for (int i = 0; i < rows; i++) { //separating the upper half
for (int j = 0; j < columns - i; j++) {
if (j > columns - i) {
cout << array[i][j] << " ";
} else {
cout << array[i][j] << " ";
if (array[i][j] > maxPoint.Value()) {
maxPoint.SetPoint(i, j, array[i][j]);
}
}
}
cout << "\n";
}
cout << "For finding Min: " << endl;
for (int i = 0; i < rows; i++) { //separating the lower half
for (int j = 0; j < columns; j++) {
if (j < columns - i - 1) {
cout << " ";
} else {
cout << array[i][j] << " ";
if (array[i][j] < minPoint.Value()) {
minPoint.SetPoint(i, j, array[i][j]);
}
}
}
cout << "\n";
}
cout << "array before: " << endl;
PrintArray(array, rows, columns);
cout << "Swapping " << "maxPoint(" << maxPoint.X() << ", " <<
maxPoint.Y() << ") with minPoint("
<< minPoint.X() << ", " << minPoint.Y() << ")" << endl;
std::swap(
minPoint.GetCellReference(array),
maxPoint.GetCellReference(array));
PrintArray(array, rows, columns);
return 0;
}
As mentioned in one of the comments, std::swap() is one method of performing a swap. I have modified the example to use std:swap() at the end of main();
Related
I'm a C++ newb. I need to insert numbers to an array and then display first the odd numbers and then the even numbers in a single array. I've managed to create two separate arrays with the odd and even numbers but now I don't know how to sort them and put them back in a single array. I need your help to understand how to do this with basic C++ knowledge, so no advanced functions. Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N{ 0 }, vector[100], even[100], odd[100], unify[100], i{ 0 }, j{ 0 }, k{ 0 };
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++) {
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++) {
if (vector[i] % 2 == 0) {
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0) {
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++) {
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++) {
cout << " " << odd[i] << " ";
cout << endl;
}
return 0;
}
If you don't need to store the values then you can simply run through the elements and print the odd and the even values to different stringstreams, then print the streams at the end:
#include <sstream>
#include <stddef.h>
#include <iostream>
int main () {
std::stringstream oddStr;
std::stringstream evenStr;
static constexpr size_t vecSize{100};
int vec[vecSize] = {10, 5, 7, /*other elements...*/ };
for(size_t vecIndex = 0; vecIndex < vecSize; ++vecIndex) {
if(vec[vecIndex] % 2 == 0) {
evenStr << vec[vecIndex] << " ";
} else {
oddStr << vec[vecIndex] << " ";
}
}
std::cout << "Even elements are:" << evenStr.rdbuf() << std::endl;
std::cout << "Odd elements are:" << oddStr.rdbuf() << std::endl;
}
Storing and sorting the elements are always expensive.
Basically, it would be better to sort them first.
#include <iostream>
using namespace std;
int main()
{
int numbers[5];
int mergedArrays[5];
int evenNumbers[5];
int oddNumbers[5];
for(int i=0;i<5;i++){
cin>>numbers[i];
}
int temp=numbers[0];
//bubble sort
for(int i = 0; i<5; i++)
{
for(int j = i+1; j<5; j++)
{
if(numbers[j] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
int nEvens=0;
int nOdds=0;
for(int i = 0; i<5; i++)
{
if(numbers[i]%2==0)
{
evenNumbers[nEvens]=numbers[i];
nEvens++;
}
else if(numbers[i]%2!=0)
{
oddNumbers[nOdds]=numbers[i];
nOdds++;
}
}
int lastIndex=0;
//copy evens
for(int i = 0; i<nEvens; i++)
{
mergedArrays[i]=evenNumbers[i];
lastIndex=i;
}
//copy odds
for(int i =lastIndex; i<nOdds; i++)
{
mergedArrays[i]=oddNumbers[i];
}
return 0;
}
If you have to just output the numbers in any order, or the order given in the input then just loop over the array twice and output first the even and then the odd numbers.
If you have to output the numbers in order than there is no way around sorting them. And then you can include the even/odd test in the comparison:
std::ranges::sort(vector, [](const int &lhs, const int &rhs) {
return ((lhs % 2) < (rhs % 2)) || (lhs < rhs); });
or using a projection:
std::ranges::sort(vector, {}, [](const int &x) {
return std::pair<bool, int>{x % 2 == 0, x}; });
If you can't use std::ranges::sort then implementing your own sort is left to the reader.
I managed to find the following solution. Thanks you all for your help.
#include <iostream>
using namespace std;
int main()
{
int N{0}, vector[100], even[100], odd[100], merge[100], i{0}, j{0}, k{0}, l{0};
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++)
{
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++)
{
if (vector[i] % 2 == 0)
{
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0)
{
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++)
{
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++)
{
cout << " " << odd[i] << " ";
cout << endl;
}
for (i = 0; i < k; i++)
{
merge[i] = odd[i];
}
for (int; i < j + k; i++)
{
merge[i] = even[i - k];
}
for (int i = 0; i < N; i++)
{
cout << merge[i] << endl;
}
return 0;
}
You can use Bubble Sort Algorithm to sort whole input. After sorting them using if and put odd or even numbers in start of result array and and others after them. like below:
//Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already
// in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
// Insert In array
int result[100];
if(odd[0]<even[0])
{
for (int i = 0; i < k; i++)
{result[i] = odd[i];}
for (int i = 0; i < j; i++)
{result[i+k] = even[i];}
}else
{
for (int i = 0; i < j; i++)
{result[i] = even[i];}
for (int i = 0; i < k; i++)
{result[i+k] = odd[i];}
}
I am trying to create a program that swaps the row that contains the min number with the row that contains the max number in a n x m twodimensional array (c++)
#include <iostream>
using namespace std;
int main()
{
int i, j, n, m, imin, imax, jnm, jnv;
cin >> n >> m;
int k[n][m];
int max = 0;
int min = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cout << "a[" << i << "][" << j << "]" << endl;
cin >> k[i][j];
}
}
cout << endl
<< endl;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cout << k[i][j];
}
cout << endl;
}
cout << endl
<< endl;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (k[i][j] > max) {
max = k[i][j];
imax = i;
}
}
cout << endl;
}
min = max;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (k[i][j] < min) {
min = k[i][j];
imin = i;
}
}
cout << endl;
}
cout << endl
<< endl;
if (imax == imin) {
cout << endl
<< "Min & Max are in the same row!" << endl;
}
else {
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (i == imax) {
k[i][j] = k[imin][j];
}
else if (i == imin) {
k[i][j] = k[imax][j];
}
cout << k[i][j];
}
cout << endl;
}
}
return 0;
}
I know the code isn't the cleanest and most professionally written, and that isn't important, as I'm currently preparing for a coding competition where the only thing that matters is functionality of the program.
When I execute this program, it usually swaps one row but the other is still the same.
You could use function swapif you want to swap. At the moment you assignments are wrong.
So, simply write:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int i, j, n, m, imin=0, imax=0;
cin >> n >> m;
vector<vector<int>> k(n, vector<int>(m, 0));
int max = 0;
int min = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cout << "a[" << i << "][" << j << "]" << endl;
cin >> k[i][j];
}
}
cout << endl
<< endl;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cout << k[i][j] << ' ';
}
cout << endl;
}
cout << endl
<< endl;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (k[i][j] > max) {
max = k[i][j];
imax = i;
}
}
cout << endl;
}
min = max;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (k[i][j] < min) {
min = k[i][j];
imin = i;
}
}
cout << endl;
}
cout << endl
<< endl;
if (imax == imin) {
cout << endl
<< "Min & Max are in the same row!" << endl;
}
else {
for (j = 0; j < m; j++)
swap(k[imin][j], k[imax][j]);
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
cout << k[i][j] << ' ';
}
cout << endl;
}
}
return 0;
}
And sorry, I cannot write int k[n][m]; because this is not C++ and my compiler cannot compile it. But vector can be used in the same way.
If you are not allowed to use std::swapyou can use instead:
for (j = 0; j < m; j++) {
int tmp = k[imin][j];
k[imin][j] = k[imax][j];
k[imax][j] = tmp;
}
For the competition you could also get the min and max values already during input and write:
#include <iostream>
#include <vector>
#include <algorithm>
#include <limits>
int main()
{
// Read matrix size
size_t rows{}, columns{};
if (std::cin >> rows >> columns) {
// Here we will store our matrix
std::vector<std::vector<int>> matrix(rows, std::vector<int>(columns, 0));
// Initilize min max values
int maxElement = std::numeric_limits<int>::min();
int minElement = std::numeric_limits<int>::max();
size_t indexMaxRow{}, indexMinRow{};
// Enter values in matrix
for (size_t row{}; row < rows; ++row) {
for (size_t column{}; column < columns; ++column) {
std::cout << "array[" << row << "][" << column << "]\n";
if (std::cin >> matrix[row][column]) {
// Already during input find the min and max values
if (matrix[row][column] > maxElement) {
maxElement = matrix[row][column];
indexMaxRow = row;
}
if (matrix[row][column] < minElement) {
minElement = matrix[row][column];
indexMinRow = row;
}
}
}
}
// Show original matrix
std::cout << "\n\n\nYou entered:\n\n";
for (const auto& row : matrix) {
for (const auto& col : row) std::cout << col << ' ';
std::cout << '\n';
}
// Swap
std::swap(matrix[indexMaxRow], matrix[indexMinRow]);
// Show swapped matrix
std::cout << "\n\n\nSwapped:\n\n";
for (const auto& row : matrix) {
for (const auto& col : row) std::cout << col << ' ';
std::cout << '\n';
}
}
else std::cerr << "\nError while reading size\n";
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have written next code but 3 functions must be replaced by 1 and I don't know how to.
The program creates 3 arrays but only 1 function must calculate negative numbers of each column and find the max element in each column. Here's the code:
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
int n = 0;
const int m = 3, k = 3, b = 4, u = 5;
int i, j;
void calc(float** array, int i, int j );
void calc1(float** array, int i, int j);
void calc2(float** array, int i, int j);
int main()
{
float** array = new float* [m];
for (int l = 0; l < m; l++) {
array[l] = new float[k];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
array[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < k; j++) {
cout << setprecision(2) << setw(4) << array[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(array, i, j); // FUNCTION !!!
float** arr = new float* [b];
for (int l = 0; l < b; l++) {
arr[l] = new float[b];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < b; i++) {
for (int j = 0; j < b; j++) {
arr[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < b; i++)
{
for (int j = 0; j < b; j++) {
cout << setprecision(2) << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(arr, i, j); // FUNCTION !!!
float** ar = new float* [u];
for (int l = 0; l < u; l++) {
ar[l] = new float[u];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < u; i++) {
for (int j = 0; j < u; j++) {
ar[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < u; i++)
{
for (int j = 0; j < u; j++) {
cout << setprecision(2) << setw(4) << ar[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc2(ar, i, j); // FUNCTION !!!
}
void calc(float** array, int i, int j) {
int max = array[0][0];
for (int j = 0; j < k; j++)
{
max = array[0][0];
for (int i = 0; i < k; i++) {
if (array[i][j] > max)
max = array[i][j];
if (array[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
void calc1(float** arr, int i, int j) {
int max = arr[0][0];
for (int j = 0; j < b; j++)
{
max = arr[0][0];
for (int i = 0; i < b; i++) {
if (arr[i][j] > max)
max = arr[i][j];
if (arr[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
void calc2(float** ar, int i, int j) {
int max = ar[0][0];
for (int j = 0; j < u; j++)
{
max = ar[0][0];
for (int i = 0; i < u; i++) {
if (ar[i][j] > max)
max = ar[i][j];
if (ar[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
The parameters to calc() should be the number of rows and columns in the array. Then it should use these as the limits in the for loops.
Also, since you're calculating total negative and maximum for each column, you must reset these variables each time through the column loop.
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
const int m = 3, k = 3, b = 4, u = 5;
void calc(float** array, int rows, int cols);
int main()
{
float** array = new float* [m];
for (int l = 0; l < m; l++) {
array[l] = new float[k];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
array[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < k; j++) {
cout << setprecision(2) << setw(4) << array[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(array, m, k); // FUNCTION !!!
float *arr = new float* [b];
for (int l = 0; l < b; l++) {
arr[l] = new float[b];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < b; i++) {
for (int j = 0; j < b; j++) {
arr[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < b; i++)
{
for (int j = 0; j < b; j++) {
cout << setprecision(2) << setw(4) << arr[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(arr, b, b); // FUNCTION !!!
float** ar = new float* [u];
for (int l = 0; l < u; l++) {
ar[l] = new float[u];
}
// заполнение массива
srand(time(0));
for (int i = 0; i < u; i++) {
for (int j = 0; j < u; j++) {
ar[i][j] = rand() % 21 - 10;
}
}
cout << "The initial array is: " << endl << endl;
for (int i = 0; i < u; i++)
{
for (int j = 0; j < u; j++) {
cout << setprecision(2) << setw(4) << ar[i][j] << " ";
}
cout << endl;
}
cout << endl << "The amount of negative elements in each column: ";
calc(ar, u, u); // FUNCTION !!!
}
void calc(float** array, int rows, int cols) {
for (int j = 0; j < cols; j++)
{
int n = 0;
int max = array[0][j];
for (int i = 1; i < rows; i++) {
if (array[i][j] > max)
max = array[i][j];
if (array[i][j] < 0) {
n += 1;
}
}
cout << endl << "IN the [" << j + 1 << "] column is " << n << " negative elements" << endl << endl; n = 0;
cout << "IN the [" << j + 1 << "] column is " << max << " maximal element" << endl;
}
}
learning graph theory in c++ here.
Sorry for the C-style codes.
I got an segmentation fault of my codes. I understand the meaning of it but have not learnt how to debug with IDE yet.
However I feel the bug is somewhere in my spanningtree() function. Could anyone point me out what could went wrong? The program is meant to print out the cost matrix, the minimum distance path and the total path cost. However, it exited after inputting.
#include <iostream>
using namespace std;
class prims
{
private:
int no_of_edges, no_of_nodes;
int graph[10][10],visited[10],mindist[10];
public:
void input();
void output();
void spanningtree();
prims()
{
no_of_edges = no_of_nodes = 0;
for (int i = 0; i<10; i++)
{
//assign visited minimum distance array to 0
visited[i] = mindist[i] = 0;
for (int j = 0; j<10; j++)
{
graph[i][j] = 0;
}
}
}
};
void prims::input()
{
int vertex1, vertex2, cost;
cout << "Enter no_of_nodes ";
cin >> no_of_nodes;
cout << "Enter the no_of_edges ";
cin >> no_of_edges;
for (int i = 0; i< no_of_edges; i++)
{
cout << "Enter vertex1 ";
cin >> vertex1;
cout << "Enter vertex2 ";
cin >> vertex2;
cout << "Enter the cost of " << vertex1 << " and " << vertex2 << " ";
cin >> cost;
graph[vertex1][vertex2]=graph[vertex2][vertex1]=cost;
}
}
void prims::output()
{
for (int i = 0; i < no_of_nodes; i++)
{
cout << endl;
for (int j = 0; j< no_of_nodes; j++)
{
cout.width(4);
cout << graph[i][j];
}
}
}
void prims::spanningtree()
{
int min = 9999, row, col, index = 0;
for (int i = 0; i < no_of_nodes; i++)
{
for(int j = i; j < no_of_nodes; j++)
{
if(graph[i][j]<min&&graph[i][j]!=0)
{
min = graph[i][j];
row = i;
col = j;
}
}
}
visited[row]=visited[col]=1;
mindist[index++]=min;
for (int i = 0; i < no_of_nodes - 2; i++)
{
min = 9999;
for (int j = 0; j < no_of_nodes; j++)
{
if(visited[j]==1)
{
for(int k = 0; j < no_of_nodes; k++)
{
if(graph[j][k]<min&&graph[j][k]!=0 && visited[k]==0)
{
min = graph[j][k];
row = j;
col = k;
}
}
}
}
mindist[index++]=min;
visited[row]=visited[col]=1;
}
int total = 0;
cout << endl;
cout << "Minimum distance path is ";
for (int i=0; i < no_of_nodes-1; i++)
{
cout << " " << mindist[i] << " ";
total = total + mindist[i];
}
cout << endl << "Total path cost is " << total;
}
int main()
{
prims obj;
obj.input();
obj.spanningtree();
obj.output();
return 0;
}
Taking some credits from the helpful comments/answers. Here is my revised codes. The main issue was the typo in one of the loop for(int k = 0; j < no_of_nodes; k++).
using namespace std;
class prims
{
private:
int no_of_edges, no_of_nodes;
int graph[10][10],visited[10],mindist[10];
public:
void input();
void output();
void spanningtree();
prims()
{
no_of_edges = no_of_nodes = 0;
for (int i = 0; i<10; i++)
{
//assign visited minimum distance array to 0
visited[i] = mindist[i] = 0;
for (int j = 0; j<10; j++)
{
graph[i][j] = 0;
}
}
}
};
void prims::input()
{
int vertex1, vertex2, cost;
cout << "Enter no_of_nodes ";
cin >> no_of_nodes;
cout << "Enter the no_of_edges ";
cin >> no_of_edges;
for (int i = 0; i< no_of_edges; i++)
{
cout << "Enter vertex1 ";
cin >> vertex1;
cout << "Enter vertex2 ";
cin >> vertex2;
cout << "Enter the cost of " << vertex1 << " and " << vertex2 << " ";
cin >> cost;
graph[vertex1][vertex2]=graph[vertex2][vertex1]=cost;
}
}
void prims::output()
{
for (int i = 0; i < no_of_nodes; i++)
{
cout << endl;
for (int j = 0; j< no_of_nodes; j++)
{
cout.width(4);
cout << graph[i][j]<<" ";
}
}
}
void prims::spanningtree()
{
int min = 9999, row, col, index = 0;
for (int i = 0; i < no_of_nodes; i++)
{
for(int j = i; j < no_of_nodes; j++)
{
if(graph[i][j]<min&&graph[i][j]!=0)
{
min = graph[i][j];
row = i;
col = j;
}
}
}
visited[row]=visited[col]=1;
mindist[index++]=min;
for (int i = 0; i < no_of_nodes - 2; i++)
{
min = 9999;
for (int j = 0; j < no_of_nodes; j++)
{
if(visited[j]==1)
{
for(int k = 0; k < no_of_nodes; k++)
{
if(graph[j][k]<min&&graph[j][k]!=0 && visited[k]==0)
{
min = graph[j][k];
row = j;
col = k;
}
}
}
}
mindist[index++]=min;
visited[row]=visited[col]=1;
}
int total = 0;
cout << endl;
cout << "Minimum distance path is ";
for (int i=0; i < no_of_nodes-1; i++)
{
cout << " " << mindist[i] << " ";
total = total + mindist[i];
}
cout << endl << "Total path cost is " << total << endl;
}
int main()
{
prims obj;
obj.input();
obj.spanningtree();
obj.output();
// return 0;
}
Your primary problem is not checking that indexes are in range (there is where c++ might help, but you can do it in c as well). Primary debugging tool - print. If you would print j and k before using them as array indexes you would solve your problem yourself
So, I am trying to implement this algorithm from our textbook.
I wrote this :
// Knapsack_memoryfunc.cpp : Defines the entry point for the console application.
//Solving Knapsack problem using dynamic programmig and Memory function
#include "stdafx.h"
#include "iostream"
#include "iomanip"
using namespace std;
int table[20][20] = { 0 };
int value, n, wt[20], val[20], max_wt;
// ---CONCERNED FUNCTION-----
int MNSack(int i, int j)
{
value = 0;
if (table[i][j] < 0)
if (j < wt[i])
value = MNSack(i - 1, j);
else
value = fmax(MNSack(i - 1, j), val[i] + MNSack(i - 1, j - wt[i]));
table[i][j] = value;
return table[i][j];
}
// --------------------------
void items_picked(int n, int max_wt)
{
cout << "\n Items picked : " << endl;
while (n > 0)
{
if (table[n][max_wt] == table[n - 1][max_wt]) // if value doesnot change in table column-wise, item isn't selected
n--; // n-- goes to next item
else // if it changes, it is selected
{
cout << " Item " << n << endl;
max_wt -= wt[n]; // removing weight from total available (max_wt)
n--; // next item
}
}
}
int main()
{
cout << " Enter the number of items : ";
cin >> n;
cout << " Enter the Maximum weight : ";
cin >> max_wt;
cout << endl;
for (int i = 1; i <= n; i++)
{
cout << " Enter weight and value of item " << i << " : ";
cin >> wt[i] >> val[i];
}
for (int i = 0; i <= n; i++)
for (int j = 0; j <= max_wt; j++)
table[i][j] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= max_wt; j++)
table[i][j] = -1;
cout << " Optimum value : " << MNSack(n, max_wt);
cout << " \n Table : \n";
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= max_wt; j++)
if (table[i][j] == -1)
cout << setw(5) << "-";
else
cout << setw(5) << table[i][j];
cout << endl;
}
items_picked(n, max_wt);
return 0;
}
Here is the question and output :
It seems like its correct on some places like optimum value, yet isn't fully acceptable.
I've tried to debug it, but its quite hard with recursive functions. Can someone please help?
int MNSack(int i, int j)
{
value = 0;
if (table[i][j] < 0)
{
if (j < wt[i])
value = MNSack(i - 1, j);
else
value = max(MNSack(i - 1, j), val[i] + MNSack(i - 1, j - wt[i]));
table[i][j] = value;
}
return table[i][j];
}
The problem comes in here. When your table item is greater or equal to 0, you will skip the recursion but still set the table item to 0, which won't be right if your table item is greater than 0.
You only need to update the table item when it needs to be change, so put it in the braces will correct this.
The bottom up solution.
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
int main()
{
int table[20][20] = { 0 };
int value, n, wt[20], val[20], max_wt;
cout << " Enter the number of items : ";
cin >> n;
cout << " Enter the Maximum weight : ";
cin >> max_wt;
cout << endl;
for (int i = 1; i <= n; i++)
{
cout << " Enter weight and value of item " << i << " : ";
cin >> wt[i] >> val[i];
}
// Initialization
for (int i = 0; i <= n; i++)
for (int j = 0; j <= max_wt; j++)
table[i][j] = 0;
// In practice, this can be skipped in a bottom up solution
for (int i = 1; i <= n; i++)
for (int j = 1; j <= max_wt; j++)
table[i][j] = -1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= max_wt; j++)
{
if (j < wt[i])
table[i][j] = table[i - 1][j];
else
table[i][j] = max(table[i - 1][j], val[i] + table[i - 1][j - wt[i]]);
}
}
cout << " Optimum value : " << table[n][max_wt] << endl;
cout << " \n Table : \n";
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= max_wt; j++)
if (table[i][j] == -1)
cout << setw(5) << "-";
else
cout << setw(5) << table[i][j];
cout << endl;
}
return 0;
}
You can see that this changes the recursion to a loop, and therefore avoids the global variables. It also makes the code simpler, so that you can avoid checking if the table item is valid (equal to -1 in your example).
The drawback of this solution is, it always traverses all the possible nodes. But it gains better coefficient per item because the recursion and double checking the table item costs more. Both top-down and bottom-up have the same order of complexity O(n^2), and it's hard to tell which one is faster.