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
Related
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";
}
Let the matrix have 4 verticles and 4 edge: (1,2),(1,4),(2,3),(2,4). I need to fill Adjacency (I did) and transform this Adjacency matrix to Incidence matrix. The result should be a matrix Incidence={(0111),(1010),(1101),(1010)} What is the best algorithm. I can't find a solution, all ideas are with bugs. :-( Thanks
#include "iostream"
#include "conio.h"
#include <stdlib.h>
using namespace std;
struct Rebro {
int x=0;
int y=0;
};
int main()
{
int Graph[100][100], Vertex, Edge, x, y;
int VG, EG;
int Incidence[100][100];
cout << "Enter number of vertexes:";
cin >> Vertex;
cout << "\nEnter number of edges:";
cin >> Edge;
//_________________________NULL
for (int i = 1; i <= Vertex; i++)
for (int j = 1; j <= Vertex; j++)
{
Graph[i][j] = 0;
}
//_________________________NULL
for (int i = 1; i <= Vertex; i++)
for (int j = 1; j <= Vertex; j++)
{
Incidence[i][j] = 0;
}
//_________________________INPUT
Rebro mass[100];
cout << "\nEnter edges:\n " << endl;
for (int i = 1; i <= Edge; i++)
{
cout << "e1=";
cin >> x;
cout << "e2=";
cin >> y;
cout << endl;
Graph[x][y] = 1;
Graph[y][x] = 1;
mass[i].x =x ;
mass[i].y =y ;
}
//_________________________OUTPUT
cout << "\nAdjacency matrix:\n" << endl;
for (int i = 1; i <= Vertex; i++)
{
for (int j = 1; j <= Vertex; j++)
{
cout <<" "<< Graph[i][j];
}
cout << endl;
}
cout << endl;
for (int i = 1; i <= Edge; i++) {
Incidence[i][mass[i].x] = 1;
Incidence[i][mass[i].y] = 1;
}
//_________________________OUTPUT
cout << "\nIncidence matrix:\n" << endl;
int count = 0;
for (int j = 1; j <= Vertex; j++)
{
for (int i = 1; i <= Vertex; i++)
{
cout << " " << Incidence[i][j];
}
cout << endl;
}
cout << endl;
_getch();
}
OR generally a wrong idea:
#include "iostream"
#include "conio.h"
#include <stdlib.h>
using namespace std;
int main()
{
int Graph[100][100], Vertex, Edge, x, y;
int VG, EG;
int Incidence[100][100];
cout << "Enter number of vertexes:";
cin >> Vertex;
cout << "\nEnter number of edges:";
cin >> Edge;
//_________________________NULL
for (int i = 1; i <= Vertex; i++)
for (int j = 1; j <= Vertex; j++)
{
Graph[i][j] = 0;
}
//_________________________NULL
for (int i = 1; i <= Vertex; i++)
for (int j = 1; j <= Vertex; j++)
{
Incidence[i][j] = 0;
}
//_________________________INPUT
cout << "\nEnter edges:\n " << endl;
for (int i = 1; i <= Edge; i++)
{
cout << "e1=";
cin >> x;
cout << "e2=";
cin >> y;
cout << endl;
Graph[x][y] = 1;
Graph[y][x] = 1;
}
//_________________________OUTPUT
cout << "\nAdjacency matrix:\n" << endl;
for (int i = 1; i <= Vertex; i++)
{
for (int j = 1; j <= Vertex; j++)
{
cout <<" "<< Graph[i][j];
}
cout << endl;
}
cout << endl;
for (int i =1; i<=Edge; i++) {
for (int j=1; j<=Edge; j++) {
if (Graph[x][y]==1) {
if ((i==x)||(i==y)||(j==x)||(j==y)) {
Incidence[i][j]==1;
Incidence[j][i]==1;
}
else {
Incidence[i][j]==0;
Incidence[j][i]==0;
}
}
}
}
//_________________________OUTPUT
cout << "\nIncidence matrix:\n" << endl;
int count = 0;
for (int j = 1; j <= Vertex; j++)
{
for (int i = 1; i <= Vertex; i++)
{
cout << " " << Incidence[i][j];
}
cout << endl;
}
cout << endl;
_getch();
}
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();
so i got this code.
int n;
int m=1;
int a=9;
cout<<"Enter N Number = ";
cin>>n;
n=n*2-1;
for(int y=1;y<=n;y++)
{
for(int x=1;x<=n;x++)
{
if(x==y+n/2 || x==y-n/2 || x==n-y+1-n/2 || x==n-y+1+n/2)
{
if(m<=9)
{
cout<<m++;
}
else if(m>9&&a>0)
{
a--;
cout<<a;
}
}
else
{
cout<<" ";
}
}
cout<<endl;
}
This is what i get :
Diamond Shape(Fail)
And what i expected is there's no number "0" on the bottom of the shape, so after it printed the number 1 its bounce back to number 2,3 and so on
pardon for my bad english
Do you want it to be like this?
Check this out!
I can code in Pascal, C++ and Java.
PS: I am not a native English speaker too.
First Answer: This is not the best answer, I will improve it tomorrow afternoon.
#include <iostream>
using namespace std;
int get() {
static int counter = 0;
static bool reverse = false;
!reverse ? counter++ : counter--;
if (counter==10 or counter==0) reverse = !reverse;
counter==10 ? counter = 8 : 0;
counter==0 ? counter = 2 : 0;
return counter;
}
int main() {
int number;
cout << "Enter N Number = ";
cin >> number;
//forward:
for (int i = 0; i < number; i++) {
for (int j = number-i-1; j > 0; j--)
cout << " ";
cout << get();
if (i!=0) {
for (int j = 0; j < i * 2 -1; j++) cout << " ";
cout << get();
}
cout << endl;
}
//backward:
for (int i = number-1; i > 0 ; i--) {
for (int j = number-i; j > 0; j--)
cout << " ";
cout << get();
if (i!=1) {
for (int j = i * 2 -3; j > 0; j--) cout << " ";
cout << get();
}
cout << endl;
}
return 0;
}
Second Answer: Improved loops
#include <iostream>
using namespace std;
int nextNumber() {
static int counter = 0;
static bool reverse = true;
!reverse ? counter++ : counter--;
if (counter==-1) counter=1;
if (counter==9 or counter==1) reverse = !reverse;
return counter;
}
int main() {
int number;
cout << "Enter N Number = ";
cin >> number;
int space = number;
int middle = -3;
for (int row = 0; row < number*2-1; row++) {
if(row<number) {
space--;
middle += 2;
}
else {
space++;
middle -= 2;
}
for (int i = 0; i < space; i++)
cout << " ";
cout << nextNumber();
if(row!=0 and row!=number*2-2) {
for (int i = 0; i < middle; i++)
cout << " ";
cout << nextNumber();
}
cout << endl;
}
return 0;
}
So me and my group have been working on this project for a few days we can get the top part too draw when we step into it but it does not run and we are not sure why it wont.
The first function is to draw the top and the second is to draw the bottom.
The top seems to draw fine i am not sure why the code will not even run.
#include<iostream>
using namespace std;
void drawTopPart(int userNum);
void drawBottomPart(int userNum);
int main() {
//declarations
int userNum;
//get user input
cout << "Enter an odd number from 1 to 15: ";
cin >> userNum;
//output
drawTopPart(userNum);
drawBottomPart(userNum);
cout << endl;
system("pause");
return 0;
}
void drawTopPart(int userNumPar) {
int z = 1;
int size;
cin >> size;
for (int i = 0; i <= size; i++) {
for (int j = size; j>i; j--) {
cout << " ";
}
cout << "*";
if (i>0) {
for (int k = 1; k <= z; k++) {
cout << " ";
} z += 2; cout << "*";
}
cout << endl;
}
}
void drawBottomPart(int userNumPar){
int z -= 4;
int size;
cin >> size;
for (int i = 0; i <= size - 1; i++) {
for (int j = 0; j <= i; j++) {
cout << " ";
}
cout << "*";
for (int k = 1; k <= z; k++) {
cout << " ";
}
z -= 2;
if (i != size - 1) {
cout << "*";
}
}
You have two mainly errors.
First,
void drawBottomPart(int userNumPar){
int z -= 4;
int size;
int z -= 4; have syntax error.You can change it int z = 17;
Second,you forget endl here.
if (i != size - 1) {
cout << "*";
}
cout << endl;