I wrote this method for finding the longest increasing sub sequence in an array. My question is, after checking if the next index is higher in the second for loop, why do I have to even use the else block afterwards? It doesn't output a correct result if I don't. Why wouldn't it just be sufficient to increment currentSeq by 1 if the next one in the sequence is bigger? If false, than just move on with the flow of control, with currentSeq being left at 1 anyway?
static void Main(string[] args)
{
int length = int.Parse(Console.ReadLine());
int[] nums = new int[length];
int currentSeq = 1;
int maxSeq = 1;
for (int i = 0; i < nums.Length; i++)
{
nums[i] = int.Parse(Console.ReadLine());
}
for (int i = 0; i < nums.Length - 1; i++)
{
if (nums[i] < nums[i + 1])
{
currentSeq++;
}
else
{
currentSeq = 1;
}
if (currentSeq > maxSeq)
{
maxSeq = currentSeq;
}
}
Console.WriteLine(maxSeq);
}
You need the else keyword to reset currentSeq to 1 for the next sequence calculation. Imagine that you're done with the first sequence and you start calculating the next one in the table, you'll need to restart from 1.
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.
i must create array and fill it with random numbers , between 1-100. From there, i must find the 1st uneven number and print it.
Also have to print 0 if no uneven numbers are in the array.
Heres what i did:
int[] tab = new int[10];
int[] uneven = new int[tab.Length];
int i;
for (i = 0; i < tab.Length; i++)
tab[i] = new Random().Next(100) + 1;
do
{
uneven[i] = tab[i];
} while (tab[i] % 2 == 1);
Console.WriteLine(uneven[0]);
So my reasoning is that i add uneven numbers in uneven[i] as long as tab[i] is uneven,then print the first element of the array.
However, i get "out of bonds exception".
Thank you in advance for any help.
Your for loop set i to 10 which is outside the bounds of the array. You need to re-set it to 0 before the do loop. Also, you need to increment i.
i = 0;
do
{
uneven[i] = tab[i];
i++;
} while (tab[i] % 2 != 0);
By the time your do loop starts your "i" variable is stuck on 10. Arrays start at 0 so it only goes up to 9 which is why you're seeing the out of bounds exception. Here's a small example of what you're trying to achieve:
int[] tab = new int[10];
var rnd = new Random();
// Create 10 random numbers
for (int i = 0; i < tab.Length; i++)
{
tab[i] = rnd.Next(100) + 1;
}
// Find the first uneven number
bool found = false;
for (int i = 0; i < tab.Length; i++)
{
if (tab[i] % 2 != 0)
{
Console.WriteLine(tab[i]);
found = true;
break;
}
}
// Didn't generate an uneven number?
if (!found)
{
Console.WriteLine("Nothing found");
}
This creates an array[] with random numbers assigned to each element.
The second for loop checks if the number is even/odd then breaks the loop if it is odd.
static void Main(string[] args)
{
int[] numList = new int[100];
var rand = new Random();
Console.WriteLine(rand.Next(101));
for (int i = 0; i <= 99; i++)
{
numList[i] = rand.Next(101);
Console.WriteLine($"Element; {i}: {numList[i]}");
}
for (int i = 0; i <= 99; i++)
{
int num = numList[i];
if (num / 2 != 0)
{
Console.WriteLine($"The first uneven number is: {num} in element: {i}");
break;
}
if(i == numList.Count())
{
Console.WriteLine("All numbers are even");
break;
}
}
Console.ReadLine();
}
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];
}
This Console-application is a bit strange but kinda funny, if it works. First, I'm clocking the time it takes to fill a LinkedList with 4.000.000 elements, with random numbers. Then I'm searching for 100 random elements in that LinkedList. And between this I'm writing out the time it took to fill and find the elements.
After that I'm trying to do the same thing again, but with an Array. First filling it, then looking for 100 random elements. And then I'm sorting the array, to see the difference between looking for 100 random elements in a unsorted vs sorted array. And then typing the time again.
The problem is, after I've filled the LinkedList, and found the elements in the LinkedList, I'm starting to fill the Array with a loop. And I get a infinite loop. I really don't know what's wrong ATM.
I suggest, if you want to help, that you copy the code I'm pasting into this question, so you understand how it should look for all the parts of the program.
Code:
public static bool sokning(int[] a, int b)
{
bool sant = false;
Random rand = new Random();
Stopwatch watchFindArray = new Stopwatch();
Console.Write("Letar efter tal: ");
watchFindArray.Start();
int myint = 0;
for (int iii = 0; iii < a.Length; iii++)
{
b = rand.Next();
Console.Write("#");
myint = Array.BinarySearch(a, b);
if (myint < 0)
{
sant = false;
}
else
{
sant = true;
}
}
watchFindArray.Stop();
if (sant == true)
{
Console.WriteLine("\nFann alla element efter " + watchFindArray.Elapsed.TotalSeconds + " sekunder.");
return true;
}
else
{
return false;
}
}
public static void körMetod()
{
const int MAX = 40000000;
int[] array = new int[MAX];
int hittamig2 = 0;
Random rand2 = new Random();
Stopwatch watchArray = new Stopwatch();
Console.WriteLine("\nStartar Array...");
watchArray.Start();
Console.Write("Position: ");
for (int ii = 0; ii < MAX; ii++)
{
array[ii] = rand2.Next();
if (array.Length % 1000000 == 0)
{
Console.Write("#");
}
}
watchArray.Stop();
Console.WriteLine("\nTid: " + watchArray.Elapsed.TotalSeconds + " sekunder att fylla en array.");
Console.WriteLine("Letar efter tal: ");
bool sant = sokning(array, hittamig2);
Console.WriteLine("Sorterar arrayen.");
Array.Sort(array);
sant = sokning(array, hittamig2);
if (sant == false)
{
Console.WriteLine("\nHittade inte alla element i arrayen.");
Console.ReadLine();
}
else
{
Console.WriteLine("Klar!");
Console.ReadLine();
}
}
static void Main(string[] args)
{
Random rnd = new Random();
const int MAX = 40000000;
LinkedList<int> lankadLista = new LinkedList<int>();
Stopwatch watchLinkedList = new Stopwatch();
Console.WriteLine("Startar LinkedList...");
watchLinkedList.Start();
Console.Write("Position: ");
for (int i = 0; i < MAX; i++)
{
lankadLista.AddLast(rnd.Next());
if (lankadLista.Count() % 1000000 == 0)
{
Console.Write("#");
}
}
watchLinkedList.Stop();
Console.WriteLine("\nTid: " + watchLinkedList.Elapsed.TotalSeconds + " sekunder att fylla en LinkedList.");
Stopwatch watchFindLinkedList = new Stopwatch();
int hittaMig;
Console.Write("Letar efter tal: ");
watchFindLinkedList.Start();
for (int j = 0; j < 100; j++)
{
hittaMig = rnd.Next();
Console.Write("#");
lankadLista.Find(hittaMig);
}
watchFindLinkedList.Stop();
Console.WriteLine("\nFann alla element efter " +
watchFindLinkedList.Elapsed.TotalSeconds + " sekunder.");
Console.ReadLine();
körMetod();
}
Best Regards.
You are not in an infinite loop, the problem is that it the following code:
for (int ii = 0; ii < MAX; ii++)
{
array[ii] = rand2.Next();
if (array.Length % 1000000 == 0)
{
Console.Write("#");
}
}
The inner condition is array.Length % 1000000 == 0 which is always true because the size of array is always 40000000 as you initialized it:
const int MAX = 40000000;
int[] array = new int[MAX];
When you are doing array[ii] = rand2.Next(); you are not changing the length of the array you are just setting one of its cells with a value equals to rand2.Next();.
This causes the Console.Write("#"); to work in every iteration and also slowing your loop dramatically.
To fix this, just change:
if (array.Length % 1000000 == 0)
to:
if (ii % 1000000 == 0)
You don't want to add new item at the end of the array every time because, resizing the array reallocates the array every time which is super slow but you can do it using the Array.Resize method (no reason for you to do it)
I think you have a big problem in the routine that searches the Array. (sokning)
Where is the code that searches for only 100 elements?
It seems that your are searching a random generated number for 40 millions times. Just fixing the Console.Write("#") to write correctly at every million point is not enough. I think that the big delay that let you think to have an infinite loop is in your code that search 40 millions of random generated numbers in an array of 40 millions of numbers
Of course this is not very "responsive" (considering also that you call this method two times)
public static bool sokning(int[] a, int b)
{
bool sant = false;
Random rand = new Random();
Stopwatch watchFindArray = new Stopwatch();
Console.Write("Letar efter tal: ");
watchFindArray.Start();
int myint = 0;
// Search only 100 numbers like you do in the linked list
for (int iii = 0; iii < 100; iii++)
{
b = rand.Next();
Console.Write("#");
myint = Array.BinarySearch(a, b);
if (myint < 0)
{
sant = false;
}
else
{
sant = true;
}
}
watchFindArray.Stop();
if (sant == true)
{
Console.WriteLine("\nFann alla element efter " + watchFindArray.Elapsed.TotalSeconds + " sekunder.");
return true;
}
else
{
return false;
}
}
There are also two minor problems.
Why passing the variable b inside the sokning method? The original value is never used and when you start the loop to search a random generated number the b variable os overwritten. So I think you could remove it
The second problem is the result of this sokning method. You set the sant variable to true or false at every loop. So the latest loop wins. In other words, if the latest loop finds a match you return true or false if not. If some previous loop has a different result, it is totally lost for the callers of sokning.
This solution factorizes a number (numInput), it works perfectly well except for a logic error I can't seem to find no matter how much I track the solution. The logic error causes the returned result to be 0 no matter the value initialized for numInput.
using System;
namespace factorizer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(factorialise());
Console.ReadKey();
}
private static int factorialise()
{
int numInput = int.Parse(Console.ReadLine());
int[] number = new int[numInput];
for (int i = 1; i < numInput; i++) //stores the (n-1)...(n-i) value for the number input'd in the array number[i]
{
number[i - 1] = numInput - i; //the element indicating the index number is 'i - 1' index values start from zero
}
for (int index = 0; index < number.Length; index++) //multiplies the element corresponding the index number with the number input'd
{
numInput = numInput * number[index];
}
return numInput;
}
}
}
Your last item in array stays uninitialized (i.e. equal to zero). Change items count:
int[] number = new int[numInput-1];
Also why not simply use for loop?
int result = 1;
for(int i = 1; i <= numInput; i++)
result *= i;
And another sample just for fun
Enumerable.Range(1, numInput).Aggregate(1, (a,i) => a * i)