I have a 2-dimensional array with user-entered values. I need to find sum of the even elements in the diagonal of the array.
I know how to declare the array and get it filled by the user, but I'm not sure what even elements in the main diagonal really means.
I know I can find out if a number is even by saying:
if n / 2 == 0
Once I've reported the sum of the even elements in the diagonal, I would like to replace all 0 values in the array with ones.
Diagonal means all places where x and y cordinates are the same
Do if your array contains:
1 3 8 5
3 3 9 7
4 4 5 7
5 1 7 4
Then the diagonal are in bold.
Assuming the array is a square:
int sum = 0;
for(int i = 0; i < numOfArrayRows; i++)
{
//Use the mod operator to find if the value is even.
if(array[i][i] % 2 == 0)
sum += array[i][i];
//Change 0's to ones
for(int j = 0; j < numOfArrayCols; j++)
if(array[i][j] == 0)
array[i][j] = 1;
}
Also, next time add the "Homework" tag if you have a homework question :P
With a two-dimensional array it's really easy, since you don't need any index magic:
int a[N][N] = ...;
int sum = 0;
for(int i=0; i<N; ++i)
if(a[i][i] % 2 == 0) //or a[i] & 1, if you like, just check if it's dividable by 2
sum += a[i][i];
This C++ code shouldn't be that different in C or C#, but you should get the point. Likewise the second question would be as simple as:
int a[M][N] = ...;
for(i=0; i<M; ++i)
for(j=0; j<N; ++j)
if(a[i][j] == 0)
a[i][j] = 1;
And I suspec that the main diagonal is the one that begins with coordinates 0,0.
To replace 0 elements with 1 you would do something like:
if (array[i,j] == 0) array[i,j] == 1;
This sounds like homework - however I will help out :)
So if you have an 2D array, and in order to find the sum of the diagonal values, you will know that the indices of both of the values would match in order to provide you with each of the diagonal values.
To iterate through these you could use a simple loop that would sum up every diagonal value, as shown:
//Your Sum
int sum = 0;
//This will iterate and grab all of the diagonals
//You don't need to iterate through every element as you only need
//the diagonals.
for(int i = 0; i < sizeOfArray; i++)
{
//This will add the value of the first, second, ... diagonal value to your sum
sum += array[i,i];
}
To set each of the values that is 0 to 1, you could iterate through each element of the array and check if the value is 0, then set that value to 1, for example:
for(int i = 0; i < sizeOfArray; i++)
{
for(int j = 0; j < sizeOfArray; j++)
{
//Check if this value is 0;
//If it is 0, set it to 1, otherwise continue
}
}
int[,] array = new int[,] {{1,2,3},
{4,5,6},
{7,8,9}};
//Suppose you want to find 2,5,8
for(int row = 0; row < 3; row++)
{
for(int column = 0; column < 3; column++)
{
if((row == 0 && column == 1) || (row == 1 && column == 1) || (row == 2 && column == 1))
{
Console.WriteLine("Row: {0} Column: {1} Value: {2}",row + 1, column + 1, array[row, column]);
}
}
}
Here is the code you need, not much explain:
//Read the size of the array, you can get it from .Count() if you wish
int n = Convert.ToInt32(Console.ReadLine());
int[][] a = new int[n][];
//Reading all the values and preparing the array (a)
for (int a_i = 0; a_i < n; a_i++)
{
string[] a_temp = Console.ReadLine().Split(' ');
a[a_i] = Array.ConvertAll(a_temp, Int32.Parse);
}
//performing the operation (google what diagonal matrix means)
int PrimarySum = 0, SecondarySum = 0;
for (int i = 0; i < n; i++)
{
//The If condition is to skip the odd numbers
if (a[i][i] % 2 == 0) { PrimarySum += a[i][i]; }
//For the reverse order
int lastelement = a[i].Count() - 1 - i;
if (a[i][lastelement] % 2 == 0) { SecondarySum += a[i][lastelement]; }
}
//Get the absolute value
Console.WriteLine(Math.Abs(PrimarySum - SecondarySum).ToString());
Console.ReadKey();
Related
I found this code that i need for an assigment, but it only reads odd numbers and i need it to read even numbers too, but i don't know whats wrong. I need it to make the random magic squares go from 1 to 10.
Still very much a beginner and don't understand functions yet, please let me know if there is a way to dolve this.
using System;
class GFG
{
// Function to generate odd sized magic squares
static void generateSquare(int n)
{
int[,] magicSquare = new int[n, n];
// Initialize position for 1
int i = n / 2;
int j = n - 1;
// One by one put all values in magic square
for (int num = 1; num <= n * n;)
{
if (i == -1 && j == n) // 3rd condition
{
j = n - 2;
i = 0;
}
else
{
// 1st condition helper if next number
// goes to out of square's right side
if (j == n)
j = 0;
// 1st condition helper if next number is
// goes to out of square's upper side
if (i < 0)
i = n - 1;
}
// 2nd condition
if (magicSquare[i, j] != 0)
{
j -= 2;
i++;
continue;
}
else
// set number
magicSquare[i, j] = num++;
// 1st condition
j++;
i--;
}
// print magic square
Console.WriteLine("The Magic Square for " + n
+ ":");
Console.WriteLine("Sum of each row or column "
+ n * (n * n + 1) / 2 + ":");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
Console.Write(magicSquare[i, j] + " ");
Console.WriteLine();
}
}
// driver program
public static void Main()
{
Console.WriteLine("Value of n: ");
int n = int.Parse(Console.ReadLine());
// Works only when n is odd
generateSquare(n);
}
}
Step through the program with a debugger. Using n = 2 as an example, on your second loop through the for loop you get to this with i = 1 and j = 1:
if (magicSquare[i, j] != 0)
{
j -= 2;
i++;
continue;
}
And that makes i = 2 on the next loop through. Because there is no 2 index in the array you have created, it crashes when it gets to this same check the next loop.
Presumably odd numbers are working because they are getting floored on division (in the case of n = 5 -> i = 2).
That should be enough to point you in the right direction.
the assignment asks me to find the second lowest number from the user input (max 10), and if a 0 is entered the program should stop and find the second lowest, without counting. But I have to declare the size of the array beforehand.
For example, if I type in 4 7 3 8 0 the program also counts all the 0 until there are 10 numbers so it sees this: 4 7 3 8 0 0 0 0 0 0. Is there a way for me to stop the program from seeing the other 0 or to somehow change the array size?
Edit:
Ok, so here is the code I have so far:
int s;
s = 10;
int[] numbers = new int[s];
for (int i = 0; i < numbers.Length; i++)
{
int.TryParse(Console.ReadLine(), out numbers[i]);
}
int firstLowestNumber = numbers[0];
int secondLowestNumber = numbers[0];
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] < firstLowestNumber)
{
firstLowestNumber = numbers[i];
}
}
for (int x = 0; x < numbers.Length; x++)
{
if (numbers[x] < secondLowestNumber && firstLowestNumber != numbers[x])
{
secondLowestNumber = numbers[x];
}
}
Console.WriteLine("Second Lowest Number is {0}", secondLowestNumber);
Console.ReadLine();
With the initialization of an int-array all numbers will be 0. This means you only need to stop reading when a 0 is given as input.
So a little change in the first foreach will do:
int input;
int.TryParse(Console.ReadLine(), out input);
if (input == 0) break; //This will jump out of the foreach
number[i] = input;
It depends on goal of your homework.
1) Using of Linq (its possible teacher requested this task for you especially to not use a Linq)
using System.Linq;
/*...*/
List<int> ints = new List<int>();
ints.Add(/*...*/);
/*...*/
ints = ints.Where(x => x != 0).ToList();
/*...*/
2) As #Aldert's answer.
3) change printing mechanics of array
int[] ints = new int[10];
foreach (int element in ints) {
if (element == 0)
continue;
Console.Write("{0} ", element);
}
i have a huge Problem when dealing with jagged arrays [][].
I wrote a program that interacts with lots of CSV-files. It will read them and then compare them. Now i have a problem if Array A has the dimension of 10 Rows and 10 Columns but Array B only has the dimension of 5 Rows and 5 Columns. I get the "out of range" on array B. This is only an example it gets even worse if i have a array which has different amount of Rows in each Column...
I tried checking for "null" but this doesnt work since i get the "out of range" once it tries to acess the field...
Now i have 2 theories to solve the problem:
A.)Check for "out of range" in Array B and if so fill Array A at the same field with a "0"
B.) Check if Array A and Array B has same dimension and if not fill the array with lesser amount with "0" so that it has the same amount
On both solutions i have absolutely no clue how to do this in C#... I am always getting the out of range...
What i currently do for 1 array is:
for (int b = CSV_Statistiken.Length - 1; b >= 0; b--)
{
for (int a = 0; a < CSV_Statistiken[b].Length; a++)
{
CSV_Statistiken[b][a] = 1;
}
}
so i get the dimension of the array and iterate through it, setting every value to 1. But how do i deal with my problem with 2 arrays?
I researched a bit but couldnt find any solution to this =/
Thanks in advance
Edit: What i am trying to do for examlple:
for (int i = 0; i < number; i++) //runs through every File existing
{
NextFile = fold.Filepath + "\\" + files[i].ToString();
file = new FileInfo(#NextFile);
max_Rows = 0;
max_Col = 0;
CSV_temp = ReadCSV(file, ref max_Rows, ref max_Col); // reads the next file to an arraay [][] and saves the size of this array in max_col/ max_rows
MAX_Col_Total = GetHighestValues(ref MAX_Col_Total, max_Col);
MAX_Rows_Total = GetHighestValues(ref MAX_Rows_Total, max_Rows);
for (int j = 0; j < MAX_Col_Total; j++) //runs thrugh the max amount of cols found
{
for (int k = MAX_Rows_Total - 1; k >= 0; k--) //runs through the max mount of rows found
{
if (CSV_temp.GetLength(0) >= j && CSV_temp.GetLength(1) >= k)//Checks if Field exists -> does NOT work!
{
if (CSV_temp[k][j] > (Threshhold))) //
{
do something
}
}
else
{
// Field doesnt exists -> do something else
}
}
}
}
You can check Lengths of two arrays in for loops:
for (int a = 0; a < array1.Length && a < array2.Length; a++)
{
for (int b = 0; b < array1[a].Length && b < array2[a].Length; b++)
{
//compare
}
}
Now your loops never go outside of any array index and you won't get IndexOutOfRangeException.
EDIT:
var biggestLength1 = Math.Max(array1.Length, array2.Length);
for (int a = 0; a < biggestLength1; a++)
{
var biggestLength2 = 0;
if (array1.Length > a && array2.Length > a)
{
biggestLength2 = Math.Max(array1[a].Length, array2[a].Length);
}
else
{
biggestLength2 = array1.Length > a ? array1.Length : array2.Length;
}
for (int b = 0; b < biggestLength2; b++)
{
if (a < array1.Length &&
a < array2.Length &&
b < array1[a].Length &&
b < array2[a].Length)
{
// every array has enough elements count
// you can do operations with both arrays
}
else
{
// some array is bigger
}
}
}
given a binary number find the maximum consecutive 1s or 0s that can be obtained by flipping only one bit (either a 1 or a 0)
the code given was
public int getMacCon(string[] A)
{
int n = A.Length;
int result = 0;
for (int i = 0; i < n - 1; i++)
{
if (A[i] == A[i + 1])
result = result + 1;
}
int r = -2;
for (int i = 0; i < n; i++)
{
int count = 0;
if (i > 0)
{
if (A[i - 1] != A[i])
count = count + 1;
else
count = count - 1;
}
if (i < n - 1)
{
if (A[i + 1] != A[i])
count = count + 1;
else
count = count - 1;
}
r = Math.Max(r, count);
}
return result + r;
}
Im finding hard to figure out the logic here. specially the given below part
for (int i = 0; i < n - 1; i++)
{
if (A[i] == A[i + 1])
result = result + 1;
}
I would highly apretiate if any one can explain me the logic in this solution.
Thanks
The bit you've highlighted just counts the number of currently adjacent equal values, i.e. where one value (A[i]) is equal to the next (A[i+1]). It then asks (the second loop), for each value in turn, whether flipping it would increase vs decrease vs not change the number of adjacent equal values; so if a value is currently different from the one before it (A[i-1] != A[i]), a flip would be an increase - else decrease; likewise the one after it. The final result is the pre-existing number of adjacent equal values (result), plus the best delta (r) found in the sweep.
public int getMacCon(string[] A)
{
int n = A.Length;
int result = 0;
// find how many adjacent values are currently in the string
for (int i = 0; i < n - 1; i++)
{
// if same as the next value, that's a hit
if (A[i] == A[i + 1])
result = result + 1;
}
// worst case delta from flipping one value is that me make it
// worse on both sides, so -2
int r = -2;
// now consider each value in turn
for (int i = 0; i < n; i++)
{
int count = 0;
if (i > 0) // test value before, if not the first value
{
if (A[i - 1] != A[i])
count = count + 1; // before is different; flip is incr
else
count = count - 1; // before is same; flip is decr
}
if (i < n - 1) // test value after, if not the last value
{
if (A[i + 1] != A[i])
count = count + 1; // after is different; flip is incr
else
count = count - 1; // after is same; flip is decr
}
// compare that to the tracking counter, and keep the best value
r = Math.Max(r, count);
}
// final result is sum of pre-existing count plus the delta
return result + r;
}
Incidentally, an optimization might be to change the second loop test from i < n to i < n && r != 2 - i.e. stop as soon as the best possible delta is found (making it better on both sides, +2)
Not an direct answer to your question (as Marc Gravell's answer covers it enough) but I just need to add how would I solve this instead:
encode your string with RLE (run length encoding)
so you need array of b,v,n values. Where b>=0 is start position, v={0,1} is bit value and n is the count of consequent occurencies. For example something like:
const int _max=100; // max number of bits
int b[_max],v[_max],n[_max],bvns=0;
The bvns is number of used b,v,n in the arrays. You can also use any dynamic list/template instead.
reset your actual solution
You need bit position to change ix and the count of consequent bits resulting after its flip sz. Set booth to zero.
scan the RLE for items with n=1
if found that means item before and after in the RLE is the same so flipping will join them. So compute the resulting size and if bigger then store as actual solution something like:
for (int i=1;i<bvns-1;i++) // scann RLE except first and last item
if (n[i]==1) // single bit found
{
l=n[i-1]+1+n[i+1]; // resulting size
if (l>=sz) { sz=l; ix=b; } // update solution
}
test if enlarging single sequence is not bigger
simply:
for (int i=0;i<bvns;i++) // scann RLE
if (n[i]>=sz) // result is bigger?
{
sz=l; ix=b-1; // update solution
if (ix<0) ix=b+n[i];
}
I'm trying to get the maximum Submatrix Sum from given nxn matrices. From what I read around the algorithm have a complexity of n^3 (kadane). I tried to implement it in java using a code I found here on stackoverflow (written by Anders Gustafsson in C# in these post) but it seems to not always work.
my code is this:
public static void maxSubMatrix(int matrix[][]) {
// O(n^3) Max Sum Submatrix
int row = matrix.length;
int col = matrix[0].length; // Get the col-length by taking the length of
// row 0 (in programm the matrices will be n x n)
// Initialise maxSum
int maxSum = 0;
// Set left column
for (int left=0; left<col; left++) {
// Initialise array
int tempArray[] = new int[row];
// Set right column by left column (outer loop)
for (int right=left; right<col; right++){
// Calculate sum between current left-right for every row 'i'
for (int i=0; i<row; i++)
tempArray[i] = matrix[i][right];
// ----
// Find maximum sum in tempArray[]
int sum = maxSubArray(tempArray);
// Compare sum with maxSum so far, and update it if necessary
if (sum > maxSum) maxSum = sum;
}
}
System.out.println(maxSum);
}
// ==========================
public static int maxSubArray(int array[]){
// Kadane O(n) Max Sum Subarray
int maxSum = 0;
int tempSum = 0;
for (int i=0; i<array.length; i++){
int b = array[i];
if (tempSum + b > 0) tempSum += b;
else tempSum = 0;
maxSum = Math.max(maxSum, tempSum);
}
return maxSum;
}
I have three examples:
Matrix 1
-2 -3
-1 -4
Output is 0 (Also the empty 0x0 Matrix is a solution)
Matrix 2
2 -1
-2 -1
Output is 2
Matrix 3
-1 3
3 -1
Output is 3, but should be 4
Maybe someone can see the error. I'm also open to completely new idea to implement it.
You have just forgotten to add the next rigth element to the temp-array:
(int i=0; i<row; i++)
tempArray[i] += matrix[i][right];
Now everything's fine! ;)
Greetz