C programming two-hop neighbors - c

I am not sure how to get my two-hop neighbors correctly. It's almost correct but on my output, I don't want to include the same vertex. For my output now if vertex 0 is 0, it says "vertex 0: 0.....
I want to skip the vertex it is currently looking at.
Please help me, are my codes for two hop wrong?
this is my codes:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define M 20
#define N 20
int main()
{
int i, j, x, a, b;
int G[20][20] = { { 0 } };
/*creaate random adjaceney matrix*/
printf("==================================================\n");
printf("Welcome to my Graph Processing tool!\n\n");
srand(time(NULL));
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
if (i == j) {
G[i][j] = 0;
}
else {
G[i][j] = rand() % 2;
G[j][i] = G[i][j];
}
}
}
/*check whether the whole row equals to 0*/
for (j = 0; j < N; j++) {
if (G[j] == 0) {
x = rand() % 20 + 1;
G[x][j] = G[j][x] = 1;
}
/*print the matrix G*/
else
{
printf("The adjacency for graph G is\n");
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
printf("%d ", G[i][j]);
}
printf("\n");
}
}
}
/*all one-hop neighbors*/
printf("\nList of one-hop neighbors:");
for (i = 0; i < M; i++) {
printf("\nVertex %d: ", i);
for (j = 0; j < N; j++) {
if (G[i][j] == 1) {
printf("%d ", j);
}
}
}
printf("\n===================================\n\n");
/*two-hop neighbors*/
for (i = 0; i < M; i++) {
printf("\nVertex %d: ", i);
for (j = 0; j < N; j++) {
if (G[i][j] == 0) {
printf("%d ", j);
}
}
}
}
printf("\n============================================\n");
system("pause");
return 0;
}
This is my output:
One hop
Two hop

The answer provided by #Jake only works for node 0. For only looking at different nodes you need to do
for (j = 0; j < N; j++) {
if (i != j && G[i][j] == 0) {
printf("%d ", j);
}
}
Furthermore, you are assuming that all nodes without an edge are two-hop neighbors. This is not correct. One way to calculate the actual two-hop neighbors would be ((A + I)^2 > 0) - ((A + I) > 0), where I is the identity matrix.
Also, you can code this via a three-layer loop:
int node, neighbor, neighbor2;
for (node = 0; node < N; node++) {
printf("\nVertex %d: ", node);
for (neighbor = 0; neighbor < N; neighbor++) {
if (G[node][neighbor] == 1) {
for (neighbor2 = 0; neighbor2 < N; neighbor2++) {
if (node != neighbor2 && G[neighbor][neighbor2] == 1) {
printf("%d ", neighbor2);
}
}
}
}
}
Note that per definition M=N, so I've just used N. Also, this might print some 2-hop neighbors twice. You might want to do some filtering before printing.

Couple things to note here.
Be more descriptive with your variable naming, it would have made this a lot easier to read.
M-ROWS, N-COLS, G-Graph
When you loop through each row, you initialize j to 0. This includes the vertex that you are wanting to leave out.
for (j = 1; j < N; j++)

Related

How to transpose a matrix without using another matrix?

Write a program which will accept 2-dimensional square matrix and find out the transpose of it.
Program should not make use of another matrix
Hi I am trying to transpose a 2*2 matrix without using another matrix.
Is there anything wrong with my transpose logic?
I am a newbie
#include <stdio.h>
int main()
{
int mat[2][2];
int i, j, temp;
for (i = 0; i < 2; i++) {
printf("\nEnter elements of %d row of first matrix: ", i + 1); //i+1 so that it can print 1 row, 2 row, 3 row etc
for (j = 0; j < 2; j++) { //loop inside to loop to get value for a[0][0],a[0][1],a[0][2]
scanf("%d", &mat[i][j]);
}
}
printf("The matrix\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[i][j]);
}
printf("\n");
}
//transpose logic using same matrix
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
temp = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = temp;
}
}
printf("The transpose of the matrix is\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[i][j]);
}
printf("\n");
}
}
EDIT: I found an easier way to do it however I still don't understand why my transpose logic by using this
temp = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = temp;
cannot get it to transpose.
Below is my corrected answer
#include <stdio.h>
int main()
{
int mat[2][2];
int i, j, temp;
for (i = 0; i < 2; i++) {
printf("\nEnter elements of %d row of first matrix: ", i + 1);//i+1 so that it can print 1 row, 2 row, 3 row etc
for (j = 0; j < 2; j++) {//loop inside to loop to get value for a[0][0],a[0][1],a[0][2]
scanf("%d", &mat[i][j]);
}
}
printf("The matrix\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[i][j]);
}
printf("\n");
}
printf("The transpose of the matrix is\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[j][i]);
}
printf("\n");
}
}
Your program is a good attempt, but transposing the matrix is like reversing an array: you must stop half way to avoid swapping the transposed values twice, leading to the original matrix as you observe.
You should stop the inner loop when j == i, hence change the inner loop to:
for (j = 0; j < i; j++) { // j < i instead of j < 2
Here is a modified version:
#include <stdio.h>
int main() {
int mat[2][2];
int i, j, temp;
for (i = 0; i < 2; i++) {
printf("\nEnter elements of %d row of first matrix: ", i + 1);
for (j = 0; j < 2; j++) {
if (scanf("%d", &mat[i][j]) != 1)
return 1;
}
}
printf("The matrix:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[i][j]);
}
printf("\n");
}
//transpose logic using same matrix
for (i = 0; i < 2; i++) {
for (j = 0; j < i; j++) {
temp = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = temp;
}
}
printf("The transpose of the matrix is:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%d\t", mat[i][j]);
}
printf("\n");
}
return 0;
}
Your corrected answer does not transpose the matrix at all, it merely outputs the transposed matrix. The matrix mat in memory is unchanged.

Finding duplicate value in a row (2D array)

I would like to know how to find duplicate values in the 1st row of my 2d array.
I thought that by setting array[0][0] == array[i][j], it would check if the array[0][0] equals to the number of array[0][rest of the column]. But my code is just popping up my try again message whenever I put my first value.
Here's what I've tried so far.
void main(void)
{
int array[2][5];
int i, j, l, k;
printf("\Please enter 10 values\n");
for (j = 0; j < 5; j++)
{
for (i = 0; i < 2; i++)
{
scanf("%i", &array[i][j]);
for (k = 0; k < 2; k++)
{
for (l = 0; l < 5; l++)
{
while (array[0][0] == array[i][j])
{
printf("You entered 2 identical numbers in the first row, try again:\n");
scanf("%i", &array[i][j]);
}
}
}
}
}
}
// this isn't the fastest algorithm but it works because of the small length
int check_duplicates(int arr[], int len) {
// iterate through the array
for (int i = 0; i < len; i++) {
// only need to check to the right
// since the left elements have been checked previously
for (int j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
// there's a duplicate, return
return 1;
}
}
}
// no duplicates found
return 0;
}
int main(void) {
int array[2][5];
int i, j, l, k;
printf("Please enter 10 values\n");
for (j = 0; j < 5; j++) {
for (i = 0; i < 2; i++) {
scanf("%i", &array[i][j]);
// a duplicate has been found
if (check_duplicates(array[0], j + 1)) {
printf("You entered a duplicate, try again.\n");
// undo one loop to read back into that position
i --;
}
}
}
return 0;
}

How to implement check for distinctness

I have a function that reads in a line of ints as an array. I would like to implement an additional check for distinctness in the elements. I am already checking to make sure the array values don't equal the element number.
I tried nesting another for loop to run the check within the other check but I couldn't get it to work properly.
int readArray(int r[SIZE]) {
int i;
for (i = 0; i < SIZE; i++) {
scanf("%d", r + i);
// check for error element number
if (i == r[i]) {
printf("Error: element[%d] == %d\n", i, i);
return 0;
}
}
return 1;
}
I expect the function to output an error if there is a duplicate value or if the element number and value are equal.
My working solution is listed below I would like to make it a bit more concise is possible.
int i,j;
for (i = 0; i < SIZE; i++) {
scanf("%d", r + i);
// check for error
if (i == r[i]) {
printf("Error: Element[%d] == %d\n", i, i);
return 0;
}
}
// check for distinctness
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if(i != j)//check indexes
{
if (r[i] == r[j])
{
printf("Two elements repeat to %d" , i);
printf("\nBad input exiting program");
return 0;
}
}
}
}
return 1;
}
Maybe it's not more concise, but if you want something more efficient, how about this:
...
for (i = 0; i < SIZE; i++)
{
for (j = i; j < SIZE; j++)
...
That way, you skip the comparisons you already made ;)
EDIT: Oh, even better:
...
for (j = i+1; j < SIZE; j++)
...
That way, you get rid of the:
if(i != j)

Duplicated output values

I want to display the calendar data in ascending order.
If the date appears several times I need to display it once.
The code works if the date appears five or less times in the input,
if the date appears more than five times at the output it will show up twice.
I don't see the error.
#include <stdio.h>
#include <stdlib.h>
struct date {
int zi;
int luna;
};
int main() {
int n, i, j, k = 0, l;
char c;
scanf("%d", &n);
struct date v[100];
for (i = 0; i < n; i++) {
scanf("%d %c %d", &v[i].zi, &c, &v[i].luna);
}
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (v[i].luna > v[j].luna) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
} else if (v[i].luna == v[j].luna && v[i].zi > v[j].zi) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
}
}
}
printf("\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
for (i = 0; i < n; i++) {
if (v[i].luna < 10 && v[i].zi >= 10) {
printf("%d-0%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna >= 10) {
printf("0%d-%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna < 10) {
printf("0%d-0%d\n", v[i].zi, v[i].luna);
} else
printf("%d-%d\n", v[i].zi, v[i].luna);
}
}
The problem seems to be this block:
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
When you remove a duplicate (i.e. by shifting all elements towards the start and decrementing n) you still increment j. Consequently, your loop will skip one element and you may end up with duplicates.
The solution could be as simple as decrementing j at the same time as you decrement n.
BTW: It seems strange that the j-loop start from zero. I would expect it to start from i+1

Wrong output when printing a tent shape with stars

I'm trying to print out a hollow, open tent shape using asterisk stars "*". The code uses two for loops, the first for the rows, and the other for the columns.
following is my code:
void printTent(int n)
{
int j = 1;
int i = 1;
if (n == 1) {
printf("*");
} else {
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
printf(" ");
}
if(j == n) {
printf("*");
for(j = 1; j <= n; j++) {
printf(" ");
}
}
}
}
}
int main()
{
printTent(4);
}
Output obtained:
* * * *
Desired output:
*
* *
* *
* *
I don't think you will need that
if (n == 1) {
printf("*");
}
We can take care of that in what you've written in the else part.
For n=4, the number of spaces to be printed at the start of each line is 3, 2, 1 & 0.
You seem to be trying to accomplish that with your first inner loop. But
for(j = 0; j < n; j++) {
printf(" ");
}
will always print n spaces. We need to reduce the number of spaces printed by 1 on each iteration of the outer loop.
Coming to your second loop,
for(j = 1; j <= n; j++) {
printf(" ");
}
This has a similar problem only difference being the incrementation of the number of spaces printed.
Try something like this
void printTentNMMod(int n)
{
int j;
int i;
for(i = 0; i < n; i++) {
for(j = i; j < n; j++) {
printf(" ");
}
printf("*");
if(i!=0)
{
for(j=0; j<2*(i-1)+1; ++j)
{
printf(" ");
}
printf("*");
}
printf("\n");
}
}
Also, you could shorten this to
void printTent(int n)
{
int j;
int i;
for(i = 0; i < n; i++) {
printf("%*c", n-i, '*');
if(i!=0)
{
printf("%*c", 2*i, '*');
}
printf("\n");
}
}
The * in %*c will set the number of places occupied by the character printed by the %c.
I've finished it and I have written annotation.
void printTent(int n)
{
int j = 1;
int i = 1;
if (n == 1) {
printf("*");
}
else {
for (i = 0; i < n; i++) {
for (j = 0; j < n -i; j++) {// you should use n-i instead of n because the number of spaces is decreasing
printf(" ");
}
if (j == n-i) { //
printf("*");
for (j = 1; j <= i * 2 - 1; j++)//this loop outputs spaces between two "*"
{
printf(" ");
}
if (i != 0)//the first line only needs one "*"
printf("*");
printf("\n"); //Line breaks
}
}
}
}
Another way.
#include <stdio.h>
int main() {
int i, j;
int height = 5;
for(i = height; i > 0; i--) {
for(j = 1; j < height * 2; j++) {
if(j == i || j == height * 2 - i)
printf("*");
else
printf(" ");
}
puts("");
}
return 0;
}
Output
*
* *
* *
* *
* *

Resources